From 21fb08b15aae54470100f666495c7c32d6165516 Mon Sep 17 00:00:00 2001
From: Kenneth Reitz <me@kennethreitz.org>
Date: Thu, 19 Apr 2018 09:38:44 -0400
Subject: [PATCH] setuptools installation method

Signed-off-by: Kenneth Reitz <me@kennethreitz.org>
---
 bin/steps/python                              |    3 +-
 setuptools.egg-info/entry_points.txt          |   14 +
 vendor/setuptools-39.0.1/CHANGES.rst          | 3651 +++++++++++
 vendor/setuptools-39.0.1/LICENSE              |   19 +
 vendor/setuptools-39.0.1/MANIFEST.in          |   14 +
 vendor/setuptools-39.0.1/PKG-INFO             |   65 +
 vendor/setuptools-39.0.1/README.rst           |   34 +
 vendor/setuptools-39.0.1/bootstrap.py         |   64 +
 .../build/lib/easy_install.py                 |    5 +
 .../build/lib/pkg_resources/__init__.py       | 3125 +++++++++
 .../lib/pkg_resources/_vendor/__init__.py     |    0
 .../lib/pkg_resources/_vendor/appdirs.py      |  552 ++
 .../_vendor/packaging/__about__.py            |   21 +
 .../_vendor/packaging/__init__.py             |   14 +
 .../_vendor/packaging/_compat.py              |   30 +
 .../_vendor/packaging/_structures.py          |   68 +
 .../_vendor/packaging/markers.py              |  301 +
 .../_vendor/packaging/requirements.py         |  127 +
 .../_vendor/packaging/specifiers.py           |  774 +++
 .../pkg_resources/_vendor/packaging/utils.py  |   14 +
 .../_vendor/packaging/version.py              |  393 ++
 .../lib/pkg_resources/_vendor/pyparsing.py    | 5696 +++++++++++++++++
 .../build/lib/pkg_resources/_vendor/six.py    |  868 +++
 .../lib/pkg_resources/extern/__init__.py      |   73 +
 .../build/lib/pkg_resources/py31compat.py     |   22 +
 .../build/lib/setuptools/__init__.py          |  180 +
 .../build/lib/setuptools/_vendor/__init__.py  |    0
 .../setuptools/_vendor/packaging/__about__.py |   21 +
 .../setuptools/_vendor/packaging/__init__.py  |   14 +
 .../setuptools/_vendor/packaging/_compat.py   |   30 +
 .../_vendor/packaging/_structures.py          |   68 +
 .../setuptools/_vendor/packaging/markers.py   |  301 +
 .../_vendor/packaging/requirements.py         |  127 +
 .../_vendor/packaging/specifiers.py           |  774 +++
 .../lib/setuptools/_vendor/packaging/utils.py |   14 +
 .../setuptools/_vendor/packaging/version.py   |  393 ++
 .../build/lib/setuptools/_vendor/pyparsing.py | 5696 +++++++++++++++++
 .../build/lib/setuptools/_vendor/six.py       |  868 +++
 .../build/lib/setuptools/archive_util.py      |  173 +
 .../build/lib/setuptools/build_meta.py        |  172 +
 .../build/lib/setuptools/cli-32.exe           |  Bin 0 -> 65536 bytes
 .../build/lib/setuptools/cli-64.exe           |  Bin 0 -> 74752 bytes
 .../build/lib/setuptools/cli.exe              |  Bin 0 -> 65536 bytes
 .../build/lib/setuptools/command/__init__.py  |   18 +
 .../build/lib/setuptools/command/alias.py     |   80 +
 .../build/lib/setuptools/command/bdist_egg.py |  502 ++
 .../build/lib/setuptools/command/bdist_rpm.py |   43 +
 .../lib/setuptools/command/bdist_wininst.py   |   21 +
 .../lib/setuptools/command/build_clib.py      |   98 +
 .../build/lib/setuptools/command/build_ext.py |  331 +
 .../build/lib/setuptools/command/build_py.py  |  270 +
 .../build/lib/setuptools/command/develop.py   |  216 +
 .../build/lib/setuptools/command/dist_info.py |   36 +
 .../lib/setuptools/command/easy_install.py    | 2334 +++++++
 .../build/lib/setuptools/command/egg_info.py  |  696 ++
 .../build/lib/setuptools/command/install.py   |  125 +
 .../setuptools/command/install_egg_info.py    |   62 +
 .../lib/setuptools/command/install_lib.py     |  121 +
 .../lib/setuptools/command/install_scripts.py |   65 +
 .../setuptools/command/launcher manifest.xml  |   15 +
 .../lib/setuptools/command/py36compat.py      |  136 +
 .../build/lib/setuptools/command/register.py  |   10 +
 .../build/lib/setuptools/command/rotate.py    |   66 +
 .../build/lib/setuptools/command/saveopts.py  |   22 +
 .../build/lib/setuptools/command/sdist.py     |  200 +
 .../build/lib/setuptools/command/setopt.py    |  149 +
 .../build/lib/setuptools/command/test.py      |  268 +
 .../build/lib/setuptools/command/upload.py    |   42 +
 .../lib/setuptools/command/upload_docs.py     |  206 +
 .../build/lib/setuptools/config.py            |  556 ++
 .../build/lib/setuptools/dep_util.py          |   23 +
 .../build/lib/setuptools/depends.py           |  186 +
 .../build/lib/setuptools/dist.py              | 1070 ++++
 .../build/lib/setuptools/extension.py         |   57 +
 .../build/lib/setuptools/extern/__init__.py   |   73 +
 .../build/lib/setuptools/glibc.py             |   86 +
 .../build/lib/setuptools/glob.py              |  176 +
 .../build/lib/setuptools/gui-32.exe           |  Bin 0 -> 65536 bytes
 .../build/lib/setuptools/gui-64.exe           |  Bin 0 -> 75264 bytes
 .../build/lib/setuptools/gui.exe              |  Bin 0 -> 65536 bytes
 .../build/lib/setuptools/launch.py            |   35 +
 .../build/lib/setuptools/lib2to3_ex.py        |   62 +
 .../build/lib/setuptools/monkey.py            |  197 +
 .../build/lib/setuptools/msvc.py              | 1302 ++++
 .../build/lib/setuptools/namespaces.py        |  107 +
 .../build/lib/setuptools/package_index.py     | 1119 ++++
 .../build/lib/setuptools/pep425tags.py        |  316 +
 .../build/lib/setuptools/py27compat.py        |   28 +
 .../build/lib/setuptools/py31compat.py        |   41 +
 .../build/lib/setuptools/py33compat.py        |   54 +
 .../build/lib/setuptools/py36compat.py        |   82 +
 .../build/lib/setuptools/sandbox.py           |  491 ++
 .../build/lib/setuptools/script (dev).tmpl    |    5 +
 .../build/lib/setuptools/script.tmpl          |    3 +
 .../build/lib/setuptools/site-patch.py        |   74 +
 .../build/lib/setuptools/ssl_support.py       |  260 +
 .../build/lib/setuptools/unicode_utils.py     |   44 +
 .../build/lib/setuptools/version.py           |    6 +
 .../build/lib/setuptools/wheel.py             |  163 +
 .../build/lib/setuptools/windows_support.py   |   29 +
 vendor/setuptools-39.0.1/conftest.py          |    8 +
 .../dist/setuptools-39.0.1-py2.7.egg          |  Bin 0 -> 563427 bytes
 vendor/setuptools-39.0.1/docs/Makefile        |   75 +
 .../docs/_templates/indexsidebar.html         |    8 +
 .../docs/_theme/nature/static/nature.css_t    |  237 +
 .../docs/_theme/nature/static/pygments.css    |   54 +
 .../docs/_theme/nature/theme.conf             |    4 +
 vendor/setuptools-39.0.1/docs/conf.py         |  151 +
 .../docs/developer-guide.txt                  |  115 +
 vendor/setuptools-39.0.1/docs/development.txt |   35 +
 .../setuptools-39.0.1/docs/easy_install.txt   | 1623 +++++
 vendor/setuptools-39.0.1/docs/formats.txt     |  682 ++
 vendor/setuptools-39.0.1/docs/history.txt     |   46 +
 vendor/setuptools-39.0.1/docs/index.txt       |   25 +
 .../setuptools-39.0.1/docs/pkg_resources.txt  | 1941 ++++++
 vendor/setuptools-39.0.1/docs/python3.txt     |   94 +
 vendor/setuptools-39.0.1/docs/releases.txt    |   48 +
 .../setuptools-39.0.1/docs/requirements.txt   |    5 +
 vendor/setuptools-39.0.1/docs/roadmap.txt     |    6 +
 vendor/setuptools-39.0.1/docs/setuptools.txt  | 2775 ++++++++
 vendor/setuptools-39.0.1/easy_install.py      |    5 +
 vendor/setuptools-39.0.1/launcher.c           |  335 +
 .../setuptools-39.0.1/msvc-build-launcher.cmd |   39 +
 vendor/setuptools-39.0.1/pavement.py          |   62 +
 .../pkg_resources/__init__.py                 | 3125 +++++++++
 .../pkg_resources/_vendor/__init__.py         |    0
 .../pkg_resources/_vendor/appdirs.py          |  552 ++
 .../_vendor/packaging/__about__.py            |   21 +
 .../_vendor/packaging/__init__.py             |   14 +
 .../_vendor/packaging/_compat.py              |   30 +
 .../_vendor/packaging/_structures.py          |   68 +
 .../_vendor/packaging/markers.py              |  301 +
 .../_vendor/packaging/requirements.py         |  127 +
 .../_vendor/packaging/specifiers.py           |  774 +++
 .../pkg_resources/_vendor/packaging/utils.py  |   14 +
 .../_vendor/packaging/version.py              |  393 ++
 .../pkg_resources/_vendor/pyparsing.py        | 5696 +++++++++++++++++
 .../pkg_resources/_vendor/six.py              |  868 +++
 .../pkg_resources/_vendor/vendored.txt        |    4 +
 .../pkg_resources/api_tests.txt               |  401 ++
 .../pkg_resources/extern/__init__.py          |   73 +
 .../pkg_resources/py31compat.py               |   22 +
 .../pkg_resources/tests/__init__.py           |    0
 .../tests/test_find_distributions.py          |   66 +
 .../pkg_resources/tests/test_markers.py       |    8 +
 .../pkg_resources/tests/test_pkg_resources.py |  209 +
 .../pkg_resources/tests/test_resources.py     |  834 +++
 .../pkg_resources/tests/test_working_set.py   |  482 ++
 vendor/setuptools-39.0.1/pytest.ini           |    6 +
 vendor/setuptools-39.0.1/setup.cfg            |   29 +
 vendor/setuptools-39.0.1/setup.py             |  195 +
 .../setuptools.egg-info/PKG-INFO              |   65 +
 .../setuptools.egg-info/SOURCES.txt           |  192 +
 .../setuptools.egg-info/dependency_links.txt  |    2 +
 .../setuptools.egg-info/entry_points.txt      |   65 +
 .../setuptools.egg-info/requires.txt          |    6 +
 .../setuptools.egg-info/top_level.txt         |    3 +
 .../setuptools.egg-info/zip-safe              |    1 +
 .../setuptools-39.0.1/setuptools/__init__.py  |  180 +
 .../setuptools/_vendor/__init__.py            |    0
 .../setuptools/_vendor/packaging/__about__.py |   21 +
 .../setuptools/_vendor/packaging/__init__.py  |   14 +
 .../setuptools/_vendor/packaging/_compat.py   |   30 +
 .../_vendor/packaging/_structures.py          |   68 +
 .../setuptools/_vendor/packaging/markers.py   |  301 +
 .../_vendor/packaging/requirements.py         |  127 +
 .../_vendor/packaging/specifiers.py           |  774 +++
 .../setuptools/_vendor/packaging/utils.py     |   14 +
 .../setuptools/_vendor/packaging/version.py   |  393 ++
 .../setuptools/_vendor/pyparsing.py           | 5696 +++++++++++++++++
 .../setuptools/_vendor/six.py                 |  868 +++
 .../setuptools/_vendor/vendored.txt           |    3 +
 .../setuptools/archive_util.py                |  173 +
 .../setuptools/build_meta.py                  |  172 +
 .../setuptools-39.0.1/setuptools/cli-32.exe   |  Bin 0 -> 65536 bytes
 .../setuptools-39.0.1/setuptools/cli-64.exe   |  Bin 0 -> 74752 bytes
 vendor/setuptools-39.0.1/setuptools/cli.exe   |  Bin 0 -> 65536 bytes
 .../setuptools/command/__init__.py            |   18 +
 .../setuptools/command/alias.py               |   80 +
 .../setuptools/command/bdist_egg.py           |  502 ++
 .../setuptools/command/bdist_rpm.py           |   43 +
 .../setuptools/command/bdist_wininst.py       |   21 +
 .../setuptools/command/build_clib.py          |   98 +
 .../setuptools/command/build_ext.py           |  331 +
 .../setuptools/command/build_py.py            |  270 +
 .../setuptools/command/develop.py             |  216 +
 .../setuptools/command/dist_info.py           |   36 +
 .../setuptools/command/easy_install.py        | 2334 +++++++
 .../setuptools/command/egg_info.py            |  696 ++
 .../setuptools/command/install.py             |  125 +
 .../setuptools/command/install_egg_info.py    |   62 +
 .../setuptools/command/install_lib.py         |  121 +
 .../setuptools/command/install_scripts.py     |   65 +
 .../setuptools/command/launcher manifest.xml  |   15 +
 .../setuptools/command/py36compat.py          |  136 +
 .../setuptools/command/register.py            |   10 +
 .../setuptools/command/rotate.py              |   66 +
 .../setuptools/command/saveopts.py            |   22 +
 .../setuptools/command/sdist.py               |  200 +
 .../setuptools/command/setopt.py              |  149 +
 .../setuptools/command/test.py                |  268 +
 .../setuptools/command/upload.py              |   42 +
 .../setuptools/command/upload_docs.py         |  206 +
 vendor/setuptools-39.0.1/setuptools/config.py |  556 ++
 .../setuptools-39.0.1/setuptools/dep_util.py  |   23 +
 .../setuptools-39.0.1/setuptools/depends.py   |  186 +
 vendor/setuptools-39.0.1/setuptools/dist.py   | 1070 ++++
 .../setuptools-39.0.1/setuptools/extension.py |   57 +
 .../setuptools/extern/__init__.py             |   73 +
 vendor/setuptools-39.0.1/setuptools/glibc.py  |   86 +
 vendor/setuptools-39.0.1/setuptools/glob.py   |  176 +
 .../setuptools-39.0.1/setuptools/gui-32.exe   |  Bin 0 -> 65536 bytes
 .../setuptools-39.0.1/setuptools/gui-64.exe   |  Bin 0 -> 75264 bytes
 vendor/setuptools-39.0.1/setuptools/gui.exe   |  Bin 0 -> 65536 bytes
 vendor/setuptools-39.0.1/setuptools/launch.py |   35 +
 .../setuptools/lib2to3_ex.py                  |   62 +
 vendor/setuptools-39.0.1/setuptools/monkey.py |  197 +
 vendor/setuptools-39.0.1/setuptools/msvc.py   | 1302 ++++
 .../setuptools/namespaces.py                  |  107 +
 .../setuptools/package_index.py               | 1119 ++++
 .../setuptools/pep425tags.py                  |  316 +
 .../setuptools/py27compat.py                  |   28 +
 .../setuptools/py31compat.py                  |   41 +
 .../setuptools/py33compat.py                  |   54 +
 .../setuptools/py36compat.py                  |   82 +
 .../setuptools-39.0.1/setuptools/sandbox.py   |  491 ++
 .../setuptools/script (dev).tmpl              |    5 +
 .../setuptools-39.0.1/setuptools/script.tmpl  |    3 +
 .../setuptools/site-patch.py                  |   74 +
 .../setuptools/ssl_support.py                 |  260 +
 .../setuptools/tests/__init__.py              |    6 +
 .../setuptools/tests/contexts.py              |   98 +
 .../setuptools/tests/environment.py           |   60 +
 .../setuptools/tests/files.py                 |   39 +
 .../setuptools/tests/fixtures.py              |   23 +
 .../indexes/test_links_priority/external.html |    3 +
 .../simple/foobar/index.html                  |    4 +
 .../setuptools/tests/mod_with_constant.py     |    1 +
 .../setuptools/tests/namespaces.py            |   42 +
 .../setuptools/tests/script-with-bom.py       |    3 +
 .../setuptools/tests/server.py                |   72 +
 .../setuptools/tests/test_archive_util.py     |   42 +
 .../setuptools/tests/test_bdist_egg.py        |   66 +
 .../setuptools/tests/test_build_clib.py       |   59 +
 .../setuptools/tests/test_build_ext.py        |   45 +
 .../setuptools/tests/test_build_meta.py       |  126 +
 .../setuptools/tests/test_build_py.py         |   30 +
 .../setuptools/tests/test_config.py           |  583 ++
 .../setuptools/tests/test_dep_util.py         |   30 +
 .../setuptools/tests/test_depends.py          |   16 +
 .../setuptools/tests/test_develop.py          |  202 +
 .../setuptools/tests/test_dist.py             |  145 +
 .../setuptools/tests/test_dist_info.py        |   78 +
 .../setuptools/tests/test_easy_install.py     |  760 +++
 .../setuptools/tests/test_egg_info.py         |  586 ++
 .../setuptools/tests/test_find_packages.py    |  182 +
 .../setuptools/tests/test_install_scripts.py  |   88 +
 .../setuptools/tests/test_integration.py      |  165 +
 .../setuptools/tests/test_manifest.py         |  602 ++
 .../setuptools/tests/test_msvc.py             |  178 +
 .../setuptools/tests/test_namespaces.py       |  111 +
 .../setuptools/tests/test_packageindex.py     |  275 +
 .../setuptools/tests/test_sandbox.py          |  133 +
 .../setuptools/tests/test_sdist.py            |  427 ++
 .../setuptools/tests/test_setuptools.py       |  368 ++
 .../setuptools/tests/test_test.py             |  131 +
 .../setuptools/tests/test_unicode_utils.py    |   10 +
 .../setuptools/tests/test_upload_docs.py      |   71 +
 .../setuptools/tests/test_virtualenv.py       |  139 +
 .../setuptools/tests/test_wheel.py            |  508 ++
 .../setuptools/tests/test_windows_wrappers.py |  181 +
 .../setuptools/tests/text.py                  |    9 +
 .../setuptools/tests/textwrap.py              |    8 +
 .../setuptools/unicode_utils.py               |   44 +
 .../setuptools-39.0.1/setuptools/version.py   |    6 +
 vendor/setuptools-39.0.1/setuptools/wheel.py  |  163 +
 .../setuptools/windows_support.py             |   29 +
 vendor/setuptools-39.0.1/tests/manual_test.py |   98 +
 vendor/setuptools-39.0.1/tests/test_pypi.py   |   82 +
 vendor/setuptools-39.0.1/tox.ini              |   11 +
 280 files changed, 89080 insertions(+), 1 deletion(-)
 create mode 100644 setuptools.egg-info/entry_points.txt
 create mode 100644 vendor/setuptools-39.0.1/CHANGES.rst
 create mode 100644 vendor/setuptools-39.0.1/LICENSE
 create mode 100644 vendor/setuptools-39.0.1/MANIFEST.in
 create mode 100644 vendor/setuptools-39.0.1/PKG-INFO
 create mode 100755 vendor/setuptools-39.0.1/README.rst
 create mode 100644 vendor/setuptools-39.0.1/bootstrap.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/easy_install.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/appdirs.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/__about__.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/_compat.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/_structures.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/markers.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/requirements.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/specifiers.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/utils.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/version.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/pyparsing.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/six.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/extern/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/pkg_resources/py31compat.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/__about__.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/_compat.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/_structures.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/markers.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/requirements.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/specifiers.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/utils.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/version.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/pyparsing.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/six.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/archive_util.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/build_meta.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/cli-32.exe
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/cli-64.exe
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/cli.exe
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/alias.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/bdist_egg.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/bdist_rpm.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/bdist_wininst.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/build_clib.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/build_ext.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/build_py.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/develop.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/dist_info.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/easy_install.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/egg_info.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/install.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/install_egg_info.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/install_lib.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/install_scripts.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/launcher manifest.xml
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/py36compat.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/register.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/rotate.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/saveopts.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/sdist.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/setopt.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/test.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/upload.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/command/upload_docs.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/config.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/dep_util.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/depends.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/dist.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/extension.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/extern/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/glibc.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/glob.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/gui-32.exe
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/gui-64.exe
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/gui.exe
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/launch.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/lib2to3_ex.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/monkey.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/msvc.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/namespaces.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/package_index.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/pep425tags.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/py27compat.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/py31compat.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/py33compat.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/py36compat.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/sandbox.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/script (dev).tmpl
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/script.tmpl
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/site-patch.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/ssl_support.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/unicode_utils.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/version.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/wheel.py
 create mode 100644 vendor/setuptools-39.0.1/build/lib/setuptools/windows_support.py
 create mode 100644 vendor/setuptools-39.0.1/conftest.py
 create mode 100644 vendor/setuptools-39.0.1/dist/setuptools-39.0.1-py2.7.egg
 create mode 100644 vendor/setuptools-39.0.1/docs/Makefile
 create mode 100644 vendor/setuptools-39.0.1/docs/_templates/indexsidebar.html
 create mode 100644 vendor/setuptools-39.0.1/docs/_theme/nature/static/nature.css_t
 create mode 100644 vendor/setuptools-39.0.1/docs/_theme/nature/static/pygments.css
 create mode 100644 vendor/setuptools-39.0.1/docs/_theme/nature/theme.conf
 create mode 100644 vendor/setuptools-39.0.1/docs/conf.py
 create mode 100644 vendor/setuptools-39.0.1/docs/developer-guide.txt
 create mode 100644 vendor/setuptools-39.0.1/docs/development.txt
 create mode 100644 vendor/setuptools-39.0.1/docs/easy_install.txt
 create mode 100644 vendor/setuptools-39.0.1/docs/formats.txt
 create mode 100644 vendor/setuptools-39.0.1/docs/history.txt
 create mode 100644 vendor/setuptools-39.0.1/docs/index.txt
 create mode 100644 vendor/setuptools-39.0.1/docs/pkg_resources.txt
 create mode 100644 vendor/setuptools-39.0.1/docs/python3.txt
 create mode 100644 vendor/setuptools-39.0.1/docs/releases.txt
 create mode 100644 vendor/setuptools-39.0.1/docs/requirements.txt
 create mode 100644 vendor/setuptools-39.0.1/docs/roadmap.txt
 create mode 100644 vendor/setuptools-39.0.1/docs/setuptools.txt
 create mode 100755 vendor/setuptools-39.0.1/easy_install.py
 create mode 100755 vendor/setuptools-39.0.1/launcher.c
 create mode 100644 vendor/setuptools-39.0.1/msvc-build-launcher.cmd
 create mode 100644 vendor/setuptools-39.0.1/pavement.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/_vendor/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/_vendor/appdirs.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/__about__.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/_compat.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/_structures.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/markers.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/requirements.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/specifiers.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/utils.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/version.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/_vendor/pyparsing.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/_vendor/six.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/_vendor/vendored.txt
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/api_tests.txt
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/extern/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/py31compat.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/tests/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/tests/test_find_distributions.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/tests/test_markers.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/tests/test_pkg_resources.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/tests/test_resources.py
 create mode 100644 vendor/setuptools-39.0.1/pkg_resources/tests/test_working_set.py
 create mode 100755 vendor/setuptools-39.0.1/pytest.ini
 create mode 100755 vendor/setuptools-39.0.1/setup.cfg
 create mode 100755 vendor/setuptools-39.0.1/setup.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools.egg-info/PKG-INFO
 create mode 100644 vendor/setuptools-39.0.1/setuptools.egg-info/SOURCES.txt
 create mode 100644 vendor/setuptools-39.0.1/setuptools.egg-info/dependency_links.txt
 create mode 100644 vendor/setuptools-39.0.1/setuptools.egg-info/entry_points.txt
 create mode 100644 vendor/setuptools-39.0.1/setuptools.egg-info/requires.txt
 create mode 100644 vendor/setuptools-39.0.1/setuptools.egg-info/top_level.txt
 create mode 100644 vendor/setuptools-39.0.1/setuptools.egg-info/zip-safe
 create mode 100644 vendor/setuptools-39.0.1/setuptools/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/_vendor/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/_vendor/packaging/__about__.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/_vendor/packaging/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/_vendor/packaging/_compat.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/_vendor/packaging/_structures.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/_vendor/packaging/markers.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/_vendor/packaging/requirements.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/_vendor/packaging/specifiers.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/_vendor/packaging/utils.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/_vendor/packaging/version.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/_vendor/pyparsing.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/_vendor/six.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/_vendor/vendored.txt
 create mode 100755 vendor/setuptools-39.0.1/setuptools/archive_util.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/build_meta.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/cli-32.exe
 create mode 100644 vendor/setuptools-39.0.1/setuptools/cli-64.exe
 create mode 100644 vendor/setuptools-39.0.1/setuptools/cli.exe
 create mode 100644 vendor/setuptools-39.0.1/setuptools/command/__init__.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/command/alias.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/command/bdist_egg.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/command/bdist_rpm.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/command/bdist_wininst.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/command/build_clib.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/command/build_ext.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/command/build_py.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/command/develop.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/command/dist_info.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/command/easy_install.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/command/egg_info.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/command/install.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/command/install_egg_info.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/command/install_lib.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/command/install_scripts.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/command/launcher manifest.xml
 create mode 100644 vendor/setuptools-39.0.1/setuptools/command/py36compat.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/command/register.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/command/rotate.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/command/saveopts.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/command/sdist.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/command/setopt.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/command/test.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/command/upload.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/command/upload_docs.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/config.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/dep_util.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/depends.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/dist.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/extension.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/extern/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/glibc.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/glob.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/gui-32.exe
 create mode 100644 vendor/setuptools-39.0.1/setuptools/gui-64.exe
 create mode 100644 vendor/setuptools-39.0.1/setuptools/gui.exe
 create mode 100644 vendor/setuptools-39.0.1/setuptools/launch.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/lib2to3_ex.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/monkey.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/msvc.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/namespaces.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/package_index.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/pep425tags.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/py27compat.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/py31compat.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/py33compat.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/py36compat.py
 create mode 100755 vendor/setuptools-39.0.1/setuptools/sandbox.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/script (dev).tmpl
 create mode 100644 vendor/setuptools-39.0.1/setuptools/script.tmpl
 create mode 100644 vendor/setuptools-39.0.1/setuptools/site-patch.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/ssl_support.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/__init__.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/contexts.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/environment.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/files.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/fixtures.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/indexes/test_links_priority/external.html
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/indexes/test_links_priority/simple/foobar/index.html
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/mod_with_constant.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/namespaces.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/script-with-bom.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/server.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_archive_util.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_bdist_egg.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_build_clib.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_build_ext.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_build_meta.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_build_py.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_config.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_dep_util.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_depends.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_develop.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_dist.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_dist_info.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_easy_install.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_egg_info.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_find_packages.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_install_scripts.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_integration.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_manifest.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_msvc.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_namespaces.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_packageindex.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_sandbox.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_sdist.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_setuptools.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_test.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_unicode_utils.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_upload_docs.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_virtualenv.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_wheel.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/test_windows_wrappers.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/text.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/tests/textwrap.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/unicode_utils.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/version.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/wheel.py
 create mode 100644 vendor/setuptools-39.0.1/setuptools/windows_support.py
 create mode 100644 vendor/setuptools-39.0.1/tests/manual_test.py
 create mode 100644 vendor/setuptools-39.0.1/tests/test_pypi.py
 create mode 100644 vendor/setuptools-39.0.1/tox.ini

diff --git a/bin/steps/python b/bin/steps/python
index f753804e..7ecbdf37 100755
--- a/bin/steps/python
+++ b/bin/steps/python
@@ -67,8 +67,9 @@ if [ "$FRESH_PYTHON" ] || [[ ! $(pip --version) == *$PIP_UPDATE* ]]; then
   rm -fr /app/.heroku/python/lib/python*/site-packages/pip-*
   rm -fr /app/.heroku/python/lib/python*/site-packages/setuptools-*
 
+  /app/.heroku/python/bin/python "$ROOT_DIR/vendor/setuptools-39.0.1/setup.py" install # &> /dev/null
   /app/.heroku/python/bin/python "$ROOT_DIR/vendor/pip-9.0.3/setup.py" install # &> /dev/null
-  /app/.heroku/python/bin/pip install "$ROOT_DIR/vendor/setuptools-39.0.1-py2.py3-none-any.whl"
+
 
 fi
 
diff --git a/setuptools.egg-info/entry_points.txt b/setuptools.egg-info/entry_points.txt
new file mode 100644
index 00000000..6a0252a0
--- /dev/null
+++ b/setuptools.egg-info/entry_points.txt
@@ -0,0 +1,14 @@
+
+[distutils.commands]
+egg_info = setuptools.command.egg_info:egg_info
+
+[distutils.setup_keywords]
+include_package_data = setuptools.dist:assert_bool
+install_requires = setuptools.dist:check_requirements
+extras_require = setuptools.dist:check_extras
+entry_points = setuptools.dist:check_entry_points
+
+[egg_info.writers]
+dependency_links.txt = setuptools.command.egg_info:overwrite_arg
+entry_points.txt = setuptools.command.egg_info:write_entries
+requires.txt = setuptools.command.egg_info:write_requirements
diff --git a/vendor/setuptools-39.0.1/CHANGES.rst b/vendor/setuptools-39.0.1/CHANGES.rst
new file mode 100644
index 00000000..05de76e5
--- /dev/null
+++ b/vendor/setuptools-39.0.1/CHANGES.rst
@@ -0,0 +1,3651 @@
+v39.0.1
+-------
+
+* #1297: Restore Unicode handling for Maintainer fields in
+  metadata.
+
+v39.0.0
+-------
+
+* #1296: Setuptools now vendors its own direct dependencies, no
+  longer relying on the dependencies as vendored by pkg_resources.
+
+* #296: Removed long-deprecated support for iteration on
+  Version objects as returned by ``pkg_resources.parse_version``.
+  Removed the ``SetuptoolsVersion`` and
+  ``SetuptoolsLegacyVersion`` names as well. They should not
+  have been used, but if they were, replace with
+  ``Version`` and ``LegacyVersion`` from ``packaging.version``.
+
+v38.7.0
+-------
+
+* #1288: Add support for maintainer in PKG-INFO.
+
+v38.6.1
+-------
+
+* #1292: Avoid generating ``Provides-Extra`` in metadata when
+  no extra is present (but environment markers are).
+
+v38.6.0
+-------
+
+* #1286: Add support for Metadata 2.1 (PEP 566).
+
+v38.5.2
+-------
+
+* #1285: Fixed RuntimeError in pkg_resources.parse_requirements
+  on Python 3.7 (stemming from PEP 479).
+
+v38.5.1
+-------
+
+* #1271: Revert to Cython legacy ``build_ext`` behavior for
+  compatibility.
+
+v38.5.0
+-------
+
+* #1229: Expand imports in ``build_ext`` to refine detection of
+  Cython availability.
+
+* #1270: When Cython is available, ``build_ext`` now uses the
+  new_build_ext.
+
+v38.4.1
+-------
+
+* #1257: In bdist_egg.scan_module, fix ValueError on Python 3.7.
+
+v38.4.0
+-------
+
+* #1231: Removed warning when PYTHONDONTWRITEBYTECODE is enabled.
+
+v38.3.0
+-------
+
+* #1210: Add support for PEP 345 Project-URL metadata.
+* #1207: Add support for ``long_description_type`` to setup.cfg
+  declarative config as intended and documented.
+
+v38.2.5
+-------
+
+* #1232: Fix trailing slash handling in ``pkg_resources.ZipProvider``.
+
+v38.2.4
+-------
+
+* #1220: Fix `data_files` handling when installing from wheel.
+
+v38.2.3
+-------
+
+* fix Travis' Python 3.3 job.
+
+v38.2.2
+-------
+
+* #1214: fix handling of namespace packages when installing
+  from a wheel.
+
+v38.2.1
+-------
+
+* #1212: fix encoding handling of metadata when installing
+  from a wheel.
+
+v38.2.0
+-------
+
+* #1200: easy_install now support installing from wheels:
+  they will be installed as standalone unzipped eggs.
+
+v38.1.0
+-------
+
+* #1208: Improve error message when failing to locate scripts
+  in egg-info metadata.
+
+v38.0.0
+-------
+
+* #458: In order to support deterministic builds, Setuptools no
+  longer allows packages to declare ``install_requires`` as
+  unordered sequences (sets or dicts).
+
+v37.0.0
+-------
+
+* #878: Drop support for Python 2.6. Python 2.6 users should
+  rely on 'setuptools < 37dev'.
+
+v36.8.0
+-------
+
+* #1190: In SSL support for package index operations, use SNI
+  where available.
+
+v36.7.3
+-------
+
+* #1175: Bug fixes to ``build_meta`` module.
+
+v36.7.2
+-------
+
+* #701: Fixed duplicate test discovery on Python 3.
+
+v36.7.1
+-------
+
+* #1193: Avoid test failures in bdist_egg when
+  PYTHONDONTWRITEBYTECODE is set.
+
+v36.7.0
+-------
+
+* #1054: Support ``setup_requires`` in ``setup.cfg`` files.
+
+v36.6.1
+-------
+
+* #1132: Removed redundant and costly serialization/parsing step
+  in ``EntryPoint.__init__``.
+
+* #844: ``bdist_egg --exclude-source-files`` now tested and works
+  on Python 3.
+
+v36.6.0
+-------
+
+* #1143: Added ``setuptools.build_meta`` module, an implementation
+  of PEP-517 for Setuptools-defined packages.
+
+* #1143: Added ``dist_info`` command for producing dist_info
+  metadata.
+
+v36.5.0
+-------
+
+* #170: When working with Mercurial checkouts, use Windows-friendly
+  syntax for suppressing output.
+
+* Inspired by #1134, performed substantial refactoring of
+  ``pkg_resources.find_on_path`` to facilitate an optimization
+  for paths with many non-version entries.
+
+v36.4.0
+-------
+
+* #1075: Add new ``Description-Content-Type`` metadata field. `See here for
+  documentation on how to use this field.
+  <https://packaging.python.org/specifications/#description-content-type>`_
+
+* #1068: Sort files and directories when building eggs for
+  deterministic order.
+
+* #196: Remove caching of easy_install command in fetch_build_egg.
+  Fixes issue where ``pytest-runner-N.N`` would satisfy the installation
+  of ``pytest``.
+
+* #1129: Fix working set dependencies handling when replacing conflicting
+  distributions (e.g. when using ``setup_requires`` with a conflicting
+  transitive dependency, fix #1124).
+
+* #1133: Improved handling of README files extensions and added
+  Markdown to the list of searched READMES.
+
+* #1135: Improve performance of pkg_resources import by not invoking
+  ``access`` or ``stat`` and using ``os.listdir`` instead.
+
+v36.3.0
+-------
+
+* #1131: Make possible using several files within ``file:`` directive
+  in metadata.long_description in ``setup.cfg``.
+
+v36.2.7
+-------
+
+* fix #1105: Fix handling of requirements with environment
+  markers when declared in ``setup.cfg`` (same treatment as
+  for #1081).
+
+v36.2.6
+-------
+
+* #462: Don't assume a directory is an egg by the ``.egg``
+  extension alone.
+
+v36.2.5
+-------
+
+* #1093: Fix test command handler with extras_require.
+* #1112, #1091, #1115: Now using Trusty containers in
+  Travis for CI and CD.
+
+v36.2.4
+-------
+
+* #1092: ``pkg_resources`` now uses ``inspect.getmro`` to
+  resolve classes in method resolution order.
+
+v36.2.3
+-------
+
+* #1102: Restore behavior for empty extras.
+
+v36.2.2
+-------
+
+* #1099: Revert commit a3ec721, restoring intended purpose of
+  extras as part of a requirement declaration.
+
+v36.2.1
+-------
+
+* fix #1086
+* fix #1087
+* support extras specifiers in install_requires requirements
+
+v36.2.0
+-------
+
+* #1081: Environment markers indicated in ``install_requires``
+  are now processed and treated as nameless ``extras_require``
+  with markers, allowing their metadata in requires.txt to be
+  correctly generated.
+
+* #1053: Tagged commits are now released using Travis-CI
+  build stages, meaning releases depend on passing tests on
+  all supported Python versions (Linux) and not just the latest
+  Python version.
+
+v36.1.1
+-------
+
+* #1083: Correct ``py31compat.makedirs`` to correctly honor
+  ``exist_ok`` parameter.
+* #1083: Also use makedirs compatibility throughout setuptools.
+
+v36.1.0
+-------
+
+* #1083: Avoid race condition on directory creation in
+  ``pkg_resources.ensure_directory``.
+
+* Removed deprecation of and restored support for
+  ``upload_docs`` command for sites other than PyPI.
+  Only warehouse is dropping support, but services like
+  `devpi <http://doc.devpi.net/latest/>`_ continue to
+  support docs built by setuptools' plugins. See
+  `this comment <https://bitbucket.org/hpk42/devpi/issues/388/support-rtd-model-for-building-uploading#comment-34292423>`_
+  for more context on the motivation for this change.
+
+v36.0.1
+-------
+
+* #1042: Fix import in py27compat module that still
+  referenced six directly, rather than through the externs
+  module (vendored packages hook).
+
+v36.0.0
+-------
+
+* #980 and others: Once again, Setuptools vendors all
+  of its dependencies. It seems to be the case that in
+  the Python ecosystem, all build tools must run without
+  any dependencies (build, runtime, or otherwise). At
+  such a point that a mechanism exists that allows
+  build tools to have dependencies, Setuptools will adopt
+  it.
+
+v35.0.2
+-------
+
+* #1015: Fix test failures on Python 3.7.
+
+* #1024: Add workaround for Jython #2581 in monkey module.
+
+v35.0.1
+-------
+
+* #992: Revert change introduced in v34.4.1, now
+  considered invalid.
+
+* #1016: Revert change introduced in v35.0.0 per #1014,
+  referencing #436. The approach had unintended
+  consequences, causing sdist installs to be missing
+  files.
+
+v35.0.0
+-------
+
+* #436: In egg_info.manifest_maker, no longer read
+  the file list from the manifest file, and instead
+  re-build it on each build. In this way, files removed
+  from the specification will not linger in the manifest.
+  As a result, any files manually added to the manifest
+  will be removed on subsequent egg_info invocations.
+  No projects should be manually adding files to the
+  manifest and should instead use MANIFEST.in or SCM
+  file finders to force inclusion of files in the manifest.
+
+v34.4.1
+-------
+
+* #1008: In MSVC support, use always the last version available for Windows SDK and UCRT SDK.
+
+* #1008: In MSVC support, fix "vcruntime140.dll" returned path with Visual Studio 2017.
+
+* #992: In msvc.msvc9_query_vcvarsall, ensure the
+  returned dicts have str values and not Unicode for
+  compatibility with os.environ.
+
+v34.4.0
+-------
+
+* #995: In MSVC support, add support for "Microsoft Visual Studio 2017" and "Microsoft Visual Studio Build Tools 2017".
+
+* #999 via #1007: Extend support for declarative package
+  config in a setup.cfg file to include the options
+  ``python_requires`` and ``py_modules``.
+
+v34.3.3
+-------
+
+* #967 (and #997): Explicitly import submodules of
+  packaging to account for environments where the imports
+  of those submodules is not implied by other behavior.
+
+v34.3.2
+-------
+
+* #993: Fix documentation upload by correcting
+  rendering of content-type in _build_multipart
+  on Python 3.
+
+v34.3.1
+-------
+
+* #988: Trap ``os.unlink`` same as ``os.remove`` in
+  ``auto_chmod`` error handler.
+
+* #983: Fixes to invalid escape sequence deprecations on
+  Python 3.6.
+
+v34.3.0
+-------
+
+* #941: In the upload command, if the username is blank,
+  default to ``getpass.getuser()``.
+
+* #971: Correct distutils findall monkeypatch to match
+  appropriate versions (namely Python 3.4.6).
+
+v34.2.0
+-------
+
+* #966: Add support for reading dist-info metadata and
+  thus locating Distributions from zip files.
+
+* #968: Allow '+' and '!' in egg fragments
+  so that it can take package names that contain
+  PEP 440 conforming version specifiers.
+
+v34.1.1
+-------
+
+* #953: More aggressively employ the compatibility issue
+  originally added in #706.
+
+v34.1.0
+-------
+
+* #930: ``build_info`` now accepts two new parameters
+  to optimize and customize the building of C libraries.
+
+v34.0.3
+-------
+
+* #947: Loosen restriction on the version of six required,
+  restoring compatibility with environments relying on
+  six 1.6.0 and later.
+
+v34.0.2
+-------
+
+* #882: Ensure extras are honored when building the
+  working set.
+* #913: Fix issue in develop if package directory has
+  a trailing slash.
+
+v34.0.1
+-------
+
+* #935: Fix glob syntax in graft.
+
+v34.0.0
+-------
+
+* #581: Instead of vendoring the growing list of
+  dependencies that Setuptools requires to function,
+  Setuptools now requires these dependencies just like
+  any other project. Unlike other projects, however,
+  Setuptools cannot rely on ``setup_requires`` to
+  demand the dependencies it needs to install because
+  its own machinery would be necessary to pull those
+  dependencies if not present (a bootstrapping problem).
+  As a result, Setuptools no longer supports self upgrade or
+  installation in the general case. Instead, users are
+  directed to use pip to install and upgrade using the
+  ``wheel`` distributions of setuptools.
+
+  Users are welcome to contrive other means to install
+  or upgrade Setuptools using other means, such as
+  pre-installing the Setuptools dependencies with pip
+  or a bespoke bootstrap tool, but such usage is not
+  recommended and is not supported.
+
+  As discovered in #940, not all versions of pip will
+  successfully install Setuptools from its pre-built
+  wheel. If you encounter issues with "No module named
+  six" or "No module named packaging", especially
+  following a line "Running setup.py egg_info for package
+  setuptools", then your pip is not new enough.
+
+  There's an additional issue in pip where setuptools
+  is upgraded concurrently with other source packages,
+  described in pip #4253. The proposed workaround is to
+  always upgrade Setuptools first prior to upgrading
+  other packages that would upgrade Setuptools.
+
+v33.1.1
+-------
+
+* #921: Correct issue where certifi fallback not being
+  reached on Windows.
+
+v33.1.0
+-------
+
+Installation via pip, as indicated in the `Python Packaging
+User's Guide <https://packaging.python.org/installing/>`_,
+is the officially-supported mechanism for installing
+Setuptools, and this recommendation is now explicit in the
+much more concise README.
+
+Other edits and tweaks were made to the documentation. The
+codebase is unchanged.
+
+v33.0.0
+-------
+
+* #619: Removed support for the ``tag_svn_revision``
+  distribution option. If Subversion tagging support is
+  still desired, consider adding the functionality to
+  setuptools_svn in setuptools_svn #2.
+
+v32.3.1
+-------
+
+* #866: Use ``dis.Bytecode`` on Python 3.4 and later in
+  ``setuptools.depends``.
+
+v32.3.0
+-------
+
+* #889: Backport proposed fix for disabling interpolation in
+  distutils.Distribution.parse_config_files.
+
+v32.2.0
+-------
+
+* #884: Restore support for running the tests under
+  `pytest-runner <https://github.com/pytest-dev/pytest-runner>`_
+  by ensuring that PYTHONPATH is honored in tests invoking
+  a subprocess.
+
+v32.1.3
+-------
+
+* #706: Add rmtree compatibility shim for environments where
+  rmtree fails when passed a unicode string.
+
+v32.1.2
+-------
+
+* #893: Only release sdist in zip format as warehouse now
+  disallows releasing two different formats.
+
+v32.1.1
+-------
+
+* #704: More selectively ensure that 'rmtree' is not invoked with
+  a byte string, enabling it to remove files that are non-ascii,
+  even on Python 2.
+
+* #712: In 'sandbox.run_setup', ensure that ``__file__`` is
+  always a ``str``, modeling the behavior observed by the
+  interpreter when invoking scripts and modules.
+
+v32.1.0
+-------
+
+* #891: In 'test' command on test failure, raise DistutilsError,
+  suppression invocation of subsequent commands.
+
+v32.0.0
+-------
+
+* #890: Revert #849. ``global-exclude .foo`` will not match all
+  ``*.foo`` files any more. Package authors must add an explicit
+  wildcard, such as ``global-exclude *.foo``, to match all
+  ``.foo`` files. See #886, #849.
+
+v31.0.1
+-------
+
+* #885: Fix regression where 'pkg_resources._rebuild_mod_path'
+  would fail when a namespace package's '__path__' was not
+  a list with a sort attribute.
+
+v31.0.0
+-------
+
+* #250: Install '-nspkg.pth' files for packages installed
+  with 'setup.py develop'. These .pth files allow
+  namespace packages installed by pip or develop to
+  co-mingle. This change required the removal of the
+  change for #805 and pip #1924, introduced in 28.3.0 and implicated
+  in #870, but means that namespace packages not in a
+  site packages directory will no longer work on Python
+  earlier than 3.5, whereas before they would work on
+  Python not earlier than 3.3.
+
+v30.4.0
+-------
+
+* #879: For declarative config:
+
+  - read_configuration() now accepts ignore_option_errors argument. This allows scraping tools to read metadata without a need to download entire packages. E.g. we can gather some stats right from GitHub repos just by downloading setup.cfg.
+
+  - packages find: directive now supports fine tuning from a subsection. The same arguments as for find() are accepted.
+
+v30.3.0
+-------
+
+* #394 via #862: Added support for `declarative package
+  config in a setup.cfg file
+  <https://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files>`_.
+
+v30.2.1
+-------
+
+* #850: In test command, invoke unittest.main with
+  indication not to exit the process.
+
+v30.2.0
+-------
+
+* #854: Bump to vendored Packaging 16.8.
+
+v30.1.0
+-------
+
+* #846: Also trap 'socket.error' when opening URLs in
+  package_index.
+
+* #849: Manifest processing now matches the filename
+  pattern anywhere in the filename and not just at the
+  start. Restores behavior found prior to 28.5.0.
+
+v30.0.0
+-------
+
+* #864: Drop support for Python 3.2. Systems requiring
+  Python 3.2 support must use 'setuptools < 30'.
+
+* #825: Suppress warnings for single files.
+
+* #830 via #843: Once again restored inclusion of data
+  files to sdists, but now trap TypeError caused by
+  techniques employed rjsmin and similar.
+
+v29.0.1
+-------
+
+* #861: Re-release of v29.0.1 with the executable script
+  launchers bundled. Now, launchers are included by default
+  and users that want to disable this behavior must set the
+  environment variable
+  'SETUPTOOLS_INSTALL_WINDOWS_SPECIFIC_FILES' to
+  a false value like "false" or "0".
+
+v29.0.0
+-------
+
+* #841: Drop special exception for packages invoking
+  win32com during the build/install process. See
+  Distribute #118 for history.
+
+v28.8.0
+-------
+
+* #629: Per the discussion, refine the sorting to use version
+  value order for more accurate detection of the latest
+  available version when scanning for packages. See also
+  #829.
+
+* #837: Rely on the config var "SO" for Python 3.3.0 only
+  when determining the ext filename.
+
+v28.7.1
+-------
+
+* #827: Update PyPI root for dependency links.
+
+* #833: Backed out changes from #830 as the implementation
+  seems to have problems in some cases.
+
+v28.7.0
+-------
+
+* #832: Moved much of the namespace package handling
+  functionality into a separate module for re-use in something
+  like #789.
+* #830: ``sdist`` command no longer suppresses the inclusion
+  of data files, re-aligning with the expectation of distutils
+  and addressing #274 and #521.
+
+v28.6.1
+-------
+
+* #816: Fix manifest file list order in tests.
+
+v28.6.0
+-------
+
+* #629: When scanning for packages, ``pkg_resources`` now
+  ignores empty egg-info directories and gives precedence to
+  packages whose versions are lexicographically greatest,
+  a rough approximation for preferring the latest available
+  version.
+
+v28.5.0
+-------
+
+* #810: Tests are now invoked with tox and not setup.py test.
+* #249 and #450 via #764: Avoid scanning the whole tree
+  when building the manifest. Also fixes a long-standing bug
+  where patterns in ``MANIFEST.in`` had implicit wildcard
+  matching. This caused ``global-exclude .foo`` to exclude
+  all ``*.foo`` files, but also ``global-exclude bar.py`` to
+  exclude ``foo_bar.py``.
+
+v28.4.0
+-------
+
+* #732: Now extras with a hyphen are honored per PEP 426.
+* #811: Update to pyparsing 2.1.10.
+* Updated ``setuptools.command.sdist`` to re-use most of
+  the functionality directly from ``distutils.command.sdist``
+  for the ``add_defaults`` method with strategic overrides.
+  See #750 for rationale.
+* #760 via #762: Look for certificate bundle where SUSE
+  Linux typically presents it. Use ``certifi.where()`` to locate
+  the bundle.
+
+v28.3.0
+-------
+
+* #809: In ``find_packages()``, restore support for excluding
+  a parent package without excluding a child package.
+
+* #805: Disable ``-nspkg.pth`` behavior on Python 3.3+ where
+  PEP-420 functionality is adequate. Fixes pip #1924.
+
+v28.1.0
+-------
+
+* #803: Bump certifi to 2016.9.26.
+
+v28.0.0
+-------
+
+* #733: Do not search excluded directories for packages.
+  This introduced a backwards incompatible change in ``find_packages()``
+  so that ``find_packages(exclude=['foo']) == []``, excluding subpackages of ``foo``.
+  Previously, ``find_packages(exclude=['foo']) == ['foo.bar']``,
+  even though the parent ``foo`` package was excluded.
+
+* #795: Bump certifi.
+
+* #719: Suppress decoding errors and instead log a warning
+  when metadata cannot be decoded.
+
+v27.3.1
+-------
+
+* #790: In MSVC monkeypatching, explicitly patch each
+  function by name in the target module instead of inferring
+  the module from the function's ``__module__``. Improves
+  compatibility with other packages that might have previously
+  patched distutils functions (i.e. NumPy).
+
+v27.3.0
+-------
+
+* #794: In test command, add installed eggs to PYTHONPATH
+  when invoking tests so that subprocesses will also have the
+  dependencies available. Fixes `tox 330
+  <https://github.com/tox-dev/tox/issues/330>`_.
+
+* #795: Update vendored pyparsing 2.1.9.
+
+v27.2.0
+-------
+
+* #520 and #513: Suppress ValueErrors in fixup_namespace_packages
+  when lookup fails.
+
+* Nicer, more consistent interfaces for msvc monkeypatching.
+
+v27.1.2
+-------
+
+* #779 via #781: Fix circular import.
+
+v27.1.1
+-------
+
+* #778: Fix MSVC monkeypatching.
+
+v27.1.0
+-------
+
+* Introduce the (private) ``monkey`` module to encapsulate
+  the distutils monkeypatching behavior.
+
+v27.0.0
+-------
+
+* Now use Warehouse by default for
+  ``upload``, patching ``distutils.config.PyPIRCCommand`` to
+  affect default behavior.
+
+  Any config in .pypirc should be updated to replace
+
+    https://pypi.python.org/pypi/
+
+  with
+
+    https://upload.pypi.org/legacy/
+
+  Similarly, any passwords stored in the keyring should be
+  updated to use this new value for "system".
+
+  The ``upload_docs`` command will continue to use the python.org
+  site, but the command is now deprecated. Users are urged to use
+  Read The Docs instead.
+
+* #776: Use EXT_SUFFIX for py_limited_api renaming.
+
+* #774 and #775: Use LegacyVersion from packaging when
+  detecting numpy versions.
+
+v26.1.1
+-------
+
+* Re-release of 26.1.0 with pytest pinned to allow for automated
+  deployment and thus proper packaging environment variables,
+  fixing issues with missing executable launchers.
+
+v26.1.0
+-------
+
+* #763: ``pkg_resources.get_default_cache`` now defers to the
+  `appdirs project <https://pypi.org/project/appdirs>`_ to
+  resolve the cache directory. Adds a vendored dependency on
+  appdirs to pkg_resources.
+
+v26.0.0
+-------
+
+* #748: By default, sdists are now produced in gzipped tarfile
+  format by default on all platforms, adding forward compatibility
+  for the same behavior in Python 3.6 (See Python #27819).
+
+* #459 via #736: On Windows with script launchers,
+  sys.argv[0] now reflects
+  the name of the entry point, consistent with the behavior in
+  distlib and pip wrappers.
+
+* #752 via #753: When indicating ``py_limited_api`` to Extension,
+  it must be passed as a keyword argument.
+
+v25.4.0
+-------
+
+* Add Extension(py_limited_api=True). When set to a truthy value,
+  that extension gets a filename appropriate for code using Py_LIMITED_API.
+  When used correctly this allows a single compiled extension to work on
+  all future versions of CPython 3.
+  The py_limited_api argument only controls the filename. To be
+  compatible with multiple versions of Python 3, the C extension
+  will also need to set -DPy_LIMITED_API=... and be modified to use
+  only the functions in the limited API.
+
+v25.3.0
+-------
+
+* #739 Fix unquoted libpaths by fixing compatibility between `numpy.distutils` and `distutils._msvccompiler` for numpy < 1.11.2 (Fix issue #728, error also fixed in Numpy).
+
+* #731: Bump certifi.
+
+* Style updates. See #740, #741, #743, #744, #742, #747.
+
+* #735: include license file.
+
+v25.2.0
+-------
+
+* #612 via #730: Add a LICENSE file which needs to be provided by the terms of
+  the MIT license.
+
+v25.1.6
+-------
+
+* #725: revert `library_dir_option` patch (Error is related to `numpy.distutils` and make errors on non Numpy users).
+
+v25.1.5
+-------
+
+* #720
+* #723: Improve patch for `library_dir_option`.
+
+v25.1.4
+-------
+
+* #717
+* #713
+* #707: Fix Python 2 compatibility for MSVC by catching errors properly.
+* #715: Fix unquoted libpaths by patching `library_dir_option`.
+
+v25.1.3
+-------
+
+* #714 and #704: Revert fix as it breaks other components
+  downstream that can't handle unicode. See #709, #710,
+  and #712.
+
+v25.1.2
+-------
+
+* #704: Fix errors when installing a zip sdist that contained
+  files named with non-ascii characters on Windows would
+  crash the install when it attempted to clean up the build.
+* #646: MSVC compatibility - catch errors properly in
+  RegistryInfo.lookup.
+* #702: Prevent UnboundLocalError when initial working_set
+  is empty.
+
+v25.1.1
+-------
+
+* #686: Fix issue in sys.path ordering by pkg_resources when
+  rewrite technique is "raw".
+* #699: Fix typo in msvc support.
+
+v25.1.0
+-------
+
+* #609: Setuptools will now try to download a distribution from
+  the next possible download location if the first download fails.
+  This means you can now specify multiple links as ``dependency_links``
+  and all links will be tried until a working download link is encountered.
+
+v25.0.2
+-------
+
+* #688: Fix AttributeError in setup.py when invoked not from
+  the current directory.
+
+v25.0.1
+-------
+
+* Cleanup of setup.py script.
+
+* Fixed documentation builders by allowing setup.py
+  to be imported without having bootstrapped the
+  metadata.
+
+* More style cleanup. See #677, #678, #679, #681, #685.
+
+v25.0.0
+-------
+
+* #674: Default ``sys.path`` manipulation by easy-install.pth
+  is now "raw", meaning that when writing easy-install.pth
+  during any install operation, the ``sys.path`` will not be
+  rewritten and will no longer give preference to easy_installed
+  packages.
+
+  To retain the old behavior when using any easy_install
+  operation (including ``setup.py install`` when setuptools is
+  present), set the environment variable:
+
+    SETUPTOOLS_SYS_PATH_TECHNIQUE=rewrite
+
+  This project hopes that that few if any environments find it
+  necessary to retain the old behavior, and intends to drop
+  support for it altogether in a future release. Please report
+  any relevant concerns in the ticket for this change.
+
+v24.3.1
+-------
+
+* #398: Fix shebang handling on Windows in script
+  headers where spaces in ``sys.executable`` would
+  produce an improperly-formatted shebang header,
+  introduced in 12.0 with the fix for #188.
+
+* #663, #670: More style updates.
+
+v24.3.0
+-------
+
+* #516: Disable ``os.link`` to avoid hard linking
+  in ``sdist.make_distribution``, avoiding errors on
+  systems that support hard links but not on the
+  file system in which the build is occurring.
+
+v24.2.1
+-------
+
+* #667: Update Metadata-Version to 1.2 when
+  ``python_requires`` is supplied.
+
+v24.2.0
+-------
+
+* #631: Add support for ``python_requires`` keyword.
+
+v24.1.1
+-------
+
+* More style updates. See #660, #661, #641.
+
+v24.1.0
+-------
+
+* #659: ``setup.py`` now will fail fast and with a helpful
+  error message when the necessary metadata is missing.
+* More style updates. See #656, #635, #640,
+  #644, #650, #652, and #655.
+
+v24.0.3
+-------
+
+* Updated style in much of the codebase to match
+  community expectations. See #632, #633, #634,
+  #637, #639, #638, #642, #648.
+
+v24.0.2
+-------
+
+* If MSVC++14 is needed ``setuptools.msvc`` now redirect
+  user to Visual C++ Build Tools web page.
+
+v24.0.1
+-------
+
+* #625 and #626: Fixes on ``setuptools.msvc`` mainly
+  for Python 2 and Linux.
+
+v24.0.0
+-------
+
+* Pull Request #174: Add more aggressive support for
+  standalone Microsoft Visual C++ compilers in
+  msvc9compiler patch.
+  Particularly : Windows SDK 6.1 and 7.0
+  (MSVC++ 9.0), Windows SDK 7.1 (MSVC++ 10.0),
+  Visual C++ Build Tools 2015 (MSVC++14)
+* Renamed ``setuptools.msvc9_support`` to
+  ``setuptools.msvc``.
+
+v23.2.1
+-------
+
+Re-release of v23.2.0, which was missing the intended
+commits.
+
+* #623: Remove used of deprecated 'U' flag when reading
+  manifests.
+
+v23.1.0
+-------
+
+* #619: Deprecated ``tag_svn_revision`` distribution
+  option.
+
+v23.0.0
+-------
+
+* #611: Removed ARM executables for CLI and GUI script
+  launchers on Windows. If this was a feature you cared
+  about, please comment in the ticket.
+* #604: Removed docs building support. The project
+  now relies on documentation hosted at
+  https://setuptools.readthedocs.io/.
+
+v22.0.5
+-------
+
+* #604: Restore repository for upload_docs command
+  to restore publishing of docs during release.
+
+v22.0.4
+-------
+
+* #589: Upload releases to pypi.io using the upload
+  hostname and legacy path.
+
+v22.0.3
+-------
+
+* #589: Releases are now uploaded to pypi.io (Warehouse)
+  even when releases are made on Twine via Travis.
+
+v22.0.2
+-------
+
+* #589: Releases are now uploaded to pypi.io (Warehouse).
+
+v22.0.1
+-------
+
+* #190: On Python 2, if unicode is passed for packages to
+  ``build_py`` command, it will be handled just as with
+  text on Python 3.
+
+v22.0.0
+-------
+
+Intended to be v21.3.0, but jaraco accidentally released as
+a major bump.
+
+* #598: Setuptools now lists itself first in the User-Agent
+  for web requests, better following the guidelines in
+  `RFC 7231
+  <https://tools.ietf.org/html/rfc7231#section-5.5.3>`_.
+
+v21.2.2
+-------
+
+* Minor fixes to changelog and docs.
+
+v21.2.1
+-------
+
+* #261: Exclude directories when resolving globs in
+  package_data.
+
+v21.2.0
+-------
+
+* #539: In the easy_install get_site_dirs, honor all
+  paths found in ``site.getsitepackages``.
+
+v21.1.0
+-------
+
+* #572: In build_ext, now always import ``_CONFIG_VARS``
+  from ``distutils`` rather than from ``sysconfig``
+  to allow ``distutils.sysconfig.customize_compiler``
+  configure the OS X compiler for ``-dynamiclib``.
+
+v21.0.0
+-------
+
+* Removed ez_setup.py from Setuptools sdist. The
+  bootstrap script will be maintained in its own
+  branch and should be generally be retrieved from
+  its canonical location at
+  https://bootstrap.pypa.io/ez_setup.py.
+
+v20.10.0
+--------
+
+* #553: egg_info section is now generated in a
+  deterministic order, matching the order generated
+  by earlier versions of Python. Except on Python 2.6,
+  order is preserved when existing settings are present.
+* #556: Update to Packaging 16.7, restoring support
+  for deprecated ``python_implmentation`` marker.
+* #555: Upload command now prompts for a password
+  when uploading to PyPI (or other repository) if no
+  password is present in .pypirc or in the keyring.
+
+v20.9.0
+-------
+
+* #548: Update certify version to 2016.2.28
+* #545: Safely handle deletion of non-zip eggs in rotate
+  command.
+
+v20.8.1
+-------
+
+* Issue #544: Fix issue with extra environment marker
+  processing in WorkingSet due to refactor in v20.7.0.
+
+v20.8.0
+-------
+
+* Issue #543: Re-release so that latest release doesn't
+  cause déjà vu with distribute and setuptools 0.7 in
+  older environments.
+
+v20.7.0
+-------
+
+* Refactored extra environment marker processing
+  in WorkingSet.
+* Issue #533: Fixed intermittent test failures.
+* Issue #536: In msvc9_support, trap additional exceptions
+  that might occur when importing
+  ``distutils.msvc9compiler`` in mingw environments.
+* Issue #537: Provide better context when package
+  metadata fails to decode in UTF-8.
+
+v20.6.8
+-------
+
+* Issue #523: Restored support for environment markers,
+  now honoring 'extra' environment markers.
+
+v20.6.7
+-------
+
+* Issue #523: Disabled support for environment markers
+  introduced in v20.5.
+
+v20.6.6
+-------
+
+* Issue #503: Restore support for PEP 345 environment
+  markers by updating to Packaging 16.6.
+
+v20.6.0
+-------
+
+* New release process that relies on
+  `bumpversion <https://github.com/peritus/bumpversion>`_
+  and Travis CI for continuous deployment.
+* Project versioning semantics now follow
+  `semver <https://semver.org>`_ precisely.
+  The 'v' prefix on version numbers now also allows
+  version numbers to be referenced in the changelog,
+  e.g. http://setuptools.readthedocs.io/en/latest/history.html#v20-6-0.
+
+20.5
+----
+
+* BB Pull Request #185, #470: Add support for environment markers
+  in requirements in install_requires, setup_requires,
+  tests_require as well as adding a test for the existing
+  extra_requires machinery.
+
+20.4
+----
+
+* Issue #422: Moved hosting to
+  `Github <https://github.com/pypa/setuptools>`_
+  from `Bitbucket <https://bitbucket.org/pypa/setuptools>`_.
+  Issues have been migrated, though all issues and comments
+  are attributed to bb-migration. So if you have a particular
+  issue or issues to which you've been subscribed, you will
+  want to "watch" the equivalent issue in Github.
+  The Bitbucket project will be retained for the indefinite
+  future, but Github now hosts the canonical project repository.
+
+20.3.1
+------
+
+* Issue #519: Remove import hook when reloading the
+  ``pkg_resources`` module.
+* BB Pull Request #184: Update documentation in ``pkg_resources``
+  around new ``Requirement`` implementation.
+
+20.3
+----
+
+* BB Pull Request #179: ``pkg_resources.Requirement`` objects are
+  now a subclass of ``packaging.requirements.Requirement``,
+  allowing any environment markers and url (if any) to be
+  affiliated with the requirement
+* BB Pull Request #179: Restore use of RequirementParseError
+  exception unintentionally dropped in 20.2.
+
+20.2.2
+------
+
+* Issue #502: Correct regression in parsing of multiple
+  version specifiers separated by commas and spaces.
+
+20.2.1
+------
+
+* Issue #499: Restore compatibility for legacy versions
+  by bumping to packaging 16.4.
+
+20.2
+----
+
+* Changelog now includes release dates and links to PEPs.
+* BB Pull Request #173: Replace dual PEP 345 _markerlib implementation
+  and PEP 426 implementation of environment marker support from
+  packaging 16.1 and PEP 508. Fixes Issue #122.
+  See also BB Pull Request #175, BB Pull Request #168, and
+  BB Pull Request #164. Additionally:
+
+   - ``Requirement.parse`` no longer retains the order of extras.
+   - ``parse_requirements`` now requires that all versions be
+     PEP-440 compliant, as revealed in #499. Packages released
+     with invalid local versions should be re-released using
+     the proper local version syntax, e.g. ``mypkg-1.0+myorg.1``.
+
+20.1.1
+------
+
+* Update ``upload_docs`` command to also honor keyring
+  for password resolution.
+
+20.1
+----
+
+* Added support for using passwords from keyring in the upload
+  command. See `the upload docs
+  <https://setuptools.readthedocs.io/en/latest/setuptools.html#upload-upload-source-and-or-egg-distributions-to-pypi>`_
+  for details.
+
+20.0
+----
+
+* Issue #118: Once again omit the package metadata (egg-info)
+  from the list of outputs in ``--record``. This version of setuptools
+  can no longer be used to upgrade pip earlier than 6.0.
+
+19.7
+----
+
+* `Off-project PR <https://github.com/jaraco/setuptools/pull/32>`_:
+  For FreeBSD, also honor root certificates from ca_root_nss.
+
+19.6.2
+------
+
+* Issue #491: Correct regression incurred in 19.4 where
+  a double-namespace package installed using pip would
+  cause a TypeError.
+
+19.6.1
+------
+
+* Restore compatibility for PyPy 3 compatibility lost in
+  19.4.1 addressing Issue #487.
+* ``setuptools.launch`` shim now loads scripts in a new
+  namespace, avoiding getting relative imports from
+  the setuptools package on Python 2.
+
+19.6
+----
+
+* Added a new entry script ``setuptools.launch``,
+  implementing the shim found in
+  ``pip.util.setuptools_build``. Use this command to launch
+  distutils-only packages under setuptools in the same way that
+  pip does, causing the setuptools monkeypatching of distutils
+  to be invoked prior to invoking a script. Useful for debugging
+  or otherwise installing a distutils-only package under
+  setuptools when pip isn't available or otherwise does not
+  expose the desired functionality. For example::
+
+    $ python -m setuptools.launch setup.py develop
+
+* Issue #488: Fix dual manifestation of Extension class in
+  extension packages installed as dependencies when Cython
+  is present.
+
+19.5
+----
+
+* Issue #486: Correct TypeError when getfilesystemencoding
+  returns None.
+* Issue #139: Clarified the license as MIT.
+* BB Pull Request #169: Removed special handling of command
+  spec in scripts for Jython.
+
+19.4.1
+------
+
+* Issue #487: Use direct invocation of ``importlib.machinery``
+  in ``pkg_resources`` to avoid missing detection on relevant
+  platforms.
+
+19.4
+----
+
+* Issue #341: Correct error in path handling of package data
+  files in ``build_py`` command when package is empty.
+* Distribute #323, Issue #141, Issue #207, and
+  BB Pull Request #167: Another implementation of
+  ``pkg_resources.WorkingSet`` and ``pkg_resources.Distribution``
+  that supports replacing an extant package with a new one,
+  allowing for setup_requires dependencies to supersede installed
+  packages for the session.
+
+19.3
+----
+
+* Issue #229: Implement new technique for readily incorporating
+  dependencies conditionally from vendored copies or primary
+  locations. Adds a new dependency on six.
+
+19.2
+----
+
+* BB Pull Request #163: Add get_command_list method to Distribution.
+* BB Pull Request #162: Add missing whitespace to multiline string
+  literals.
+
+19.1.1
+------
+
+* Issue #476: Cast version to string (using default encoding)
+  to avoid creating Unicode types on Python 2 clients.
+* Issue #477: In Powershell downloader, use explicit rendering
+  of strings, rather than rely on ``repr``, which can be
+  incorrect (especially on Python 2).
+
+19.1
+----
+
+* Issue #215: The bootstrap script ``ez_setup.py`` now
+  automatically detects
+  the latest version of setuptools (using PyPI JSON API) rather
+  than hard-coding a particular value.
+* Issue #475: Fix incorrect usage in _translate_metadata2.
+
+19.0
+----
+
+* Issue #442: Use RawConfigParser for parsing .pypirc file.
+  Interpolated values are no longer honored in .pypirc files.
+
+18.8.1
+------
+
+* Issue #440: Prevent infinite recursion when a SandboxViolation
+  or other UnpickleableException occurs in a sandbox context
+  with setuptools hidden. Fixes regression introduced in Setuptools
+  12.0.
+
+18.8
+----
+
+* Deprecated ``egg_info.get_pkg_info_revision``.
+* Issue #471: Don't rely on repr for an HTML attribute value in
+  package_index.
+* Issue #419: Avoid errors in FileMetadata when the metadata directory
+  is broken.
+* Issue #472: Remove deprecated use of 'U' in mode parameter
+  when opening files.
+
+18.7.1
+------
+
+* Issue #469: Refactored logic for Issue #419 fix to re-use metadata
+  loading from Provider.
+
+18.7
+----
+
+* Update dependency on certify.
+* BB Pull Request #160: Improve detection of gui script in
+  ``easy_install._adjust_header``.
+* Made ``test.test_args`` a non-data property; alternate fix
+  for the issue reported in BB Pull Request #155.
+* Issue #453: In ``ez_setup`` bootstrap module, unload all
+  ``pkg_resources`` modules following download.
+* BB Pull Request #158: Honor PEP-488 when excluding
+  files for namespace packages.
+* Issue #419 and BB Pull Request #144: Add experimental support for
+  reading the version info from distutils-installed metadata rather
+  than using the version in the filename.
+
+18.6.1
+------
+
+* Issue #464: Correct regression in invocation of superclass on old-style
+  class on Python 2.
+
+18.6
+----
+
+* Issue #439: When installing entry_point scripts under development,
+  omit the version number of the package, allowing any version of the
+  package to be used.
+
+18.5
+----
+
+* In preparation for dropping support for Python 3.2, a warning is
+  now logged when pkg_resources is imported on Python 3.2 or earlier
+  Python 3 versions.
+* `Add support for python_platform_implementation environment marker
+  <https://github.com/jaraco/setuptools/pull/28>`_.
+* `Fix dictionary mutation during iteration
+  <https://github.com/jaraco/setuptools/pull/29>`_.
+
+18.4
+----
+
+* Issue #446: Test command now always invokes unittest, even
+  if no test suite is supplied.
+
+18.3.2
+------
+
+* Correct another regression in setuptools.findall
+  where the fix for Python #12885 was lost.
+
+18.3.1
+------
+
+* Issue #425: Correct regression in setuptools.findall.
+
+18.3
+----
+
+* BB Pull Request #135: Setuptools now allows disabling of
+  the manipulation of the sys.path
+  during the processing of the easy-install.pth file. To do so, set
+  the environment variable ``SETUPTOOLS_SYS_PATH_TECHNIQUE`` to
+  anything but "rewrite" (consider "raw"). During any install operation
+  with manipulation disabled, setuptools packages will be appended to
+  sys.path naturally.
+
+  Future versions may change the default behavior to disable
+  manipulation. If so, the default behavior can be retained by setting
+  the variable to "rewrite".
+
+* Issue #257: ``easy_install --version`` now shows more detail
+  about the installation location and Python version.
+
+* Refactor setuptools.findall in preparation for re-submission
+  back to distutils.
+
+18.2
+----
+
+* Issue #412: More efficient directory search in ``find_packages``.
+
+18.1
+----
+
+* Upgrade to vendored packaging 15.3.
+
+18.0.1
+------
+
+* Issue #401: Fix failure in test suite.
+
+18.0
+----
+
+* Dropped support for builds with Pyrex. Only Cython is supported.
+* Issue #288: Detect Cython later in the build process, after
+  ``setup_requires`` dependencies are resolved.
+  Projects backed by Cython can now be readily built
+  with a ``setup_requires`` dependency. For example::
+
+    ext = setuptools.Extension('mylib', ['src/CythonStuff.pyx', 'src/CStuff.c'])
+    setuptools.setup(
+        ...
+        ext_modules=[ext],
+        setup_requires=['cython'],
+    )
+
+  For compatibility with older versions of setuptools, packagers should
+  still include ``src/CythonMod.c`` in the source distributions or
+  require that Cython be present before building source distributions.
+  However, for systems with this build of setuptools, Cython will be
+  downloaded on demand.
+* Issue #396: Fixed test failure on OS X.
+* BB Pull Request #136: Remove excessive quoting from shebang headers
+  for Jython.
+
+17.1.1
+------
+
+* Backed out unintended changes to pkg_resources, restoring removal of
+  deprecated imp module (`ref
+  <https://bitbucket.org/pypa/setuptools/commits/f572ec9563d647fa8d4ffc534f2af8070ea07a8b#comment-1881283>`_).
+
+17.1
+----
+
+* Issue #380: Add support for range operators on environment
+  marker evaluation.
+
+17.0
+----
+
+* Issue #378: Do not use internal importlib._bootstrap module.
+* Issue #390: Disallow console scripts with path separators in
+  the name. Removes unintended functionality and brings behavior
+  into parity with pip.
+
+16.0
+----
+
+* BB Pull Request #130: Better error messages for errors in
+  parsed requirements.
+* BB Pull Request #133: Removed ``setuptools.tests`` from the
+  installed packages.
+* BB Pull Request #129: Address deprecation warning due to usage
+  of imp module.
+
+15.2
+----
+
+* Issue #373: Provisionally expose
+  ``pkg_resources._initialize_master_working_set``, allowing for
+  imperative re-initialization of the master working set.
+
+15.1
+----
+
+* Updated to Packaging 15.1 to address Packaging #28.
+* Fix ``setuptools.sandbox._execfile()`` with Python 3.1.
+
+15.0
+----
+
+* BB Pull Request #126: DistributionNotFound message now lists the package or
+  packages that required it. E.g.::
+
+      pkg_resources.DistributionNotFound: The 'colorama>=0.3.1' distribution was not found and is required by smlib.log.
+
+  Note that zc.buildout once dependended on the string rendering of this
+  message to determine the package that was not found. This expectation
+  has since been changed, but older versions of buildout may experience
+  problems. See Buildout #242 for details.
+
+14.3.1
+------
+
+* Issue #307: Removed PEP-440 warning during parsing of versions
+  in ``pkg_resources.Distribution``.
+* Issue #364: Replace deprecated usage with recommended usage of
+  ``EntryPoint.load``.
+
+14.3
+----
+
+* Issue #254: When creating temporary egg cache on Unix, use mode 755
+  for creating the directory to avoid the subsequent warning if
+  the directory is group writable.
+
+14.2
+----
+
+* Issue #137: Update ``Distribution.hashcmp`` so that Distributions with
+  None for pyversion or platform can be compared against Distributions
+  defining those attributes.
+
+14.1.1
+------
+
+* Issue #360: Removed undesirable behavior from test runs, preventing
+  write tests and installation to system site packages.
+
+14.1
+----
+
+* BB Pull Request #125: Add ``__ne__`` to Requirement class.
+* Various refactoring of easy_install.
+
+14.0
+----
+
+* Bootstrap script now accepts ``--to-dir`` to customize save directory or
+  allow for re-use of existing repository of setuptools versions. See
+  BB Pull Request #112 for background.
+* Issue #285: ``easy_install`` no longer will default to installing
+  packages to the "user site packages" directory if it is itself installed
+  there. Instead, the user must pass ``--user`` in all cases to install
+  packages to the user site packages.
+  This behavior now matches that of "pip install". To configure
+  an environment to always install to the user site packages, consider
+  using the "install-dir" and "scripts-dir" parameters to easy_install
+  through an appropriate distutils config file.
+
+13.0.2
+------
+
+* Issue #359: Include pytest.ini in the sdist so invocation of py.test on the
+  sdist honors the pytest configuration.
+
+13.0.1
+------
+
+Re-release of 13.0. Intermittent connectivity issues caused the release
+process to fail and PyPI uploads no longer accept files for 13.0.
+
+13.0
+----
+
+* Issue #356: Back out BB Pull Request #119 as it requires Setuptools 10 or later
+  as the source during an upgrade.
+* Removed build_py class from setup.py. According to 892f439d216e, this
+  functionality was added to support upgrades from old Distribute versions,
+  0.6.5 and 0.6.6.
+
+12.4
+----
+
+* BB Pull Request #119: Restore writing of ``setup_requires`` to metadata
+  (previously added in 8.4 and removed in 9.0).
+
+12.3
+----
+
+* Documentation is now linked using the rst.linker package.
+* Fix ``setuptools.command.easy_install.extract_wininst_cfg()``
+  with Python 2.6 and 2.7.
+* Issue #354. Added documentation on building setuptools
+  documentation.
+
+12.2
+----
+
+* Issue #345: Unload all modules under pkg_resources during
+  ``ez_setup.use_setuptools()``.
+* Issue #336: Removed deprecation from ``ez_setup.use_setuptools``,
+  as it is clearly still used by buildout's bootstrap. ``ez_setup``
+  remains deprecated for use by individual packages.
+* Simplified implementation of ``ez_setup.use_setuptools``.
+
+12.1
+----
+
+* BB Pull Request #118: Soften warning for non-normalized versions in
+  Distribution.
+
+12.0.5
+------
+
+* Issue #339: Correct Attribute reference in ``cant_write_to_target``.
+* Issue #336: Deprecated ``ez_setup.use_setuptools``.
+
+12.0.4
+------
+
+* Issue #335: Fix script header generation on Windows.
+
+12.0.3
+------
+
+* Fixed incorrect class attribute in ``install_scripts``. Tests would be nice.
+
+12.0.2
+------
+
+* Issue #331: Fixed ``install_scripts`` command on Windows systems corrupting
+  the header.
+
+12.0.1
+------
+
+* Restore ``setuptools.command.easy_install.sys_executable`` for pbr
+  compatibility. For the future, tools should construct a CommandSpec
+  explicitly.
+
+12.0
+----
+
+* Issue #188: Setuptools now support multiple entities in the value for
+  ``build.executable``, such that an executable of "/usr/bin/env my-python" may
+  be specified. This means that systems with a specified executable whose name
+  has spaces in the path must be updated to escape or quote that value.
+* Deprecated ``easy_install.ScriptWriter.get_writer``, replaced by ``.best()``
+  with slightly different semantics (no force_windows flag).
+
+11.3.1
+------
+
+* Issue #327: Formalize and restore support for any printable character in an
+  entry point name.
+
+11.3
+----
+
+* Expose ``EntryPoint.resolve`` in place of EntryPoint._load, implementing the
+  simple, non-requiring load. Deprecated all uses of ``EntryPoint._load``
+  except for calling with no parameters, which is just a shortcut for
+  ``ep.require(); ep.resolve();``.
+
+  Apps currently invoking ``ep.load(require=False)`` should instead do the
+  following if wanting to avoid the deprecating warning::
+
+    getattr(ep, "resolve", lambda: ep.load(require=False))()
+
+11.2
+----
+
+* Pip #2326: Report deprecation warning at stacklevel 2 for easier diagnosis.
+
+11.1
+----
+
+* Issue #281: Since Setuptools 6.1 (Issue #268), a ValueError would be raised
+  in certain cases where VersionConflict was raised with two arguments, which
+  occurred in ``pkg_resources.WorkingSet.find``. This release adds support
+  for indicating the dependent packages while maintaining support for
+  a VersionConflict when no dependent package context is known. New unit tests
+  now capture the expected interface.
+
+11.0
+----
+
+* Interop #3: Upgrade to Packaging 15.0; updates to PEP 440 so that >1.7 does
+  not exclude 1.7.1 but does exclude 1.7.0 and 1.7.0.post1.
+
+10.2.1
+------
+
+* Issue #323: Fix regression in entry point name parsing.
+
+10.2
+----
+
+* Deprecated use of EntryPoint.load(require=False). Passing a boolean to a
+  function to select behavior is an anti-pattern. Instead use
+  ``Entrypoint._load()``.
+* Substantial refactoring of all unit tests. Tests are now much leaner and
+  re-use a lot of fixtures and contexts for better clarity of purpose.
+
+10.1
+----
+
+* Issue #320: Added a compatibility implementation of
+  ``sdist._default_revctrl``
+  so that systems relying on that interface do not fail (namely, Ubuntu 12.04
+  and similar Debian releases).
+
+10.0.1
+------
+
+* Issue #319: Fixed issue installing pure distutils packages.
+
+10.0
+----
+
+* Issue #313: Removed built-in support for subversion. Projects wishing to
+  retain support for subversion will need to use a third party library. The
+  extant implementation is being ported to `setuptools_svn
+  <https://pypi.python.org/pypi/setuptools_svn>`_.
+* Issue #315: Updated setuptools to hide its own loaded modules during
+  installation of another package. This change will enable setuptools to
+  upgrade (or downgrade) itself even when its own metadata and implementation
+  change.
+
+9.1
+---
+
+* Prefer vendored packaging library `as recommended
+  <https://github.com/jaraco/setuptools/commit/170657b68f4b92e7e1bf82f5e19a831f5744af67#commitcomment-9109448>`_.
+
+9.0.1
+-----
+
+* Issue #312: Restored presence of pkg_resources API tests (doctest) to sdist.
+
+9.0
+---
+
+* Issue #314: Disabled support for ``setup_requires`` metadata to avoid issue
+  where Setuptools was unable to upgrade over earlier versions.
+
+8.4
+---
+
+* BB Pull Request #106: Now write ``setup_requires`` metadata.
+
+8.3
+---
+
+* Issue #311: Decoupled pkg_resources from setuptools once again.
+  ``pkg_resources`` is now a package instead of a module.
+
+8.2.1
+-----
+
+* Issue #306: Suppress warnings about Version format except in select scenarios
+  (such as installation).
+
+8.2
+---
+
+* BB Pull Request #85: Search egg-base when adding egg-info to manifest.
+
+8.1
+---
+
+* Upgrade ``packaging`` to 14.5, giving preference to "rc" as designator for
+  release candidates over "c".
+* PEP-440 warnings are now raised as their own class,
+  ``pkg_resources.PEP440Warning``, instead of RuntimeWarning.
+* Disabled warnings on empty versions.
+
+8.0.4
+-----
+
+* Upgrade ``packaging`` to 14.4, fixing an error where there is a
+  different result for if 2.0.5 is contained within >2.0dev and >2.0.dev even
+  though normalization rules should have made them equal.
+* Issue #296: Add warning when a version is parsed as legacy. This warning will
+  make it easier for developers to recognize deprecated version numbers.
+
+8.0.3
+-----
+
+* Issue #296: Restored support for ``__hash__`` on parse_version results.
+
+8.0.2
+-----
+
+* Issue #296: Restored support for ``__getitem__`` and sort operations on
+  parse_version result.
+
+8.0.1
+-----
+
+* Issue #296: Restore support for iteration over parse_version result, but
+  deprecated that usage with a warning. Fixes failure with buildout.
+
+8.0
+---
+
+* Implement PEP 440 within
+  pkg_resources and setuptools. This change
+  deprecates some version numbers such that they will no longer be installable
+  without using the ``===`` escape hatch. See `the changes to test_resources
+  <https://bitbucket.org/pypa/setuptools/commits/dcd552da643c4448056de84c73d56da6d70769d5#chg-setuptools/tests/test_resources.py>`_
+  for specific examples of version numbers and specifiers that are no longer
+  supported. Setuptools now "vendors" the `packaging
+  <https://github.com/pypa/packaging>`_ library.
+
+7.0
+---
+
+* Issue #80, Issue #209: Eggs that are downloaded for ``setup_requires``,
+  ``test_requires``, etc. are now placed in a ``./.eggs`` directory instead of
+  directly in the current directory. This choice of location means the files
+  can be readily managed (removed, ignored). Additionally,
+  later phases or invocations of setuptools will not detect the package as
+  already installed and ignore it for permanent install (See #209).
+
+  This change is indicated as backward-incompatible as installations that
+  depend on the installation in the current directory will need to account for
+  the new location. Systems that ignore ``*.egg`` will probably need to be
+  adapted to ignore ``.eggs``. The files will need to be manually moved or
+  will be retrieved again. Most use cases will require no attention.
+
+6.1
+---
+
+* Issue #268: When resolving package versions, a VersionConflict now reports
+  which package previously required the conflicting version.
+
+6.0.2
+-----
+
+* Issue #262: Fixed regression in pip install due to egg-info directories
+  being omitted. Re-opens Issue #118.
+
+6.0.1
+-----
+
+* Issue #259: Fixed regression with namespace package handling on ``single
+  version, externally managed`` installs.
+
+6.0
+---
+
+* Issue #100: When building a distribution, Setuptools will no longer match
+  default files using platform-dependent case sensitivity, but rather will
+  only match the files if their case matches exactly. As a result, on Windows
+  and other case-insensitive file systems, files with names such as
+  'readme.txt' or 'README.TXT' will be omitted from the distribution and a
+  warning will be issued indicating that 'README.txt' was not found. Other
+  filenames affected are:
+
+    - README.rst
+    - README
+    - setup.cfg
+    - setup.py (or the script name)
+    - test/test*.py
+
+  Any users producing distributions with filenames that match those above
+  case-insensitively, but not case-sensitively, should rename those files in
+  their repository for better portability.
+* BB Pull Request #72: When using ``single_version_externally_managed``, the
+  exclusion list now includes Python 3.2 ``__pycache__`` entries.
+* BB Pull Request #76 and BB Pull Request #78: lines in top_level.txt are now
+  ordered deterministically.
+* Issue #118: The egg-info directory is now no longer included in the list
+  of outputs.
+* Issue #258: Setuptools now patches distutils msvc9compiler to
+  recognize the specially-packaged compiler package for easy extension module
+  support on Python 2.6, 2.7, and 3.2.
+
+5.8
+---
+
+* Issue #237: ``pkg_resources`` now uses explicit detection of Python 2 vs.
+  Python 3, supporting environments where builtins have been patched to make
+  Python 3 look more like Python 2.
+
+5.7
+---
+
+* Issue #240: Based on real-world performance measures against 5.4, zip
+  manifests are now cached in all circumstances. The
+  ``PKG_RESOURCES_CACHE_ZIP_MANIFESTS`` environment variable is no longer
+  relevant. The observed "memory increase" referenced in the 5.4 release
+  notes and detailed in Issue #154 was likely not an increase over the status
+  quo, but rather only an increase over not storing the zip info at all.
+
+5.6
+---
+
+* Issue #242: Use absolute imports in svn_utils to avoid issues if the
+  installing package adds an xml module to the path.
+
+5.5.1
+-----
+
+* Issue #239: Fix typo in 5.5 such that fix did not take.
+
+5.5
+---
+
+* Issue #239: Setuptools now includes the setup_requires directive on
+  Distribution objects and validates the syntax just like install_requires
+  and tests_require directives.
+
+5.4.2
+-----
+
+* Issue #236: Corrected regression in execfile implementation for Python 2.6.
+
+5.4.1
+-----
+
+* Python #7776: (ssl_support) Correct usage of host for validation when
+  tunneling for HTTPS.
+
+5.4
+---
+
+* Issue #154: ``pkg_resources`` will now cache the zip manifests rather than
+  re-processing the same file from disk multiple times, but only if the
+  environment variable ``PKG_RESOURCES_CACHE_ZIP_MANIFESTS`` is set. Clients
+  that package many modules in the same zip file will see some improvement
+  in startup time by enabling this feature. This feature is not enabled by
+  default because it causes a substantial increase in memory usage.
+
+5.3
+---
+
+* Issue #185: Make svn tagging work on the new style SVN metadata.
+  Thanks cazabon!
+* Prune revision control directories (e.g .svn) from base path
+  as well as sub-directories.
+
+5.2
+---
+
+* Added a `Developer Guide
+  <https://setuptools.readthedocs.io/en/latest/developer-guide.html>`_ to the official
+  documentation.
+* Some code refactoring and cleanup was done with no intended behavioral
+  changes.
+* During install_egg_info, the generated lines for namespace package .pth
+  files are now processed even during a dry run.
+
+5.1
+---
+
+* Issue #202: Implemented more robust cache invalidation for the ZipImporter,
+  building on the work in Issue #168. Special thanks to Jurko Gospodnetic and
+  PJE.
+
+5.0.2
+-----
+
+* Issue #220: Restored script templates.
+
+5.0.1
+-----
+
+* Renamed script templates to end with .tmpl now that they no longer need
+  to be processed by 2to3. Fixes spurious syntax errors during build/install.
+
+5.0
+---
+
+* Issue #218: Re-release of 3.8.1 to signal that it supersedes 4.x.
+* Incidentally, script templates were updated not to include the triple-quote
+  escaping.
+
+3.7.1 and 3.8.1 and 4.0.1
+-------------------------
+
+* Issue #213: Use legacy StringIO behavior for compatibility under pbr.
+* Issue #218: Setuptools 3.8.1 superseded 4.0.1, and 4.x was removed
+  from the available versions to install.
+
+4.0
+---
+
+* Issue #210: ``setup.py develop`` now copies scripts in binary mode rather
+  than text mode, matching the behavior of the ``install`` command.
+
+3.8
+---
+
+* Extend Issue #197 workaround to include all Python 3 versions prior to
+  3.2.2.
+
+3.7
+---
+
+* Issue #193: Improved handling of Unicode filenames when building manifests.
+
+3.6
+---
+
+* Issue #203: Honor proxy settings for Powershell downloader in the bootstrap
+  routine.
+
+3.5.2
+-----
+
+* Issue #168: More robust handling of replaced zip files and stale caches.
+  Fixes ZipImportError complaining about a 'bad local header'.
+
+3.5.1
+-----
+
+* Issue #199: Restored ``install._install`` for compatibility with earlier
+  NumPy versions.
+
+3.5
+---
+
+* Issue #195: Follow symbolic links in find_packages (restoring behavior
+  broken in 3.4).
+* Issue #197: On Python 3.1, PKG-INFO is now saved in a UTF-8 encoding instead
+  of ``sys.getpreferredencoding`` to match the behavior on Python 2.6-3.4.
+* Issue #192: Preferred bootstrap location is now
+  https://bootstrap.pypa.io/ez_setup.py (mirrored from former location).
+
+3.4.4
+-----
+
+* Issue #184: Correct failure where find_package over-matched packages
+  when directory traversal isn't short-circuited.
+
+3.4.3
+-----
+
+* Issue #183: Really fix test command with Python 3.1.
+
+3.4.2
+-----
+
+* Issue #183: Fix additional regression in test command on Python 3.1.
+
+3.4.1
+-----
+
+* Issue #180: Fix regression in test command not caught by py.test-run tests.
+
+3.4
+---
+
+* Issue #176: Add parameter to the test command to support a custom test
+  runner: --test-runner or -r.
+* Issue #177: Now assume most common invocation to install command on
+  platforms/environments without stack support (issuing a warning). Setuptools
+  now installs naturally on IronPython. Behavior on CPython should be
+  unchanged.
+
+3.3
+---
+
+* Add ``include`` parameter to ``setuptools.find_packages()``.
+
+3.2
+---
+
+* BB Pull Request #39: Add support for C++ targets from Cython ``.pyx`` files.
+* Issue #162: Update dependency on certifi to 1.0.1.
+* Issue #164: Update dependency on wincertstore to 0.2.
+
+3.1
+---
+
+* Issue #161: Restore Features functionality to allow backward compatibility
+  (for Features) until the uses of that functionality is sufficiently removed.
+
+3.0.2
+-----
+
+* Correct typo in previous bugfix.
+
+3.0.1
+-----
+
+* Issue #157: Restore support for Python 2.6 in bootstrap script where
+  ``zipfile.ZipFile`` does not yet have support for context managers.
+
+3.0
+---
+
+* Issue #125: Prevent Subversion support from creating a ~/.subversion
+  directory just for checking the presence of a Subversion repository.
+* Issue #12: Namespace packages are now imported lazily. That is, the mere
+  declaration of a namespace package in an egg on ``sys.path`` no longer
+  causes it to be imported when ``pkg_resources`` is imported. Note that this
+  change means that all of a namespace package's ``__init__.py`` files must
+  include a ``declare_namespace()`` call in order to ensure that they will be
+  handled properly at runtime. In 2.x it was possible to get away without
+  including the declaration, but only at the cost of forcing namespace
+  packages to be imported early, which 3.0 no longer does.
+* Issue #148: When building (bdist_egg), setuptools no longer adds
+  ``__init__.py`` files to namespace packages. Any packages that rely on this
+  behavior will need to create ``__init__.py`` files and include the
+  ``declare_namespace()``.
+* Issue #7: Setuptools itself is now distributed as a zip archive in addition to
+  tar archive. ez_setup.py now uses zip archive. This approach avoids the potential
+  security vulnerabilities presented by use of tar archives in ez_setup.py.
+  It also leverages the security features added to ZipFile.extract in Python 2.7.4.
+* Issue #65: Removed deprecated Features functionality.
+* BB Pull Request #28: Remove backport of ``_bytecode_filenames`` which is
+  available in Python 2.6 and later, but also has better compatibility with
+  Python 3 environments.
+* Issue #156: Fix spelling of __PYVENV_LAUNCHER__ variable.
+
+2.2
+---
+
+* Issue #141: Restored fix for allowing setup_requires dependencies to
+  override installed dependencies during setup.
+* Issue #128: Fixed issue where only the first dependency link was honored
+  in a distribution where multiple dependency links were supplied.
+
+2.1.2
+-----
+
+* Issue #144: Read long_description using codecs module to avoid errors
+  installing on systems where LANG=C.
+
+2.1.1
+-----
+
+* Issue #139: Fix regression in re_finder for CVS repos (and maybe Git repos
+  as well).
+
+2.1
+---
+
+* Issue #129: Suppress inspection of ``*.whl`` files when searching for files
+  in a zip-imported file.
+* Issue #131: Fix RuntimeError when constructing an egg fetcher.
+
+2.0.2
+-----
+
+* Fix NameError during installation with Python implementations (e.g. Jython)
+  not containing parser module.
+* Fix NameError in ``sdist:re_finder``.
+
+2.0.1
+-----
+
+* Issue #124: Fixed error in list detection in upload_docs.
+
+2.0
+---
+
+* Issue #121: Exempt lib2to3 pickled grammars from DirectorySandbox.
+* Issue #41: Dropped support for Python 2.4 and Python 2.5. Clients requiring
+  setuptools for those versions of Python should use setuptools 1.x.
+* Removed ``setuptools.command.easy_install.HAS_USER_SITE``. Clients
+  expecting this boolean variable should use ``site.ENABLE_USER_SITE``
+  instead.
+* Removed ``pkg_resources.ImpWrapper``. Clients that expected this class
+  should use ``pkgutil.ImpImporter`` instead.
+
+1.4.2
+-----
+
+* Issue #116: Correct TypeError when reading a local package index on Python
+  3.
+
+1.4.1
+-----
+
+* Issue #114: Use ``sys.getfilesystemencoding`` for decoding config in
+  ``bdist_wininst`` distributions.
+
+* Issue #105 and Issue #113: Establish a more robust technique for
+  determining the terminal encoding::
+
+    1. Try ``getpreferredencoding``
+    2. If that returns US_ASCII or None, try the encoding from
+       ``getdefaultlocale``. If that encoding was a "fallback" because Python
+       could not figure it out from the environment or OS, encoding remains
+       unresolved.
+    3. If the encoding is resolved, then make sure Python actually implements
+       the encoding.
+    4. On the event of an error or unknown codec, revert to fallbacks
+       (UTF-8 on Darwin, ASCII on everything else).
+    5. On the encoding is 'mac-roman' on Darwin, use UTF-8 as 'mac-roman' was
+       a bug on older Python releases.
+
+    On a side note, it would seem that the encoding only matters for when SVN
+    does not yet support ``--xml`` and when getting repository and svn version
+    numbers. The ``--xml`` technique should yield UTF-8 according to some
+    messages on the SVN mailing lists. So if the version numbers are always
+    7-bit ASCII clean, it may be best to only support the file parsing methods
+    for legacy SVN releases and support for SVN without the subprocess command
+    would simple go away as support for the older SVNs does.
+
+1.4
+---
+
+* Issue #27: ``easy_install`` will now use credentials from .pypirc if
+  present for connecting to the package index.
+* BB Pull Request #21: Omit unwanted newlines in ``package_index._encode_auth``
+  when the username/password pair length indicates wrapping.
+
+1.3.2
+-----
+
+* Issue #99: Fix filename encoding issues in SVN support.
+
+1.3.1
+-----
+
+* Remove exuberant warning in SVN support when SVN is not used.
+
+1.3
+---
+
+* Address security vulnerability in SSL match_hostname check as reported in
+  Python #17997.
+* Prefer `backports.ssl_match_hostname
+  <https://pypi.python.org/pypi/backports.ssl_match_hostname>`_ for backport
+  implementation if present.
+* Correct NameError in ``ssl_support`` module (``socket.error``).
+
+1.2
+---
+
+* Issue #26: Add support for SVN 1.7. Special thanks to Philip Thiem for the
+  contribution.
+* Issue #93: Wheels are now distributed with every release. Note that as
+  reported in Issue #108, as of Pip 1.4, scripts aren't installed properly
+  from wheels. Therefore, if using Pip to install setuptools from a wheel,
+  the ``easy_install`` command will not be available.
+* Setuptools "natural" launcher support, introduced in 1.0, is now officially
+  supported.
+
+1.1.7
+-----
+
+* Fixed behavior of NameError handling in 'script template (dev).py' (script
+  launcher for 'develop' installs).
+* ``ez_setup.py`` now ensures partial downloads are cleaned up following
+  a failed download.
+* Distribute #363 and Issue #55: Skip an sdist test that fails on locales
+  other than UTF-8.
+
+1.1.6
+-----
+
+* Distribute #349: ``sandbox.execfile`` now opens the target file in binary
+  mode, thus honoring a BOM in the file when compiled.
+
+1.1.5
+-----
+
+* Issue #69: Second attempt at fix (logic was reversed).
+
+1.1.4
+-----
+
+* Issue #77: Fix error in upload command (Python 2.4).
+
+1.1.3
+-----
+
+* Fix NameError in previous patch.
+
+1.1.2
+-----
+
+* Issue #69: Correct issue where 404 errors are returned for URLs with
+  fragments in them (such as #egg=).
+
+1.1.1
+-----
+
+* Issue #75: Add ``--insecure`` option to ez_setup.py to accommodate
+  environments where a trusted SSL connection cannot be validated.
+* Issue #76: Fix AttributeError in upload command with Python 2.4.
+
+1.1
+---
+
+* Issue #71 (Distribute #333): EasyInstall now puts less emphasis on the
+  condition when a host is blocked via ``--allow-hosts``.
+* Issue #72: Restored Python 2.4 compatibility in ``ez_setup.py``.
+
+1.0
+---
+
+* Issue #60: On Windows, Setuptools supports deferring to another launcher,
+  such as Vinay Sajip's `pylauncher <https://bitbucket.org/pypa/pylauncher>`_
+  (included with Python 3.3) to launch console and GUI scripts and not install
+  its own launcher executables. This experimental functionality is currently
+  only enabled if  the ``SETUPTOOLS_LAUNCHER`` environment variable is set to
+  "natural". In the future, this behavior may become default, but only after
+  it has matured and seen substantial adoption. The ``SETUPTOOLS_LAUNCHER``
+  also accepts "executable" to force the default behavior of creating launcher
+  executables.
+* Issue #63: Bootstrap script (ez_setup.py) now prefers Powershell, curl, or
+  wget for retrieving the Setuptools tarball for improved security of the
+  install. The script will still fall back to a simple ``urlopen`` on
+  platforms that do not have these tools.
+* Issue #65: Deprecated the ``Features`` functionality.
+* Issue #52: In ``VerifyingHTTPSConn``, handle a tunnelled (proxied)
+  connection.
+
+Backward-Incompatible Changes
+=============================
+
+This release includes a couple of backward-incompatible changes, but most if
+not all users will find 1.0 a drop-in replacement for 0.9.
+
+* Issue #50: Normalized API of environment marker support. Specifically,
+  removed line number and filename from SyntaxErrors when returned from
+  `pkg_resources.invalid_marker`. Any clients depending on the specific
+  string representation of exceptions returned by that function may need to
+  be updated to account for this change.
+* Issue #50: SyntaxErrors generated by `pkg_resources.invalid_marker` are
+  normalized for cross-implementation consistency.
+* Removed ``--ignore-conflicts-at-my-risk`` and ``--delete-conflicting``
+  options to easy_install. These options have been deprecated since 0.6a11.
+
+0.9.8
+-----
+
+* Issue #53: Fix NameErrors in `_vcs_split_rev_from_url`.
+
+0.9.7
+-----
+
+* Issue #49: Correct AttributeError on PyPy where a hashlib.HASH object does
+  not have a `.name` attribute.
+* Issue #34: Documentation now refers to bootstrap script in code repository
+  referenced by bookmark.
+* Add underscore-separated keys to environment markers (markerlib).
+
+0.9.6
+-----
+
+* Issue #44: Test failure on Python 2.4 when MD5 hash doesn't have a `.name`
+  attribute.
+
+0.9.5
+-----
+
+* Python #17980: Fix security vulnerability in SSL certificate validation.
+
+0.9.4
+-----
+
+* Issue #43: Fix issue (introduced in 0.9.1) with version resolution when
+  upgrading over other releases of Setuptools.
+
+0.9.3
+-----
+
+* Issue #42: Fix new ``AttributeError`` introduced in last fix.
+
+0.9.2
+-----
+
+* Issue #42: Fix regression where blank checksums would trigger an
+  ``AttributeError``.
+
+0.9.1
+-----
+
+* Distribute #386: Allow other positional and keyword arguments to os.open.
+* Corrected dependency on certifi mis-referenced in 0.9.
+
+0.9
+---
+
+* `package_index` now validates hashes other than MD5 in download links.
+
+0.8
+---
+
+* Code base now runs on Python 2.4 - Python 3.3 without Python 2to3
+  conversion.
+
+0.7.8
+-----
+
+* Distribute #375: Yet another fix for yet another regression.
+
+0.7.7
+-----
+
+* Distribute #375: Repair AttributeError created in last release (redo).
+* Issue #30: Added test for get_cache_path.
+
+0.7.6
+-----
+
+* Distribute #375: Repair AttributeError created in last release.
+
+0.7.5
+-----
+
+* Issue #21: Restore Python 2.4 compatibility in ``test_easy_install``.
+* Distribute #375: Merged additional warning from Distribute 0.6.46.
+* Now honor the environment variable
+  ``SETUPTOOLS_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT`` in addition to the now
+  deprecated ``DISTRIBUTE_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT``.
+
+0.7.4
+-----
+
+* Issue #20: Fix comparison of parsed SVN version on Python 3.
+
+0.7.3
+-----
+
+* Issue #1: Disable installation of Windows-specific files on non-Windows systems.
+* Use new sysconfig module with Python 2.7 or >=3.2.
+
+0.7.2
+-----
+
+* Issue #14: Use markerlib when the `parser` module is not available.
+* Issue #10: ``ez_setup.py`` now uses HTTPS to download setuptools from PyPI.
+
+0.7.1
+-----
+
+* Fix NameError (Issue #3) again - broken in bad merge.
+
+0.7
+---
+
+* Merged Setuptools and Distribute. See docs/merge.txt for details.
+
+Added several features that were slated for setuptools 0.6c12:
+
+* Index URL now defaults to HTTPS.
+* Added experimental environment marker support. Now clients may designate a
+  PEP-426 environment marker for "extra" dependencies. Setuptools uses this
+  feature in ``setup.py`` for optional SSL and certificate validation support
+  on older platforms. Based on Distutils-SIG discussions, the syntax is
+  somewhat tentative. There should probably be a PEP with a firmer spec before
+  the feature should be considered suitable for use.
+* Added support for SSL certificate validation when installing packages from
+  an HTTPS service.
+
+0.7b4
+-----
+
+* Issue #3: Fixed NameError in SSL support.
+
+0.6.49
+------
+
+* Move warning check in ``get_cache_path`` to follow the directory creation
+  to avoid errors when the cache path does not yet exist. Fixes the error
+  reported in Distribute #375.
+
+0.6.48
+------
+
+* Correct AttributeError in ``ResourceManager.get_cache_path`` introduced in
+  0.6.46 (redo).
+
+0.6.47
+------
+
+* Correct AttributeError in ``ResourceManager.get_cache_path`` introduced in
+  0.6.46.
+
+0.6.46
+------
+
+* Distribute #375: Issue a warning if the PYTHON_EGG_CACHE or otherwise
+  customized egg cache location specifies a directory that's group- or
+  world-writable.
+
+0.6.45
+------
+
+* Distribute #379: ``distribute_setup.py`` now traps VersionConflict as well,
+  restoring ability to upgrade from an older setuptools version.
+
+0.6.44
+------
+
+* ``distribute_setup.py`` has been updated to allow Setuptools 0.7 to
+  satisfy use_setuptools.
+
+0.6.43
+------
+
+* Distribute #378: Restore support for Python 2.4 Syntax (regression in 0.6.42).
+
+0.6.42
+------
+
+* External links finder no longer yields duplicate links.
+* Distribute #337: Moved site.py to setuptools/site-patch.py (graft of very old
+  patch from setuptools trunk which inspired PR #31).
+
+0.6.41
+------
+
+* Distribute #27: Use public api for loading resources from zip files rather than
+  the private method `_zip_directory_cache`.
+* Added a new function ``easy_install.get_win_launcher`` which may be used by
+  third-party libraries such as buildout to get a suitable script launcher.
+
+0.6.40
+------
+
+* Distribute #376: brought back cli.exe and gui.exe that were deleted in the
+  previous release.
+
+0.6.39
+------
+
+* Add support for console launchers on ARM platforms.
+* Fix possible issue in GUI launchers where the subsystem was not supplied to
+  the linker.
+* Launcher build script now refactored for robustness.
+* Distribute #375: Resources extracted from a zip egg to the file system now also
+  check the contents of the file against the zip contents during each
+  invocation of get_resource_filename.
+
+0.6.38
+------
+
+* Distribute #371: The launcher manifest file is now installed properly.
+
+0.6.37
+------
+
+* Distribute #143: Launcher scripts, including easy_install itself, are now
+  accompanied by a manifest on 32-bit Windows environments to avoid the
+  Installer Detection Technology and thus undesirable UAC elevation described
+  in `this Microsoft article
+  <http://technet.microsoft.com/en-us/library/cc709628%28WS.10%29.aspx>`_.
+
+0.6.36
+------
+
+* BB Pull Request #35: In Buildout #64, it was reported that
+  under Python 3, installation of distutils scripts could attempt to copy
+  the ``__pycache__`` directory as a file, causing an error, apparently only
+  under Windows. Easy_install now skips all directories when processing
+  metadata scripts.
+
+0.6.35
+------
+
+
+Note this release is backward-incompatible with distribute 0.6.23-0.6.34 in
+how it parses version numbers.
+
+* Distribute #278: Restored compatibility with distribute 0.6.22 and setuptools
+  0.6. Updated the documentation to match more closely with the version
+  parsing as intended in setuptools 0.6.
+
+0.6.34
+------
+
+* Distribute #341: 0.6.33 fails to build under Python 2.4.
+
+0.6.33
+------
+
+* Fix 2 errors with Jython 2.5.
+* Fix 1 failure with Jython 2.5 and 2.7.
+* Disable workaround for Jython scripts on Linux systems.
+* Distribute #336: `setup.py` no longer masks failure exit code when tests fail.
+* Fix issue in pkg_resources where try/except around a platform-dependent
+  import would trigger hook load failures on Mercurial. See pull request 32
+  for details.
+* Distribute #341: Fix a ResourceWarning.
+
+0.6.32
+------
+
+* Fix test suite with Python 2.6.
+* Fix some DeprecationWarnings and ResourceWarnings.
+* Distribute #335: Backed out `setup_requires` superceding installed requirements
+  until regression can be addressed.
+
+0.6.31
+------
+
+* Distribute #303: Make sure the manifest only ever contains UTF-8 in Python 3.
+* Distribute #329: Properly close files created by tests for compatibility with
+  Jython.
+* Work around Jython #1980 and Jython #1981.
+* Distribute #334: Provide workaround for packages that reference `sys.__stdout__`
+  such as numpy does. This change should address
+  `virtualenv #359 <https://github.com/pypa/virtualenv/issues/359>`_ as long
+  as the system encoding is UTF-8 or the IO encoding is specified in the
+  environment, i.e.::
+
+     PYTHONIOENCODING=utf8 pip install numpy
+
+* Fix for encoding issue when installing from Windows executable on Python 3.
+* Distribute #323: Allow `setup_requires` requirements to supercede installed
+  requirements. Added some new keyword arguments to existing pkg_resources
+  methods. Also had to updated how __path__ is handled for namespace packages
+  to ensure that when a new egg distribution containing a namespace package is
+  placed on sys.path, the entries in __path__ are found in the same order they
+  would have been in had that egg been on the path when pkg_resources was
+  first imported.
+
+0.6.30
+------
+
+* Distribute #328: Clean up temporary directories in distribute_setup.py.
+* Fix fatal bug in distribute_setup.py.
+
+0.6.29
+------
+
+* BB Pull Request #14: Honor file permissions in zip files.
+* Distribute #327: Merged pull request #24 to fix a dependency problem with pip.
+* Merged pull request #23 to fix https://github.com/pypa/virtualenv/issues/301.
+* If Sphinx is installed, the `upload_docs` command now runs `build_sphinx`
+  to produce uploadable documentation.
+* Distribute #326: `upload_docs` provided mangled auth credentials under Python 3.
+* Distribute #320: Fix check for "createable" in distribute_setup.py.
+* Distribute #305: Remove a warning that was triggered during normal operations.
+* Distribute #311: Print metadata in UTF-8 independent of platform.
+* Distribute #303: Read manifest file with UTF-8 encoding under Python 3.
+* Distribute #301: Allow to run tests of namespace packages when using 2to3.
+* Distribute #304: Prevent import loop in site.py under Python 3.3.
+* Distribute #283: Reenable scanning of `*.pyc` / `*.pyo` files on Python 3.3.
+* Distribute #299: The develop command didn't work on Python 3, when using 2to3,
+  as the egg link would go to the Python 2 source. Linking to the 2to3'd code
+  in build/lib makes it work, although you will have to rebuild the module
+  before testing it.
+* Distribute #306: Even if 2to3 is used, we build in-place under Python 2.
+* Distribute #307: Prints the full path when .svn/entries is broken.
+* Distribute #313: Support for sdist subcommands (Python 2.7)
+* Distribute #314: test_local_index() would fail an OS X.
+* Distribute #310: Non-ascii characters in a namespace __init__.py causes errors.
+* Distribute #218: Improved documentation on behavior of `package_data` and
+  `include_package_data`. Files indicated by `package_data` are now included
+  in the manifest.
+* `distribute_setup.py` now allows a `--download-base` argument for retrieving
+  distribute from a specified location.
+
+0.6.28
+------
+
+* Distribute #294: setup.py can now be invoked from any directory.
+* Scripts are now installed honoring the umask.
+* Added support for .dist-info directories.
+* Distribute #283: Fix and disable scanning of `*.pyc` / `*.pyo` files on
+  Python 3.3.
+
+0.6.27
+------
+
+* Support current snapshots of CPython 3.3.
+* Distribute now recognizes README.rst as a standard, default readme file.
+* Exclude 'encodings' modules when removing modules from sys.modules.
+  Workaround for #285.
+* Distribute #231: Don't fiddle with system python when used with buildout
+  (bootstrap.py)
+
+0.6.26
+------
+
+* Distribute #183: Symlinked files are now extracted from source distributions.
+* Distribute #227: Easy_install fetch parameters are now passed during the
+  installation of a source distribution; now fulfillment of setup_requires
+  dependencies will honor the parameters passed to easy_install.
+
+0.6.25
+------
+
+* Distribute #258: Workaround a cache issue
+* Distribute #260: distribute_setup.py now accepts the --user parameter for
+  Python 2.6 and later.
+* Distribute #262: package_index.open_with_auth no longer throws LookupError
+  on Python 3.
+* Distribute #269: AttributeError when an exception occurs reading Manifest.in
+  on late releases of Python.
+* Distribute #272: Prevent TypeError when namespace package names are unicode
+  and single-install-externally-managed is used. Also fixes PIP issue
+  449.
+* Distribute #273: Legacy script launchers now install with Python2/3 support.
+
+0.6.24
+------
+
+* Distribute #249: Added options to exclude 2to3 fixers
+
+0.6.23
+------
+
+* Distribute #244: Fixed a test
+* Distribute #243: Fixed a test
+* Distribute #239: Fixed a test
+* Distribute #240: Fixed a test
+* Distribute #241: Fixed a test
+* Distribute #237: Fixed a test
+* Distribute #238: easy_install now uses 64bit executable wrappers on 64bit Python
+* Distribute #208: Fixed parsed_versions, it now honors post-releases as noted in the documentation
+* Distribute #207: Windows cli and gui wrappers pass CTRL-C to child python process
+* Distribute #227: easy_install now passes its arguments to setup.py bdist_egg
+* Distribute #225: Fixed a NameError on Python 2.5, 2.4
+
+0.6.21
+------
+
+* Distribute #225: FIxed a regression on py2.4
+
+0.6.20
+------
+
+* Distribute #135: Include url in warning when processing URLs in package_index.
+* Distribute #212: Fix issue where easy_instal fails on Python 3 on windows installer.
+* Distribute #213: Fix typo in documentation.
+
+0.6.19
+------
+
+* Distribute #206: AttributeError: 'HTTPMessage' object has no attribute 'getheaders'
+
+0.6.18
+------
+
+* Distribute #210: Fixed a regression introduced by Distribute #204 fix.
+
+0.6.17
+------
+
+* Support 'DISTRIBUTE_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT' environment
+  variable to allow to disable installation of easy_install-${version} script.
+* Support Python >=3.1.4 and >=3.2.1.
+* Distribute #204: Don't try to import the parent of a namespace package in
+  declare_namespace
+* Distribute #196: Tolerate responses with multiple Content-Length headers
+* Distribute #205: Sandboxing doesn't preserve working_set. Leads to setup_requires
+  problems.
+
+0.6.16
+------
+
+* Builds sdist gztar even on Windows (avoiding Distribute #193).
+* Distribute #192: Fixed metadata omitted on Windows when package_dir
+  specified with forward-slash.
+* Distribute #195: Cython build support.
+* Distribute #200: Issues with recognizing 64-bit packages on Windows.
+
+0.6.15
+------
+
+* Fixed typo in bdist_egg
+* Several issues under Python 3 has been solved.
+* Distribute #146: Fixed missing DLL files after easy_install of windows exe package.
+
+0.6.14
+------
+
+* Distribute #170: Fixed unittest failure. Thanks to Toshio.
+* Distribute #171: Fixed race condition in unittests cause deadlocks in test suite.
+* Distribute #143: Fixed a lookup issue with easy_install.
+  Thanks to David and Zooko.
+* Distribute #174: Fixed the edit mode when its used with setuptools itself
+
+0.6.13
+------
+
+* Distribute #160: 2.7 gives ValueError("Invalid IPv6 URL")
+* Distribute #150: Fixed using ~/.local even in a --no-site-packages virtualenv
+* Distribute #163: scan index links before external links, and don't use the md5 when
+  comparing two distributions
+
+0.6.12
+------
+
+* Distribute #149: Fixed various failures on 2.3/2.4
+
+0.6.11
+------
+
+* Found another case of SandboxViolation - fixed
+* Distribute #15 and Distribute #48: Introduced a socket timeout of 15 seconds on url openings
+* Added indexsidebar.html into MANIFEST.in
+* Distribute #108: Fixed TypeError with Python3.1
+* Distribute #121: Fixed --help install command trying to actually install.
+* Distribute #112: Added an os.makedirs so that Tarek's solution will work.
+* Distribute #133: Added --no-find-links to easy_install
+* Added easy_install --user
+* Distribute #100: Fixed develop --user not taking '.' in PYTHONPATH into account
+* Distribute #134: removed spurious UserWarnings. Patch by VanLindberg
+* Distribute #138: cant_write_to_target error when setup_requires is used.
+* Distribute #147: respect the sys.dont_write_bytecode flag
+
+0.6.10
+------
+
+* Reverted change made for the DistributionNotFound exception because
+  zc.buildout uses the exception message to get the name of the
+  distribution.
+
+0.6.9
+-----
+
+* Distribute #90: unknown setuptools version can be added in the working set
+* Distribute #87: setupt.py doesn't try to convert distribute_setup.py anymore
+  Initial Patch by arfrever.
+* Distribute #89: added a side bar with a download link to the doc.
+* Distribute #86: fixed missing sentence in pkg_resources doc.
+* Added a nicer error message when a DistributionNotFound is raised.
+* Distribute #80: test_develop now works with Python 3.1
+* Distribute #93: upload_docs now works if there is an empty sub-directory.
+* Distribute #70: exec bit on non-exec files
+* Distribute #99: now the standalone easy_install command doesn't uses a
+  "setup.cfg" if any exists in the working directory. It will use it
+  only if triggered by ``install_requires`` from a setup.py call
+  (install, develop, etc).
+* Distribute #101: Allowing ``os.devnull`` in Sandbox
+* Distribute #92: Fixed the "no eggs" found error with MacPort
+  (platform.mac_ver() fails)
+* Distribute #103: test_get_script_header_jython_workaround not run
+  anymore under py3 with C or POSIX local. Contributed by Arfrever.
+* Distribute #104: remvoved the assertion when the installation fails,
+  with a nicer message for the end user.
+* Distribute #100: making sure there's no SandboxViolation when
+  the setup script patches setuptools.
+
+0.6.8
+-----
+
+* Added "check_packages" in dist. (added in Setuptools 0.6c11)
+* Fixed the DONT_PATCH_SETUPTOOLS state.
+
+0.6.7
+-----
+
+* Distribute #58: Added --user support to the develop command
+* Distribute #11: Generated scripts now wrap their call to the script entry point
+  in the standard "if name == 'main'"
+* Added the 'DONT_PATCH_SETUPTOOLS' environment variable, so virtualenv
+  can drive an installation that doesn't patch a global setuptools.
+* Reviewed unladen-swallow specific change from
+  http://code.google.com/p/unladen-swallow/source/detail?spec=svn875&r=719
+  and determined that it no longer applies. Distribute should work fine with
+  Unladen Swallow 2009Q3.
+* Distribute #21: Allow PackageIndex.open_url to gracefully handle all cases of a
+  httplib.HTTPException instead of just InvalidURL and BadStatusLine.
+* Removed virtual-python.py from this distribution and updated documentation
+  to point to the actively maintained virtualenv instead.
+* Distribute #64: use_setuptools no longer rebuilds the distribute egg every
+  time it is run
+* use_setuptools now properly respects the requested version
+* use_setuptools will no longer try to import a distribute egg for the
+  wrong Python version
+* Distribute #74: no_fake should be True by default.
+* Distribute #72: avoid a bootstrapping issue with easy_install -U
+
+0.6.6
+-----
+
+* Unified the bootstrap file so it works on both py2.x and py3k without 2to3
+  (patch by Holger Krekel)
+
+0.6.5
+-----
+
+* Distribute #65: cli.exe and gui.exe are now generated at build time,
+  depending on the platform in use.
+
+* Distribute #67: Fixed doc typo (PEP 381/PEP 382).
+
+* Distribute no longer shadows setuptools if we require a 0.7-series
+  setuptools. And an error is raised when installing a 0.7 setuptools with
+  distribute.
+
+* When run from within buildout, no attempt is made to modify an existing
+  setuptools egg, whether in a shared egg directory or a system setuptools.
+
+* Fixed a hole in sandboxing allowing builtin file to write outside of
+  the sandbox.
+
+0.6.4
+-----
+
+* Added the generation of `distribute_setup_3k.py` during the release.
+  This closes Distribute #52.
+
+* Added an upload_docs command to easily upload project documentation to
+  PyPI's https://pythonhosted.org. This close issue Distribute #56.
+
+* Fixed a bootstrap bug on the use_setuptools() API.
+
+0.6.3
+-----
+
+setuptools
+==========
+
+* Fixed a bunch of calls to file() that caused crashes on Python 3.
+
+bootstrapping
+=============
+
+* Fixed a bug in sorting that caused bootstrap to fail on Python 3.
+
+0.6.2
+-----
+
+setuptools
+==========
+
+* Added Python 3 support; see docs/python3.txt.
+  This closes Old Setuptools #39.
+
+* Added option to run 2to3 automatically when installing on Python 3.
+  This closes issue Distribute #31.
+
+* Fixed invalid usage of requirement.parse, that broke develop -d.
+  This closes Old Setuptools #44.
+
+* Fixed script launcher for 64-bit Windows.
+  This closes Old Setuptools #2.
+
+* KeyError when compiling extensions.
+  This closes Old Setuptools #41.
+
+bootstrapping
+=============
+
+* Fixed bootstrap not working on Windows. This closes issue Distribute #49.
+
+* Fixed 2.6 dependencies. This closes issue Distribute #50.
+
+* Make sure setuptools is patched when running through easy_install
+  This closes Old Setuptools #40.
+
+0.6.1
+-----
+
+setuptools
+==========
+
+* package_index.urlopen now catches BadStatusLine and malformed url errors.
+  This closes Distribute #16 and Distribute #18.
+
+* zip_ok is now False by default. This closes Old Setuptools #33.
+
+* Fixed invalid URL error catching. Old Setuptools #20.
+
+* Fixed invalid bootstraping with easy_install installation (Distribute #40).
+  Thanks to Florian Schulze for the help.
+
+* Removed buildout/bootstrap.py. A new repository will create a specific
+  bootstrap.py script.
+
+
+bootstrapping
+=============
+
+* The boostrap process leave setuptools alone if detected in the system
+  and --root or --prefix is provided, but is not in the same location.
+  This closes Distribute #10.
+
+0.6
+---
+
+setuptools
+==========
+
+* Packages required at build time where not fully present at install time.
+  This closes Distribute #12.
+
+* Protected against failures in tarfile extraction. This closes Distribute #10.
+
+* Made Jython api_tests.txt doctest compatible. This closes Distribute #7.
+
+* sandbox.py replaced builtin type file with builtin function open. This
+  closes Distribute #6.
+
+* Immediately close all file handles. This closes Distribute #3.
+
+* Added compatibility with Subversion 1.6. This references Distribute #1.
+
+pkg_resources
+=============
+
+* Avoid a call to /usr/bin/sw_vers on OSX and use the official platform API
+  instead. Based on a patch from ronaldoussoren. This closes issue #5.
+
+* Fixed a SandboxViolation for mkdir that could occur in certain cases.
+  This closes Distribute #13.
+
+* Allow to find_on_path on systems with tight permissions to fail gracefully.
+  This closes Distribute #9.
+
+* Corrected inconsistency between documentation and code of add_entry.
+  This closes Distribute #8.
+
+* Immediately close all file handles. This closes Distribute #3.
+
+easy_install
+============
+
+* Immediately close all file handles. This closes Distribute #3.
+
+0.6c9
+-----
+
+ * Fixed a missing files problem when using Windows source distributions on
+   non-Windows platforms, due to distutils not handling manifest file line
+   endings correctly.
+
+ * Updated Pyrex support to work with Pyrex 0.9.6 and higher.
+
+ * Minor changes for Jython compatibility, including skipping tests that can't
+   work on Jython.
+
+ * Fixed not installing eggs in ``install_requires`` if they were also used for
+   ``setup_requires`` or ``tests_require``.
+
+ * Fixed not fetching eggs in ``install_requires`` when running tests.
+
+ * Allow ``ez_setup.use_setuptools()`` to upgrade existing setuptools
+   installations when called from a standalone ``setup.py``.
+
+ * Added a warning if a namespace package is declared, but its parent package
+   is not also declared as a namespace.
+
+ * Support Subversion 1.5
+
+ * Removed use of deprecated ``md5`` module if ``hashlib`` is available
+
+ * Fixed ``bdist_wininst upload`` trying to upload the ``.exe`` twice
+
+ * Fixed ``bdist_egg`` putting a ``native_libs.txt`` in the source package's
+   ``.egg-info``, when it should only be in the built egg's ``EGG-INFO``.
+
+ * Ensure that _full_name is set on all shared libs before extensions are
+   checked for shared lib usage.  (Fixes a bug in the experimental shared
+   library build support.)
+
+ * Fix to allow unpacked eggs containing native libraries to fail more
+   gracefully under Google App Engine (with an ``ImportError`` loading the
+   C-based module, instead of getting a ``NameError``).
+
+0.6c7
+-----
+
+ * Fixed ``distutils.filelist.findall()`` crashing on broken symlinks, and
+   ``egg_info`` command failing on new, uncommitted SVN directories.
+
+ * Fix import problems with nested namespace packages installed via
+   ``--root`` or ``--single-version-externally-managed``, due to the
+   parent package not having the child package as an attribute.
+
+0.6c6
+-----
+
+ * Added ``--egg-path`` option to ``develop`` command, allowing you to force
+   ``.egg-link`` files to use relative paths (allowing them to be shared across
+   platforms on a networked drive).
+
+ * Fix not building binary RPMs correctly.
+
+ * Fix "eggsecutables" (such as setuptools' own egg) only being runnable with
+   bash-compatible shells.
+
+ * Fix ``#!`` parsing problems in Windows ``.exe`` script wrappers, when there
+   was whitespace inside a quoted argument or at the end of the ``#!`` line
+   (a regression introduced in 0.6c4).
+
+ * Fix ``test`` command possibly failing if an older version of the project
+   being tested was installed on ``sys.path`` ahead of the test source
+   directory.
+
+ * Fix ``find_packages()`` treating ``ez_setup`` and directories with ``.`` in
+   their names as packages.
+
+0.6c5
+-----
+
+ * Fix uploaded ``bdist_rpm`` packages being described as ``bdist_egg``
+   packages under Python versions less than 2.5.
+
+ * Fix uploaded ``bdist_wininst`` packages being described as suitable for
+   "any" version by Python 2.5, even if a ``--target-version`` was specified.
+
+0.6c4
+-----
+
+ * Overhauled Windows script wrapping to support ``bdist_wininst`` better.
+   Scripts installed with ``bdist_wininst`` will always use ``#!python.exe`` or
+   ``#!pythonw.exe`` as the executable name (even when built on non-Windows
+   platforms!), and the wrappers will look for the executable in the script's
+   parent directory (which should find the right version of Python).
+
+ * Fix ``upload`` command not uploading files built by ``bdist_rpm`` or
+   ``bdist_wininst`` under Python 2.3 and 2.4.
+
+ * Add support for "eggsecutable" headers: a ``#!/bin/sh`` script that is
+   prepended to an ``.egg`` file to allow it to be run as a script on Unix-ish
+   platforms.  (This is mainly so that setuptools itself can have a single-file
+   installer on Unix, without doing multiple downloads, dealing with firewalls,
+   etc.)
+
+ * Fix problem with empty revision numbers in Subversion 1.4 ``entries`` files
+
+ * Use cross-platform relative paths in ``easy-install.pth`` when doing
+   ``develop`` and the source directory is a subdirectory of the installation
+   target directory.
+
+ * Fix a problem installing eggs with a system packaging tool if the project
+   contained an implicit namespace package; for example if the ``setup()``
+   listed a namespace package ``foo.bar`` without explicitly listing ``foo``
+   as a namespace package.
+
+0.6c3
+-----
+
+ * Fixed breakages caused by Subversion 1.4's new "working copy" format
+
+0.6c2
+-----
+
+ * The ``ez_setup`` module displays the conflicting version of setuptools (and
+   its installation location) when a script requests a version that's not
+   available.
+
+ * Running ``setup.py develop`` on a setuptools-using project will now install
+   setuptools if needed, instead of only downloading the egg.
+
+0.6c1
+-----
+
+ * Fixed ``AttributeError`` when trying to download a ``setup_requires``
+   dependency when a distribution lacks a ``dependency_links`` setting.
+
+ * Made ``zip-safe`` and ``not-zip-safe`` flag files contain a single byte, so
+   as to play better with packaging tools that complain about zero-length
+   files.
+
+ * Made ``setup.py develop`` respect the ``--no-deps`` option, which it
+   previously was ignoring.
+
+ * Support ``extra_path`` option to ``setup()`` when ``install`` is run in
+   backward-compatibility mode.
+
+ * Source distributions now always include a ``setup.cfg`` file that explicitly
+   sets ``egg_info`` options such that they produce an identical version number
+   to the source distribution's version number.  (Previously, the default
+   version number could be different due to the use of ``--tag-date``, or if
+   the version was overridden on the command line that built the source
+   distribution.)
+
+0.6b4
+-----
+
+ * Fix ``register`` not obeying name/version set by ``egg_info`` command, if
+   ``egg_info`` wasn't explicitly run first on the same command line.
+
+ * Added ``--no-date`` and ``--no-svn-revision`` options to ``egg_info``
+   command, to allow suppressing tags configured in ``setup.cfg``.
+
+ * Fixed redundant warnings about missing ``README`` file(s); it should now
+   appear only if you are actually a source distribution.
+
+0.6b3
+-----
+
+ * Fix ``bdist_egg`` not including files in subdirectories of ``.egg-info``.
+
+ * Allow ``.py`` files found by the ``include_package_data`` option to be
+   automatically included. Remove duplicate data file matches if both
+   ``include_package_data`` and ``package_data`` are used to refer to the same
+   files.
+
+0.6b1
+-----
+
+ * Strip ``module`` from the end of compiled extension modules when computing
+   the name of a ``.py`` loader/wrapper.  (Python's import machinery ignores
+   this suffix when searching for an extension module.)
+
+0.6a11
+------
+
+ * Added ``test_loader`` keyword to support custom test loaders
+
+ * Added ``setuptools.file_finders`` entry point group to allow implementing
+   revision control plugins.
+
+ * Added ``--identity`` option to ``upload`` command.
+
+ * Added ``dependency_links`` to allow specifying URLs for ``--find-links``.
+
+ * Enhanced test loader to scan packages as well as modules, and call
+   ``additional_tests()`` if present to get non-unittest tests.
+
+ * Support namespace packages in conjunction with system packagers, by omitting
+   the installation of any ``__init__.py`` files for namespace packages, and
+   adding a special ``.pth`` file to create a working package in
+   ``sys.modules``.
+
+ * Made ``--single-version-externally-managed`` automatic when ``--root`` is
+   used, so that most system packagers won't require special support for
+   setuptools.
+
+ * Fixed ``setup_requires``, ``tests_require``, etc. not using ``setup.cfg`` or
+   other configuration files for their option defaults when installing, and
+   also made the install use ``--multi-version`` mode so that the project
+   directory doesn't need to support .pth files.
+
+ * ``MANIFEST.in`` is now forcibly closed when any errors occur while reading
+   it. Previously, the file could be left open and the actual error would be
+   masked by problems trying to remove the open file on Windows systems.
+
+0.6a10
+------
+
+ * Fixed the ``develop`` command ignoring ``--find-links``.
+
+0.6a9
+-----
+
+ * The ``sdist`` command no longer uses the traditional ``MANIFEST`` file to
+   create source distributions.  ``MANIFEST.in`` is still read and processed,
+   as are the standard defaults and pruning. But the manifest is built inside
+   the project's ``.egg-info`` directory as ``SOURCES.txt``, and it is rebuilt
+   every time the ``egg_info`` command is run.
+
+ * Added the ``include_package_data`` keyword to ``setup()``, allowing you to
+   automatically include any package data listed in revision control or
+   ``MANIFEST.in``
+
+ * Added the ``exclude_package_data`` keyword to ``setup()``, allowing you to
+   trim back files included via the ``package_data`` and
+   ``include_package_data`` options.
+
+ * Fixed ``--tag-svn-revision`` not working when run from a source
+   distribution.
+
+ * Added warning for namespace packages with missing ``declare_namespace()``
+
+ * Added ``tests_require`` keyword to ``setup()``, so that e.g. packages
+   requiring ``nose`` to run unit tests can make this dependency optional
+   unless the ``test`` command is run.
+
+ * Made all commands that use ``easy_install`` respect its configuration
+   options, as this was causing some problems with ``setup.py install``.
+
+ * Added an ``unpack_directory()`` driver to ``setuptools.archive_util``, so
+   that you can process a directory tree through a processing filter as if it
+   were a zipfile or tarfile.
+
+ * Added an internal ``install_egg_info`` command to use as part of old-style
+   ``install`` operations, that installs an ``.egg-info`` directory with the
+   package.
+
+ * Added a ``--single-version-externally-managed`` option to the ``install``
+   command so that you can more easily wrap a "flat" egg in a system package.
+
+ * Enhanced ``bdist_rpm`` so that it installs single-version eggs that
+   don't rely on a ``.pth`` file. The ``--no-egg`` option has been removed,
+   since all RPMs are now built in a more backwards-compatible format.
+
+ * Support full roundtrip translation of eggs to and from ``bdist_wininst``
+   format. Running ``bdist_wininst`` on a setuptools-based package wraps the
+   egg in an .exe that will safely install it as an egg (i.e., with metadata
+   and entry-point wrapper scripts), and ``easy_install`` can turn the .exe
+   back into an ``.egg`` file or directory and install it as such.
+
+
+0.6a8
+-----
+
+ * Fixed some problems building extensions when Pyrex was installed, especially
+   with Python 2.4 and/or packages using SWIG.
+
+ * Made ``develop`` command accept all the same options as ``easy_install``,
+   and use the ``easy_install`` command's configuration settings as defaults.
+
+ * Made ``egg_info --tag-svn-revision`` fall back to extracting the revision
+   number from ``PKG-INFO`` in case it is being run on a source distribution of
+   a snapshot taken from a Subversion-based project.
+
+ * Automatically detect ``.dll``, ``.so`` and ``.dylib`` files that are being
+   installed as data, adding them to ``native_libs.txt`` automatically.
+
+ * Fixed some problems with fresh checkouts of projects that don't include
+   ``.egg-info/PKG-INFO`` under revision control and put the project's source
+   code directly in the project directory. If such a package had any
+   requirements that get processed before the ``egg_info`` command can be run,
+   the setup scripts would fail with a "Missing 'Version:' header and/or
+   PKG-INFO file" error, because the egg runtime interpreted the unbuilt
+   metadata in a directory on ``sys.path`` (i.e. the current directory) as
+   being a corrupted egg. Setuptools now monkeypatches the distribution
+   metadata cache to pretend that the egg has valid version information, until
+   it has a chance to make it actually be so (via the ``egg_info`` command).
+
+0.6a5
+-----
+
+ * Fixed missing gui/cli .exe files in distribution. Fixed bugs in tests.
+
+0.6a3
+-----
+
+ * Added ``gui_scripts`` entry point group to allow installing GUI scripts
+   on Windows and other platforms.  (The special handling is only for Windows;
+   other platforms are treated the same as for ``console_scripts``.)
+
+0.6a2
+-----
+
+ * Added ``console_scripts`` entry point group to allow installing scripts
+   without the need to create separate script files. On Windows, console
+   scripts get an ``.exe`` wrapper so you can just type their name. On other
+   platforms, the scripts are written without a file extension.
+
+0.6a1
+-----
+
+ * Added support for building "old-style" RPMs that don't install an egg for
+   the target package, using a ``--no-egg`` option.
+
+ * The ``build_ext`` command now works better when using the ``--inplace``
+   option and multiple Python versions. It now makes sure that all extensions
+   match the current Python version, even if newer copies were built for a
+   different Python version.
+
+ * The ``upload`` command no longer attaches an extra ``.zip`` when uploading
+   eggs, as PyPI now supports egg uploads without trickery.
+
+ * The ``ez_setup`` script/module now displays a warning before downloading
+   the setuptools egg, and attempts to check the downloaded egg against an
+   internal MD5 checksum table.
+
+ * Fixed the ``--tag-svn-revision`` option of ``egg_info`` not finding the
+   latest revision number; it was using the revision number of the directory
+   containing ``setup.py``, not the highest revision number in the project.
+
+ * Added ``eager_resources`` setup argument
+
+ * The ``sdist`` command now recognizes Subversion "deleted file" entries and
+   does not include them in source distributions.
+
+ * ``setuptools`` now embeds itself more thoroughly into the distutils, so that
+   other distutils extensions (e.g. py2exe, py2app) will subclass setuptools'
+   versions of things, rather than the native distutils ones.
+
+ * Added ``entry_points`` and ``setup_requires`` arguments to ``setup()``;
+   ``setup_requires`` allows you to automatically find and download packages
+   that are needed in order to *build* your project (as opposed to running it).
+
+ * ``setuptools`` now finds its commands, ``setup()`` argument validators, and
+   metadata writers using entry points, so that they can be extended by
+   third-party packages. See `Creating distutils Extensions
+   <https://setuptools.readthedocs.io/en/latest/setuptools.html#creating-distutils-extensions>`_
+   for more details.
+
+ * The vestigial ``depends`` command has been removed. It was never finished
+   or documented, and never would have worked without EasyInstall - which it
+   pre-dated and was never compatible with.
+
+0.5a12
+------
+
+ * The zip-safety scanner now checks for modules that might be used with
+   ``python -m``, and marks them as unsafe for zipping, since Python 2.4 can't
+   handle ``-m`` on zipped modules.
+
+0.5a11
+------
+
+ * Fix breakage of the "develop" command that was caused by the addition of
+   ``--always-unzip`` to the ``easy_install`` command.
+
+0.5a9
+-----
+
+ * Include ``svn:externals`` directories in source distributions as well as
+   normal subversion-controlled files and directories.
+
+ * Added ``exclude=patternlist`` option to ``setuptools.find_packages()``
+
+ * Changed --tag-svn-revision to include an "r" in front of the revision number
+   for better readability.
+
+ * Added ability to build eggs without including source files (except for any
+   scripts, of course), using the ``--exclude-source-files`` option to
+   ``bdist_egg``.
+
+ * ``setup.py install`` now automatically detects when an "unmanaged" package
+   or module is going to be on ``sys.path`` ahead of a package being installed,
+   thereby preventing the newer version from being imported. If this occurs,
+   a warning message is output to ``sys.stderr``, but installation proceeds
+   anyway. The warning message informs the user what files or directories
+   need deleting, and advises them they can also use EasyInstall (with the
+   ``--delete-conflicting`` option) to do it automatically.
+
+ * The ``egg_info`` command now adds a ``top_level.txt`` file to the metadata
+   directory that lists all top-level modules and packages in the distribution.
+   This is used by the ``easy_install`` command to find possibly-conflicting
+   "unmanaged" packages when installing the distribution.
+
+ * Added ``zip_safe`` and ``namespace_packages`` arguments to ``setup()``.
+   Added package analysis to determine zip-safety if the ``zip_safe`` flag
+   is not given, and advise the author regarding what code might need changing.
+
+ * Fixed the swapped ``-d`` and ``-b`` options of ``bdist_egg``.
+
+0.5a8
+-----
+
+ * The "egg_info" command now always sets the distribution metadata to "safe"
+   forms of the distribution name and version, so that distribution files will
+   be generated with parseable names (i.e., ones that don't include '-' in the
+   name or version). Also, this means that if you use the various ``--tag``
+   options of "egg_info", any distributions generated will use the tags in the
+   version, not just egg distributions.
+
+ * Added support for defining command aliases in distutils configuration files,
+   under the "[aliases]" section. To prevent recursion and to allow aliases to
+   call the command of the same name, a given alias can be expanded only once
+   per command-line invocation. You can define new aliases with the "alias"
+   command, either for the local, global, or per-user configuration.
+
+ * Added "rotate" command to delete old distribution files, given a set of
+   patterns to match and the number of files to keep.  (Keeps the most
+   recently-modified distribution files matching each pattern.)
+
+ * Added "saveopts" command that saves all command-line options for the current
+   invocation to the local, global, or per-user configuration file. Useful for
+   setting defaults without having to hand-edit a configuration file.
+
+ * Added a "setopt" command that sets a single option in a specified distutils
+   configuration file.
+
+0.5a7
+-----
+
+ * Added "upload" support for egg and source distributions, including a bug
+   fix for "upload" and a temporary workaround for lack of .egg support in
+   PyPI.
+
+0.5a6
+-----
+
+ * Beefed up the "sdist" command so that if you don't have a MANIFEST.in, it
+   will include all files under revision control (CVS or Subversion) in the
+   current directory, and it will regenerate the list every time you create a
+   source distribution, not just when you tell it to. This should make the
+   default "do what you mean" more often than the distutils' default behavior
+   did, while still retaining the old behavior in the presence of MANIFEST.in.
+
+ * Fixed the "develop" command always updating .pth files, even if you
+   specified ``-n`` or ``--dry-run``.
+
+ * Slightly changed the format of the generated version when you use
+   ``--tag-build`` on the "egg_info" command, so that you can make tagged
+   revisions compare *lower* than the version specified in setup.py (e.g. by
+   using ``--tag-build=dev``).
+
+0.5a5
+-----
+
+ * Added ``develop`` command to ``setuptools``-based packages. This command
+   installs an ``.egg-link`` pointing to the package's source directory, and
+   script wrappers that ``execfile()`` the source versions of the package's
+   scripts. This lets you put your development checkout(s) on sys.path without
+   having to actually install them.  (To uninstall the link, use
+   use ``setup.py develop --uninstall``.)
+
+ * Added ``egg_info`` command to ``setuptools``-based packages. This command
+   just creates or updates the "projectname.egg-info" directory, without
+   building an egg.  (It's used by the ``bdist_egg``, ``test``, and ``develop``
+   commands.)
+
+ * Enhanced the ``test`` command so that it doesn't install the package, but
+   instead builds any C extensions in-place, updates the ``.egg-info``
+   metadata, adds the source directory to ``sys.path``, and runs the tests
+   directly on the source. This avoids an "unmanaged" installation of the
+   package to ``site-packages`` or elsewhere.
+
+ * Made ``easy_install`` a standard ``setuptools`` command, moving it from
+   the ``easy_install`` module to ``setuptools.command.easy_install``. Note
+   that if you were importing or extending it, you must now change your imports
+   accordingly.  ``easy_install.py`` is still installed as a script, but not as
+   a module.
+
+0.5a4
+-----
+
+ * Setup scripts using setuptools can now list their dependencies directly in
+   the setup.py file, without having to manually create a ``depends.txt`` file.
+   The ``install_requires`` and ``extras_require`` arguments to ``setup()``
+   are used to create a dependencies file automatically. If you are manually
+   creating ``depends.txt`` right now, please switch to using these setup
+   arguments as soon as practical, because ``depends.txt`` support will be
+   removed in the 0.6 release cycle. For documentation on the new arguments,
+   see the ``setuptools.dist.Distribution`` class.
+
+ * Setup scripts using setuptools now always install using ``easy_install``
+   internally, for ease of uninstallation and upgrading.
+
+0.5a1
+-----
+
+ * Added support for "self-installation" bootstrapping. Packages can now
+   include ``ez_setup.py`` in their source distribution, and add the following
+   to their ``setup.py``, in order to automatically bootstrap installation of
+   setuptools as part of their setup process::
+
+    from ez_setup import use_setuptools
+    use_setuptools()
+
+    from setuptools import setup
+    # etc...
+
+0.4a2
+-----
+
+ * Added ``ez_setup.py`` installer/bootstrap script to make initial setuptools
+   installation easier, and to allow distributions using setuptools to avoid
+   having to include setuptools in their source distribution.
+
+ * All downloads are now managed by the ``PackageIndex`` class (which is now
+   subclassable and replaceable), so that embedders can more easily override
+   download logic, give download progress reports, etc. The class has also
+   been moved to the new ``setuptools.package_index`` module.
+
+ * The ``Installer`` class no longer handles downloading, manages a temporary
+   directory, or tracks the ``zip_ok`` option. Downloading is now handled
+   by ``PackageIndex``, and ``Installer`` has become an ``easy_install``
+   command class based on ``setuptools.Command``.
+
+ * There is a new ``setuptools.sandbox.run_setup()`` API to invoke a setup
+   script in a directory sandbox, and a new ``setuptools.archive_util`` module
+   with an ``unpack_archive()`` API. These were split out of EasyInstall to
+   allow reuse by other tools and applications.
+
+ * ``setuptools.Command`` now supports reinitializing commands using keyword
+   arguments to set/reset options. Also, ``Command`` subclasses can now set
+   their ``command_consumes_arguments`` attribute to ``True`` in order to
+   receive an ``args`` option containing the rest of the command line.
+
+0.3a2
+-----
+
+ * Added new options to ``bdist_egg`` to allow tagging the egg's version number
+   with a subversion revision number, the current date, or an explicit tag
+   value. Run ``setup.py bdist_egg --help`` to get more information.
+
+ * Misc. bug fixes
+
+0.3a1
+-----
+
+ * Initial release.
+
diff --git a/vendor/setuptools-39.0.1/LICENSE b/vendor/setuptools-39.0.1/LICENSE
new file mode 100644
index 00000000..6e0693b4
--- /dev/null
+++ b/vendor/setuptools-39.0.1/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2016 Jason R Coombs <jaraco@jaraco.com>
+
+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/vendor/setuptools-39.0.1/MANIFEST.in b/vendor/setuptools-39.0.1/MANIFEST.in
new file mode 100644
index 00000000..325bbed8
--- /dev/null
+++ b/vendor/setuptools-39.0.1/MANIFEST.in
@@ -0,0 +1,14 @@
+recursive-include setuptools *.py *.exe *.xml
+recursive-include tests *.py
+recursive-include setuptools/tests *.html
+recursive-include docs *.py *.txt *.conf *.css *.css_t Makefile indexsidebar.html
+recursive-include setuptools/_vendor *
+recursive-include pkg_resources *.py *.txt
+include *.py
+include *.rst
+include MANIFEST.in
+include LICENSE
+include launcher.c
+include msvc-build-launcher.cmd
+include pytest.ini
+include tox.ini
diff --git a/vendor/setuptools-39.0.1/PKG-INFO b/vendor/setuptools-39.0.1/PKG-INFO
new file mode 100644
index 00000000..2262142e
--- /dev/null
+++ b/vendor/setuptools-39.0.1/PKG-INFO
@@ -0,0 +1,65 @@
+Metadata-Version: 2.1
+Name: setuptools
+Version: 39.0.1
+Summary: Easily download, build, install, upgrade, and uninstall Python packages
+Home-page: https://github.com/pypa/setuptools
+Author: Python Packaging Authority
+Author-email: distutils-sig@python.org
+License: UNKNOWN
+Project-URL: Documentation, https://setuptools.readthedocs.io/
+Description: .. image:: https://img.shields.io/pypi/v/setuptools.svg
+           :target: https://pypi.org/project/setuptools
+        
+        .. image:: https://readthedocs.org/projects/setuptools/badge/?version=latest
+            :target: https://setuptools.readthedocs.io
+        
+        .. image:: https://img.shields.io/travis/pypa/setuptools/master.svg?label=Linux%20build%20%40%20Travis%20CI
+           :target: https://travis-ci.org/pypa/setuptools
+        
+        .. image:: https://img.shields.io/appveyor/ci/jaraco/setuptools/master.svg?label=Windows%20build%20%40%20Appveyor
+           :target: https://ci.appveyor.com/project/jaraco/setuptools/branch/master
+        
+        .. image:: https://img.shields.io/pypi/pyversions/setuptools.svg
+        
+        See the `Installation Instructions
+        <https://packaging.python.org/installing/>`_ in the Python Packaging
+        User's Guide for instructions on installing, upgrading, and uninstalling
+        Setuptools.
+        
+        The project is `maintained at GitHub <https://github.com/pypa/setuptools>`_.
+        
+        Questions and comments should be directed to the `distutils-sig
+        mailing list <http://mail.python.org/pipermail/distutils-sig/>`_.
+        Bug reports and especially tested patches may be
+        submitted directly to the `bug tracker
+        <https://github.com/pypa/setuptools/issues>`_.
+        
+        
+        Code of Conduct
+        ---------------
+        
+        Everyone interacting in the setuptools project's codebases, issue trackers,
+        chat rooms, and mailing lists is expected to follow the
+        `PyPA Code of Conduct <https://www.pypa.io/en/latest/code-of-conduct/>`_.
+        
+Keywords: CPAN PyPI distutils eggs package management
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: System :: Archiving :: Packaging
+Classifier: Topic :: System :: Systems Administration
+Classifier: Topic :: Utilities
+Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*
+Description-Content-Type: text/x-rst; charset=UTF-8
+Provides-Extra: certs
+Provides-Extra: ssl
diff --git a/vendor/setuptools-39.0.1/README.rst b/vendor/setuptools-39.0.1/README.rst
new file mode 100755
index 00000000..f754d966
--- /dev/null
+++ b/vendor/setuptools-39.0.1/README.rst
@@ -0,0 +1,34 @@
+.. image:: https://img.shields.io/pypi/v/setuptools.svg
+   :target: https://pypi.org/project/setuptools
+
+.. image:: https://readthedocs.org/projects/setuptools/badge/?version=latest
+    :target: https://setuptools.readthedocs.io
+
+.. image:: https://img.shields.io/travis/pypa/setuptools/master.svg?label=Linux%20build%20%40%20Travis%20CI
+   :target: https://travis-ci.org/pypa/setuptools
+
+.. image:: https://img.shields.io/appveyor/ci/jaraco/setuptools/master.svg?label=Windows%20build%20%40%20Appveyor
+   :target: https://ci.appveyor.com/project/jaraco/setuptools/branch/master
+
+.. image:: https://img.shields.io/pypi/pyversions/setuptools.svg
+
+See the `Installation Instructions
+<https://packaging.python.org/installing/>`_ in the Python Packaging
+User's Guide for instructions on installing, upgrading, and uninstalling
+Setuptools.
+
+The project is `maintained at GitHub <https://github.com/pypa/setuptools>`_.
+
+Questions and comments should be directed to the `distutils-sig
+mailing list <http://mail.python.org/pipermail/distutils-sig/>`_.
+Bug reports and especially tested patches may be
+submitted directly to the `bug tracker
+<https://github.com/pypa/setuptools/issues>`_.
+
+
+Code of Conduct
+---------------
+
+Everyone interacting in the setuptools project's codebases, issue trackers,
+chat rooms, and mailing lists is expected to follow the
+`PyPA Code of Conduct <https://www.pypa.io/en/latest/code-of-conduct/>`_.
diff --git a/vendor/setuptools-39.0.1/bootstrap.py b/vendor/setuptools-39.0.1/bootstrap.py
new file mode 100644
index 00000000..8c7d7fc3
--- /dev/null
+++ b/vendor/setuptools-39.0.1/bootstrap.py
@@ -0,0 +1,64 @@
+"""
+If setuptools is not already installed in the environment, it's not possible
+to invoke setuptools' own commands. This routine will bootstrap this local
+environment by creating a minimal egg-info directory and then invoking the
+egg-info command to flesh out the egg-info directory.
+"""
+
+from __future__ import unicode_literals
+
+import os
+import sys
+import textwrap
+import subprocess
+import io
+
+
+minimal_egg_info = textwrap.dedent("""
+    [distutils.commands]
+    egg_info = setuptools.command.egg_info:egg_info
+
+    [distutils.setup_keywords]
+    include_package_data = setuptools.dist:assert_bool
+    install_requires = setuptools.dist:check_requirements
+    extras_require = setuptools.dist:check_extras
+    entry_points = setuptools.dist:check_entry_points
+
+    [egg_info.writers]
+    dependency_links.txt = setuptools.command.egg_info:overwrite_arg
+    entry_points.txt = setuptools.command.egg_info:write_entries
+    requires.txt = setuptools.command.egg_info:write_requirements
+    """)
+
+
+def ensure_egg_info():
+    if os.path.exists('setuptools.egg-info'):
+        return
+    print("adding minimal entry_points")
+    build_egg_info()
+
+
+def build_egg_info():
+    """
+    Build a minimal egg-info, enough to invoke egg_info
+    """
+
+    os.mkdir('setuptools.egg-info')
+    with io.open('setuptools.egg-info/entry_points.txt', 'w') as ep:
+        ep.write(minimal_egg_info)
+
+
+def run_egg_info():
+    cmd = [sys.executable, 'setup.py', 'egg_info']
+    print("Regenerating egg_info")
+    subprocess.check_call(cmd)
+    print("...and again.")
+    subprocess.check_call(cmd)
+
+
+def main():
+    ensure_egg_info()
+    run_egg_info()
+
+
+__name__ == '__main__' and main()
diff --git a/vendor/setuptools-39.0.1/build/lib/easy_install.py b/vendor/setuptools-39.0.1/build/lib/easy_install.py
new file mode 100644
index 00000000..d87e9840
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/easy_install.py
@@ -0,0 +1,5 @@
+"""Run the EasyInstall command"""
+
+if __name__ == '__main__':
+    from setuptools.command.easy_install import main
+    main()
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/__init__.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/__init__.py
new file mode 100644
index 00000000..8d95bd29
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/__init__.py
@@ -0,0 +1,3125 @@
+# coding: utf-8
+"""
+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.
+"""
+
+from __future__ import absolute_import
+
+import sys
+import os
+import io
+import time
+import re
+import types
+import zipfile
+import zipimport
+import warnings
+import stat
+import functools
+import pkgutil
+import operator
+import platform
+import collections
+import plistlib
+import email.parser
+import errno
+import tempfile
+import textwrap
+import itertools
+import inspect
+from pkgutil import get_importer
+
+try:
+    import _imp
+except ImportError:
+    # Python 3.2 compatibility
+    import imp as _imp
+
+from pkg_resources.extern import six
+from pkg_resources.extern.six.moves import urllib, map, filter
+
+# 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
+
+try:
+    import importlib.machinery as importlib_machinery
+    # access attribute to force import under delayed import mechanisms.
+    importlib_machinery.__name__
+except ImportError:
+    importlib_machinery = None
+
+from . import py31compat
+from pkg_resources.extern import appdirs
+from pkg_resources.extern import packaging
+__import__('pkg_resources.extern.packaging.version')
+__import__('pkg_resources.extern.packaging.specifiers')
+__import__('pkg_resources.extern.packaging.requirements')
+__import__('pkg_resources.extern.packaging.markers')
+
+
+if (3, 0) < sys.version_info < (3, 3):
+    raise RuntimeError("Python 3.3 or later is required")
+
+if six.PY2:
+    # Those builtin exceptions are only defined in Python 3
+    PermissionError = None
+    NotADirectoryError = None
+
+# declare some globals that will be defined later to
+# satisfy the linters.
+require = None
+working_set = None
+add_activation_listener = None
+resources_stream = None
+cleanup_resources = None
+resource_dir = None
+resource_stream = None
+set_extraction_path = None
+resource_isdir = None
+resource_string = None
+iter_entry_points = None
+resource_listdir = None
+resource_filename = None
+resource_exists = None
+_distribution_finders = None
+_namespace_handlers = None
+_namespace_packages = None
+
+
+class PEP440Warning(RuntimeWarning):
+    """
+    Used when there is an issue with a version or specifier not complying with
+    PEP 440.
+    """
+
+
+def parse_version(v):
+    try:
+        return packaging.version.Version(v)
+    except packaging.version.InvalidVersion:
+        return packaging.version.LegacyVersion(v)
+
+
+_state_vars = {}
+
+
+def _declare_state(vartype, **kw):
+    globals().update(kw)
+    _state_vars.update(dict.fromkeys(kw, 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:
+            # not Mac OS X
+            pass
+    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',
+
+    # Warnings
+    'PEP440Warning',
+
+    # 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', 'invalid_marker', 'evaluate_marker',
+
+    # 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.
+
+    Should be initialized with the installed Distribution and the requested
+    Requirement.
+    """
+
+    _template = "{self.dist} is installed but {self.req} is required"
+
+    @property
+    def dist(self):
+        return self.args[0]
+
+    @property
+    def req(self):
+        return self.args[1]
+
+    def report(self):
+        return self._template.format(**locals())
+
+    def with_context(self, required_by):
+        """
+        If required_by is non-empty, return a version of self that is a
+        ContextualVersionConflict.
+        """
+        if not required_by:
+            return self
+        args = self.args + (required_by,)
+        return ContextualVersionConflict(*args)
+
+
+class ContextualVersionConflict(VersionConflict):
+    """
+    A VersionConflict that accepts a third parameter, the set of the
+    requirements that required the installed Distribution.
+    """
+
+    _template = VersionConflict._template + ' by {self.required_by}'
+
+    @property
+    def required_by(self):
+        return self.args[2]
+
+
+class DistributionNotFound(ResolutionError):
+    """A requested distribution was not found"""
+
+    _template = ("The '{self.req}' distribution was not found "
+                 "and is required by {self.requirers_str}")
+
+    @property
+    def req(self):
+        return self.args[0]
+
+    @property
+    def requirers(self):
+        return self.args[1]
+
+    @property
+    def requirers_str(self):
+        if not self.requirers:
+            return 'the application'
+        return ', '.join(self.requirers)
+
+    def report(self):
+        return self._template.format(**locals())
+
+    def __str__(self):
+        return self.report()
+
+
+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:
+        version = platform.mac_ver()[0]
+        # fallback for MacPorts
+        if version == '':
+            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:
+        # Python 2.7 or >=3.2
+        from sysconfig import get_platform
+    except ImportError:
+        from distutils.util 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+)-(.*)")
+# XXX backward compat
+get_platform = get_build_platform
+
+
+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:
+        # easy case
+        return True
+
+    # 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":
+                    return True
+            # egg isn't macosx or legacy darwin
+            return False
+
+        # 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)
+
+
+# backward compatibility
+run_main = run_script
+
+
+def get_distribution(dist):
+    """Return a current distribution object for a Requirement or string"""
+    if isinstance(dist, six.string_types):
+        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)
+
+    @classmethod
+    def _build_master(cls):
+        """
+        Prepare the master working set.
+        """
+        ws = cls()
+        try:
+            from __main__ import __requires__
+        except ImportError:
+            # The main program does not list any requirements
+            return ws
+
+        # ensure the requirements are met
+        try:
+            ws.require(__requires__)
+        except VersionConflict:
+            return cls._build_from_requirements(__requires__)
+
+        return ws
+
+    @classmethod
+    def _build_from_requirements(cls, req_spec):
+        """
+        Build a working set from a requirement spec. Rewrites sys.path.
+        """
+        # try it without defaults already on sys.path
+        # by starting with an empty path
+        ws = cls([])
+        reqs = parse_requirements(req_spec)
+        dists = ws.resolve(reqs, Environment())
+        for dist in dists:
+            ws.add(dist)
+
+        # add any missing entries from sys.path
+        for entry in sys.path:
+            if entry not in ws.entries:
+                ws.add_entry(entry)
+
+        # then copy back to sys.path
+        sys.path[:] = ws.entries
+        return ws
+
+    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:
+            # XXX add more info
+            raise VersionConflict(dist, req)
+        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 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, replace=False):
+        """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, unless `replace=True`.
+        If it's added, any callbacks registered with the ``subscribe()`` method
+        will be called.
+        """
+        if insert:
+            dist.insert_on(self.entries, entry, replace=replace)
+
+        if entry is None:
+            entry = dist.location
+        keys = self.entry_keys.setdefault(entry, [])
+        keys2 = self.entry_keys.setdefault(dist.location, [])
+        if not replace and dist.key in self.by_key:
+            # ignore hidden distros
+            return
+
+        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,
+                replace_conflicting=False, extras=None):
+        """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``.
+
+        Unless `replace_conflicting=True`, raises a VersionConflict exception
+        if
+        any requirements are found on the path that have the correct name but
+        the wrong version.  Otherwise, if an `installer` is supplied it will be
+        invoked to obtain the correct version of the requirement and activate
+        it.
+
+        `extras` is a list of the extras to be used with these requirements.
+        This is important because extra requirements may look like `my_req;
+        extra = "my_extra"`, which would otherwise be interpreted as a purely
+        optional requirement.  Instead, we want to be able to assert that these
+        requirements are truly required.
+        """
+
+        # set up the stack
+        requirements = list(requirements)[::-1]
+        # set of processed requirements
+        processed = {}
+        # key -> dist
+        best = {}
+        to_activate = []
+
+        req_extras = _ReqExtras()
+
+        # Mapping of requirement to set of distributions that required it;
+        # useful for reporting info about conflicts.
+        required_by = collections.defaultdict(set)
+
+        while requirements:
+            # process dependencies breadth-first
+            req = requirements.pop(0)
+            if req in processed:
+                # Ignore cyclic or redundant dependencies
+                continue
+
+            if not req_extras.markers_pass(req, extras):
+                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 or (dist not in req and replace_conflicting):
+                    ws = self
+                    if env is None:
+                        if dist is None:
+                            env = Environment(self.entries)
+                        else:
+                            # Use an empty environment and workingset to avoid
+                            # any further conflicts with the conflicting
+                            # distribution
+                            env = Environment([])
+                            ws = WorkingSet([])
+                    dist = best[req.key] = env.best_match(
+                        req, ws, installer,
+                        replace_conflicting=replace_conflicting
+                    )
+                    if dist is None:
+                        requirers = required_by.get(req, None)
+                        raise DistributionNotFound(req, requirers)
+                to_activate.append(dist)
+            if dist not in req:
+                # Oops, the "best" so far conflicts with a dependency
+                dependent_req = required_by[req]
+                raise VersionConflict(dist, req).with_context(dependent_req)
+
+            # push the new requirements onto the stack
+            new_requirements = dist.requires(req.extras)[::-1]
+            requirements.extend(new_requirements)
+
+            # Register the new requirements needed by req
+            for new_requirement in new_requirements:
+                required_by[new_requirement].add(req.project_name)
+                req_extras[new_requirement] = req.extras
+
+            processed[req] = True
+
+        # return list of distros to activate
+        return 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)
+            )
+            # add plugins+libs to sys.path
+            map(working_set.add, distributions)
+            # display errors
+            print('Could not load', 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)
+        # scan project names in alphabetic order
+        plugin_projects.sort()
+
+        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__([])
+        # put all our entries in shadow_set
+        list(map(shadow_set.add, self))
+
+        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:
+                    # save error info
+                    error_info[dist] = v
+                    if fallback:
+                        # try the next older version of project
+                        continue
+                    else:
+                        # give up on this project, keep going
+                        break
+
+                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, existing=True):
+        """Invoke `callback` for all distributions
+
+        If `existing=True` (default),
+        call on all existing ones, as well.
+        """
+        if callback in self.callbacks:
+            return
+        self.callbacks.append(callback)
+        if not existing:
+            return
+        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, e_k_b_c):
+        entries, keys, by_key, callbacks = e_k_b_c
+        self.entries = entries[:]
+        self.entry_keys = keys.copy()
+        self.by_key = by_key.copy()
+        self.callbacks = callbacks[:]
+
+
+class _ReqExtras(dict):
+    """
+    Map each requirement to the extras that demanded it.
+    """
+
+    def markers_pass(self, req, extras=None):
+        """
+        Evaluate markers for req against each extra that
+        demanded it.
+
+        Return False if the req has a marker and fails
+        evaluation. Otherwise, return True.
+        """
+        extra_evals = (
+            req.marker.evaluate({'extra': extra})
+            for extra in self.get(req, ()) + (extras or (None,))
+        )
+        return not req.marker or any(extra_evals)
+
+
+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. ``'3.3'``);
+        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.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.
+        """
+        py_compat = (
+            self.python is None
+            or dist.py_version is None
+            or dist.py_version == self.python
+        )
+        return py_compat 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`
+
+        Uses case-insensitive `project_name` comparison, assuming all the
+        project's distributions use their project's name converted to all
+        lowercase as their key.
+
+        """
+        distribution_key = project_name.lower()
+        return self._distmap.get(distribution_key, [])
+
+    def add(self, dist):
+        """Add `dist` if we ``can_add()`` it and it has not already been added
+        """
+        if self.can_add(dist) and dist.has_version():
+            dists = self._distmap.setdefault(dist.key, [])
+            if dist not in dists:
+                dists.append(dist)
+                dists.sort(key=operator.attrgetter('hashcmp'), reverse=True)
+
+    def best_match(
+            self, req, working_set, installer=None, replace_conflicting=False):
+        """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.
+        """
+        try:
+            dist = working_set.find(req)
+        except VersionConflict:
+            if not replace_conflicting:
+                raise
+            dist = None
+        if dist is not None:
+            return dist
+        for dist in self[req.key]:
+            if dist in req:
+                return dist
+        # try to download/install
+        return self.obtain(req, installer)
+
+    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 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
+
+
+# XXX backward compatibility
+AvailableDistributions = Environment
+
+
+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()
+
+        tmpl = textwrap.dedent("""
+            Can't extract file(s) to egg cache
+
+            The following error occurred while trying to extract file(s)
+            to the Python egg cache:
+
+              {old_exc}
+
+            The Python egg cache directory is currently set to:
+
+              {cache_path}
+
+            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.
+            """).lstrip()
+        err = ExtractionError(tmpl.format(**locals()))
+        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 Exception:
+            self.extraction_error()
+
+        self._warn_unsafe_extraction_path(extract_path)
+
+        self.cached_files[target_path] = 1
+        return target_path
+
+    @staticmethod
+    def _warn_unsafe_extraction_path(path):
+        """
+        If the default extraction path is overridden and set to an insecure
+        location, such as /tmp, it opens up an opportunity for an attacker to
+        replace an extracted file with an unauthorized payload. Warn the user
+        if a known insecure location is used.
+
+        See Distribute #375 for more details.
+        """
+        if os.name == 'nt' and not path.startswith(os.environ['windir']):
+            # On Windows, permissions are generally restrictive by default
+            #  and temp directories are not writable by other users, so
+            #  bypass the warning.
+            return
+        mode = os.stat(path).st_mode
+        if mode & stat.S_IWOTH or mode & stat.S_IWGRP:
+            msg = (
+                "%s is writable by group/others and vulnerable to attack "
+                "when "
+                "used with get_resource_filename. Consider a more secure "
+                "location (set with .set_extraction_path or the "
+                "PYTHON_EGG_CACHE environment variable)." % path
+            )
+            warnings.warn(msg, UserWarning)
+
+    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():
+    """
+    Return the ``PYTHON_EGG_CACHE`` environment variable
+    or a platform-relevant user cache dir for an app
+    named "Python-Eggs".
+    """
+    return (
+        os.environ.get('PYTHON_EGG_CACHE')
+        or appdirs.user_cache_dir(appname='Python-Eggs')
+    )
+
+
+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
+    """
+    try:
+        # normalize the version
+        return str(packaging.version.Version(version))
+    except packaging.version.InvalidVersion:
+        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('-', '_')
+
+
+def invalid_marker(text):
+    """
+    Validate text as a PEP 508 environment marker; return an exception
+    if invalid or False otherwise.
+    """
+    try:
+        evaluate_marker(text)
+    except SyntaxError as e:
+        e.filename = None
+        e.lineno = None
+        return e
+    return False
+
+
+def evaluate_marker(text, extra=None):
+    """
+    Evaluate a PEP 508 environment marker.
+    Return a boolean indicating the marker result in this environment.
+    Raise SyntaxError if marker is invalid.
+
+    This implementation uses the 'pyparsing' module.
+    """
+    try:
+        marker = packaging.markers.Marker(text)
+        return marker.evaluate()
+    except packaging.markers.InvalidMarker as e:
+        raise SyntaxError(e)
+
+
+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 io.BytesIO(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))
+
+    def get_metadata(self, name):
+        if not self.egg_info:
+            return ""
+        value = self._get(self._fn(self.egg_info, name))
+        return value.decode('utf-8') if six.PY3 else value
+
+    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(
+                "Script {script!r} not found in metadata at {self.egg_info!r}"
+                .format(**locals()),
+            )
+        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):
+            source = open(script_filename).read()
+            code = compile(source, script_filename, 'exec')
+            exec(code, 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 _is_egg_path(path):
+                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):
+        with open(path, 'rb') as stream:
+            return stream.read()
+
+    @classmethod
+    def _register(cls):
+        loader_cls = getattr(
+            importlib_machinery,
+            'SourceFileLoader',
+            type(None),
+        )
+        register_loader_type(loader_cls, cls)
+
+
+DefaultProvider._register()
+
+
+class EmptyProvider(NullProvider):
+    """Provider that returns nothing for all requests"""
+
+    module_path = None
+
+    _isdir = _has = lambda self, path: False
+
+    def _get(self, path):
+        return ''
+
+    def _listdir(self, path):
+        return []
+
+    def __init__(self):
+        pass
+
+
+empty_provider = EmptyProvider()
+
+
+class ZipManifests(dict):
+    """
+    zip manifest builder
+    """
+
+    @classmethod
+    def build(cls, path):
+        """
+        Build a dictionary similar to the zipimport directory
+        caches, except instead of tuples, store ZipInfo objects.
+
+        Use a platform-specific path separator (os.sep) for the path keys
+        for compatibility with pypy on Windows.
+        """
+        with zipfile.ZipFile(path) as zfile:
+            items = (
+                (
+                    name.replace('/', os.sep),
+                    zfile.getinfo(name),
+                )
+                for name in zfile.namelist()
+            )
+            return dict(items)
+
+    load = build
+
+
+class MemoizedZipManifests(ZipManifests):
+    """
+    Memoized zipfile manifests.
+    """
+    manifest_mod = collections.namedtuple('manifest_mod', 'manifest mtime')
+
+    def load(self, path):
+        """
+        Load a manifest at path or return a suitable manifest already loaded.
+        """
+        path = os.path.normpath(path)
+        mtime = os.stat(path).st_mtime
+
+        if path not in self or self[path].mtime != mtime:
+            manifest = self.build(path)
+            self[path] = self.manifest_mod(manifest, mtime)
+
+        return self[path].manifest
+
+
+class ZipProvider(EggProvider):
+    """Resource support for zips and eggs"""
+
+    eagers = None
+    _zip_manifests = MemoizedZipManifests()
+
+    def __init__(self, module):
+        EggProvider.__init__(self, module)
+        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
+        fspath = fspath.rstrip(os.sep)
+        if fspath == self.loader.archive:
+            return ''
+        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.
+        # pseudo-fs path
+        fspath = self.zip_pre + zip_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)
+        )
+
+    @property
+    def zipinfo(self):
+        return self._zip_manifests.load(self.loader.archive)
+
+    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)
+
+    @staticmethod
+    def _get_date_and_size(zip_stat):
+        size = zip_stat.file_size
+        # ymdhms+wday, yday, dst
+        date_time = zip_stat.date_time + (0, 0, -1)
+        # 1980 offset already done
+        timestamp = time.mktime(date_time)
+        return timestamp, size
+
+    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 the extracted directory name
+            return os.path.dirname(last)
+
+        timestamp, size = self._get_date_and_size(self.zipinfo[zip_path])
+
+        if not WRITE_SUPPORT:
+            raise IOError('"os.rename" and "os.unlink" are not supported '
+                          'on this platform')
+        try:
+
+            real_path = manager.get_cache_path(
+                self.egg_name, self._parts(zip_path)
+            )
+
+            if self._is_current(real_path, zip_path):
+                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):
+                    if self._is_current(real_path, zip_path):
+                        # the file became current since it was checked above,
+                        #  so proceed.
+                        return real_path
+                    # Windows, del old file and retry
+                    elif os.name == 'nt':
+                        unlink(real_path)
+                        rename(tmpnam, real_path)
+                        return real_path
+                raise
+
+        except os.error:
+            # report a user-friendly error
+            manager.extraction_error()
+
+        return real_path
+
+    def _is_current(self, file_path, zip_path):
+        """
+        Return True if the file_path is current for this zip_path
+        """
+        timestamp, size = self._get_date_and_size(self.zipinfo[zip_path])
+        if not os.path.isfile(file_path):
+            return False
+        stat = os.stat(file_path)
+        if stat.st_size != size or stat.st_mtime != timestamp:
+            return False
+        # check that the contents match
+        zip_contents = self.loader.get_data(zip_path)
+        with open(file_path, 'rb') as f:
+            file_contents = f.read()
+        return zip_contents == file_contents
+
+    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' and os.path.isfile(self.path)
+
+    def get_metadata(self, name):
+        if name != 'PKG-INFO':
+            raise KeyError("No metadata except PKG-INFO is available")
+
+        with io.open(self.path, encoding='utf-8', errors="replace") as f:
+            metadata = f.read()
+        self._warn_on_replacement(metadata)
+        return metadata
+
+    def _warn_on_replacement(self, metadata):
+        # Python 2.7 compat for: replacement_char = '�'
+        replacement_char = b'\xef\xbf\xbd'.decode('utf-8')
+        if replacement_char in metadata:
+            tmpl = "{self.path} could not be properly decoded in UTF-8"
+            msg = tmpl.format(**locals())
+            warnings.warn(msg)
+
+    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.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()
+
+
+_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_eggs_in_zip(importer, path_item, only=False):
+    """
+    Find eggs in zip files; possibly multiple nested eggs.
+    """
+    if importer.archive.endswith('.whl'):
+        # wheels are not supported with this finder
+        # they don't have PKG-INFO metadata, and won't ever contain eggs
+        return
+    metadata = EggMetadata(importer)
+    if metadata.has_metadata('PKG-INFO'):
+        yield Distribution.from_filename(path_item, metadata=metadata)
+    if only:
+        # don't yield nested distros
+        return
+    for subitem in metadata.resource_listdir('/'):
+        if _is_egg_path(subitem):
+            subpath = os.path.join(path_item, subitem)
+            dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath)
+            for dist in dists:
+                yield dist
+        elif subitem.lower().endswith('.dist-info'):
+            subpath = os.path.join(path_item, subitem)
+            submeta = EggMetadata(zipimport.zipimporter(subpath))
+            submeta.egg_info = subpath
+            yield Distribution.from_location(path_item, subitem, submeta)
+
+
+register_finder(zipimport.zipimporter, find_eggs_in_zip)
+
+
+def find_nothing(importer, path_item, only=False):
+    return ()
+
+
+register_finder(object, find_nothing)
+
+
+def _by_version_descending(names):
+    """
+    Given a list of filenames, return them in descending order
+    by version number.
+
+    >>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg'
+    >>> _by_version_descending(names)
+    ['Python-2.7.10.egg', 'Python-2.7.2.egg', 'foo', 'bar']
+    >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg'
+    >>> _by_version_descending(names)
+    ['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg']
+    >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.post1.egg'
+    >>> _by_version_descending(names)
+    ['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg']
+    """
+    def _by_version(name):
+        """
+        Parse each component of the filename
+        """
+        name, ext = os.path.splitext(name)
+        parts = itertools.chain(name.split('-'), [ext])
+        return [packaging.version.parse(part) for part in parts]
+
+    return sorted(names, key=_by_version, reverse=True)
+
+
+def find_on_path(importer, path_item, only=False):
+    """Yield distributions accessible on a sys.path directory"""
+    path_item = _normalize_cached(path_item)
+
+    if _is_unpacked_egg(path_item):
+        yield Distribution.from_filename(
+            path_item, metadata=PathMetadata(
+                path_item, os.path.join(path_item, 'EGG-INFO')
+            )
+        )
+        return
+
+    entries = safe_listdir(path_item)
+
+    # for performance, before sorting by version,
+    # screen entries for only those that will yield
+    # distributions
+    filtered = (
+        entry
+        for entry in entries
+        if dist_factory(path_item, entry, only)
+    )
+
+    # scan for .egg and .egg-info in directory
+    path_item_entries = _by_version_descending(filtered)
+    for entry in path_item_entries:
+        fullpath = os.path.join(path_item, entry)
+        factory = dist_factory(path_item, entry, only)
+        for dist in factory(fullpath):
+            yield dist
+
+
+def dist_factory(path_item, entry, only):
+    """
+    Return a dist_factory for a path_item and entry
+    """
+    lower = entry.lower()
+    is_meta = any(map(lower.endswith, ('.egg-info', '.dist-info')))
+    return (
+        distributions_from_metadata
+        if is_meta else
+        find_distributions
+        if not only and _is_egg_path(entry) else
+        resolve_egg_link
+        if not only and lower.endswith('.egg-link') else
+        NoDists()
+    )
+
+
+class NoDists:
+    """
+    >>> bool(NoDists())
+    False
+
+    >>> list(NoDists()('anything'))
+    []
+    """
+    def __bool__(self):
+        return False
+    if six.PY2:
+        __nonzero__ = __bool__
+
+    def __call__(self, fullpath):
+        return iter(())
+
+
+def safe_listdir(path):
+    """
+    Attempt to list contents of path, but suppress some exceptions.
+    """
+    try:
+        return os.listdir(path)
+    except (PermissionError, NotADirectoryError):
+        pass
+    except OSError as e:
+        # Ignore the directory if does not exist, not a directory or
+        # permission denied
+        ignorable = (
+            e.errno in (errno.ENOTDIR, errno.EACCES, errno.ENOENT)
+            # Python 2 on Windows needs to be handled this way :(
+            or getattr(e, "winerror", None) == 267
+        )
+        if not ignorable:
+            raise
+    return ()
+
+
+def distributions_from_metadata(path):
+    root = os.path.dirname(path)
+    if os.path.isdir(path):
+        if len(os.listdir(path)) == 0:
+            # empty metadata dir; skip
+            return
+        metadata = PathMetadata(root, path)
+    else:
+        metadata = FileMetadata(path)
+    entry = os.path.basename(path)
+    yield Distribution.from_location(
+        root, entry, metadata, precedence=DEVELOP_DIST,
+    )
+
+
+def non_empty_lines(path):
+    """
+    Yield non-empty lines from file at path
+    """
+    with open(path) as f:
+        for line in f:
+            line = line.strip()
+            if line:
+                yield line
+
+
+def resolve_egg_link(path):
+    """
+    Given a path to an .egg-link, resolve distributions
+    present in the referenced path.
+    """
+    referenced_paths = non_empty_lines(path)
+    resolved_paths = (
+        os.path.join(os.path.dirname(path), ref)
+        for ref in referenced_paths
+    )
+    dist_groups = map(find_distributions, resolved_paths)
+    return next(dist_groups, ())
+
+
+register_finder(pkgutil.ImpImporter, find_on_path)
+
+if hasattr(importlib_machinery, 'FileFinder'):
+    register_finder(importlib_machinery.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)
+        _rebuild_mod_path(path, packageName, module)
+    return subpath
+
+
+def _rebuild_mod_path(orig_path, package_name, module):
+    """
+    Rebuild module.__path__ ensuring that all entries are ordered
+    corresponding to their sys.path order
+    """
+    sys_path = [_normalize_cached(p) for p in sys.path]
+
+    def safe_sys_path_index(entry):
+        """
+        Workaround for #520 and #513.
+        """
+        try:
+            return sys_path.index(entry)
+        except ValueError:
+            return float('inf')
+
+    def position_in_sys_path(path):
+        """
+        Return the ordinal of the path based on its position in sys.path
+        """
+        path_parts = path.split(os.sep)
+        module_parts = package_name.count('.') + 1
+        parts = path_parts[:-module_parts]
+        return safe_sys_path_index(_normalize_cached(os.sep.join(parts)))
+
+    if not isinstance(orig_path, list):
+        # Is this behavior useful when module.__path__ is not a list?
+        return
+
+    orig_path.sort(key=position_in_sys_path)
+    module.__path__[:] = [_normalize_cached(p) for p in orig_path]
+
+
+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(pkgutil.ImpImporter, file_ns_handler)
+register_namespace_handler(zipimport.zipimporter, file_ns_handler)
+
+if hasattr(importlib_machinery, 'FileFinder'):
+    register_namespace_handler(importlib_machinery.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 _is_egg_path(path):
+    """
+    Determine if given path appears to be an egg.
+    """
+    return path.lower().endswith('.egg')
+
+
+def _is_unpacked_egg(path):
+    """
+    Determine if given path appears to be an unpacked egg.
+    """
+    return (
+        _is_egg_path(path) and
+        os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO'))
+    )
+
+
+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 string or sequence"""
+    if isinstance(strs, six.string_types):
+        for s in strs.splitlines():
+            s = s.strip()
+            # skip blank lines/comments
+            if s and not s.startswith('#'):
+                yield s
+    else:
+        for ss in strs:
+            for s in yield_lines(ss):
+                yield s
+
+
+MODULE = re.compile(r"\w+(\.\w+)*$").match
+EGG_NAME = re.compile(
+    r"""
+    (?P<name>[^-]+) (
+        -(?P<ver>[^-]+) (
+            -py(?P<pyver>[^-]+) (
+                -(?P<plat>.+)
+            )?
+        )?
+    )?
+    """,
+    re.VERBOSE | re.IGNORECASE,
+).match
+
+
+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 = tuple(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, *args, **kwargs):
+        """
+        Require packages for this EntryPoint, then resolve it.
+        """
+        if not require or args or kwargs:
+            warnings.warn(
+                "Parameters to load are deprecated.  Call .resolve and "
+                ".require separately.",
+                DeprecationWarning,
+                stacklevel=2,
+            )
+        if require:
+            self.require(*args, **kwargs)
+        return self.resolve()
+
+    def resolve(self):
+        """
+        Resolve the entry point from its module and attrs.
+        """
+        module = __import__(self.module_name, fromlist=['__name__'], level=0)
+        try:
+            return functools.reduce(getattr, self.attrs, module)
+        except AttributeError as exc:
+            raise ImportError(str(exc))
+
+    def require(self, env=None, installer=None):
+        if self.extras and not self.dist:
+            raise UnknownExtra("Can't require() without a distribution", self)
+
+        # Get the requirements for this entry point with all its extras and
+        # then resolve them. We have to pass `extras` along when resolving so
+        # that the working set knows what extras we want. Otherwise, for
+        # dist-info distributions, the working set will assume that the
+        # requirements for that extra are purely optional and skip over them.
+        reqs = self.dist.requires(self.extras)
+        items = working_set.resolve(reqs, env, installer, extras=self.extras)
+        list(map(working_set.add, items))
+
+    pattern = re.compile(
+        r'\s*'
+        r'(?P<name>.+?)\s*'
+        r'=\s*'
+        r'(?P<module>[\w.]+)\s*'
+        r'(:\s*(?P<attr>[\w.]+))?\s*'
+        r'(?P<extras>\[.*\])?\s*$'
+    )
+
+    @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
+        """
+        m = cls.pattern.match(src)
+        if not m:
+            msg = "EntryPoint must be in 'name=module:attrs [extras]' format"
+            raise ValueError(msg, src)
+        res = m.groupdict()
+        extras = cls._parse_extras(res['extras'])
+        attrs = res['attr'].split('.') if res['attr'] else ()
+        return cls(res['name'], res['module'], attrs, extras, dist)
+
+    @classmethod
+    def _parse_extras(cls, extras_spec):
+        if not extras_spec:
+            return ()
+        req = Requirement.parse('x' + extras_spec)
+        if req.specs:
+            raise ValueError()
+        return req.extras
+
+    @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
+
+    @classmethod
+    def parse_map(cls, data, dist=None):
+        """Parse a map of entry point groups"""
+        if isinstance(data, dict):
+            data = 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
+
+
+def _remove_md5_fragment(location):
+    if not location:
+        return ''
+    parsed = urllib.parse.urlparse(location)
+    if parsed[-1].startswith('md5='):
+        return urllib.parse.urlunparse(parsed[:-1] + ('',))
+    return location
+
+
+def _version_from_file(lines):
+    """
+    Given an iterable of lines from a Metadata file, return
+    the value of the Version field, if present, or None otherwise.
+    """
+    def is_version_line(line):
+        return line.lower().startswith('version:')
+    version_lines = filter(is_version_line, lines)
+    line = next(iter(version_lines), '')
+    _, _, value = line.partition(':')
+    return safe_version(value.strip()) or None
+
+
+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:
+            cls = _distributionImpl[ext.lower()]
+
+            match = EGG_NAME(basename)
+            if match:
+                project_name, version, py_version, platform = match.group(
+                    'name', 'ver', 'pyver', 'plat'
+                )
+        return cls(
+            location, metadata, project_name=project_name, version=version,
+            py_version=py_version, platform=platform, **kw
+        )._reload_version()
+
+    def _reload_version(self):
+        return self
+
+    @property
+    def hashcmp(self):
+        return (
+            self.parsed_version,
+            self.precedence,
+            self.key,
+            _remove_md5_fragment(self.location),
+            self.py_version or '',
+            self.platform or '',
+        )
+
+    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
+
+    @property
+    def parsed_version(self):
+        if not hasattr(self, "_parsed_version"):
+            self._parsed_version = parse_version(self.version)
+
+        return self._parsed_version
+
+    def _warn_legacy_version(self):
+        LV = packaging.version.LegacyVersion
+        is_legacy = isinstance(self._parsed_version, LV)
+        if not is_legacy:
+            return
+
+        # While an empty version is technically a legacy version and
+        # is not a valid PEP 440 version, it's also unlikely to
+        # actually come from someone and instead it is more likely that
+        # it comes from setuptools attempting to parse a filename and
+        # including it in the list. So for that we'll gate this warning
+        # on if the version is anything at all or not.
+        if not self.version:
+            return
+
+        tmpl = textwrap.dedent("""
+            '{project_name} ({version})' is being parsed as a legacy,
+            non PEP 440,
+            version. You may find odd behavior and sort order.
+            In particular it will be sorted as less than 0.0. It
+            is recommended to migrate to PEP 440 compatible
+            versions.
+            """).strip().replace('\n', ' ')
+
+        warnings.warn(tmpl.format(**vars(self)), PEP440Warning)
+
+    @property
+    def version(self):
+        try:
+            return self._version
+        except AttributeError:
+            version = _version_from_file(self._get_metadata(self.PKG_INFO))
+            if version is None:
+                tmpl = "Missing 'Version:' header and/or %s file"
+                raise ValueError(tmpl % self.PKG_INFO, self)
+            return version
+
+    @property
+    def _dep_map(self):
+        """
+        A map of extra to its list of (direct) requirements
+        for this distribution, including the null extra.
+        """
+        try:
+            return self.__dep_map
+        except AttributeError:
+            self.__dep_map = self._filter_extras(self._build_dep_map())
+        return self.__dep_map
+
+    @staticmethod
+    def _filter_extras(dm):
+        """
+        Given a mapping of extras to dependencies, strip off
+        environment markers and filter out any dependencies
+        not matching the markers.
+        """
+        for extra in list(filter(None, dm)):
+            new_extra = extra
+            reqs = dm.pop(extra)
+            new_extra, _, marker = extra.partition(':')
+            fails_marker = marker and (
+                invalid_marker(marker)
+                or not evaluate_marker(marker)
+            )
+            if fails_marker:
+                reqs = []
+            new_extra = safe_extra(new_extra) or None
+
+            dm.setdefault(new_extra, []).extend(reqs)
+        return dm
+
+    def _build_dep_map(self):
+        dm = {}
+        for name in 'requires.txt', 'depends.txt':
+            for extra, reqs in split_sections(self._get_metadata(name)):
+                dm.setdefault(extra, []).extend(parse_requirements(reqs))
+        return dm
+
+    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, replace=False):
+        """Ensure distribution is importable on `path` (default=sys.path)"""
+        if path is None:
+            path = sys.path
+        self.insert_on(path, replace=replace)
+        if path is sys.path:
+            fixup_namespace_packages(self.location)
+            for pkg in self._get_metadata('namespace_packages.txt'):
+                if pkg in sys.modules:
+                    declare_namespace(pkg)
+
+    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
+        )
+
+    def as_requirement(self):
+        """Return a ``Requirement`` that matches this distribution exactly"""
+        if isinstance(self.parsed_version, packaging.version.Version):
+            spec = "%s==%s" % (self.project_name, self.parsed_version)
+        else:
+            spec = "%s===%s" % (self.project_name, self.parsed_version)
+
+        return Requirement.parse(spec)
+
+    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, replace=False):
+        """Ensure self.location is on path
+
+        If replace=False (default):
+            - If location is already in path anywhere, do nothing.
+            - Else:
+              - If it's an egg and its parent directory is on path,
+                insert just ahead of the parent.
+              - Else: add to the end of path.
+        If replace=True:
+            - If location is already on path anywhere (not eggs)
+              or higher priority than its parent (eggs)
+              do nothing.
+            - Else:
+              - If it's an egg and its parent directory is on path,
+                insert just ahead of the parent,
+                removing any lower-priority entries.
+              - Else: add it to the front of path.
+        """
+
+        loc = loc or self.location
+        if not loc:
+            return
+
+        nloc = _normalize_cached(loc)
+        bdir = os.path.dirname(nloc)
+        npath = [(p and _normalize_cached(p) or p) for p in path]
+
+        for p, item in enumerate(npath):
+            if item == nloc:
+                if replace:
+                    break
+                else:
+                    # don't modify path (even removing duplicates) if
+                    # found and not replace
+                    return
+            elif item == bdir and self.precedence == EGG_DIST:
+                # if it's an .egg, give it precedence over its directory
+                # UNLESS it's already been added to sys.path and replace=False
+                if (not replace) and nloc in npath[p:]:
+                    return
+                if path is sys.path:
+                    self.check_version_conflict()
+                path.insert(p, loc)
+                npath.insert(p, nloc)
+                break
+        else:
+            if path is sys.path:
+                self.check_version_conflict()
+            if replace:
+                path.insert(0, loc)
+            else:
+                path.append(loc)
+            return
+
+        # p is the spot where we found or inserted loc; now remove duplicates
+        while True:
+            try:
+                np = npath.index(nloc, p + 1)
+            except ValueError:
+                break
+            else:
+                del npath[np], path[np]
+                # ha!
+                p = np
+
+        return
+
+    def check_version_conflict(self):
+        if self.key == 'setuptools':
+            # ignore the inevitable setuptools self-conflicts  :(
+            return
+
+        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"""
+        names = 'project_name version py_version platform location precedence'
+        for attr in names.split():
+            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]
+
+
+class EggInfoDistribution(Distribution):
+    def _reload_version(self):
+        """
+        Packages installed by distutils (e.g. numpy or scipy),
+        which uses an old safe_version, and so
+        their version numbers can get mangled when
+        converted to filenames (e.g., 1.11.0.dev0+2329eae to
+        1.11.0.dev0_2329eae). These distributions will not be
+        parsed properly
+        downstream by Distribution and safe_version, so
+        take an extra step and try to get the version number from
+        the metadata file itself instead of the filename.
+        """
+        md_version = _version_from_file(self._get_metadata(self.PKG_INFO))
+        if md_version:
+            self._version = md_version
+        return self
+
+
+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:
+            metadata = self.get_metadata(self.PKG_INFO)
+            self._pkg_info = email.parser.Parser().parsestr(metadata)
+            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 _compute_dependencies(self):
+        """Recompute this distribution's dependencies."""
+        dm = self.__dep_map = {None: []}
+
+        reqs = []
+        # Including any condition expressions
+        for req in self._parsed_pkg_info.get_all('Requires-Dist') or []:
+            reqs.extend(parse_requirements(req))
+
+        def reqs_for_extra(extra):
+            for req in reqs:
+                if not req.marker or req.marker.evaluate({'extra': extra}):
+                    yield req
+
+        common = frozenset(reqs_for_extra(None))
+        dm[None].extend(common)
+
+        for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []:
+            s_extra = safe_extra(extra.strip())
+            dm[s_extra] = list(frozenset(reqs_for_extra(extra)) - common)
+
+        return dm
+
+
+_distributionImpl = {
+    '.egg': Distribution,
+    '.egg-info': EggInfoDistribution,
+    '.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
+    warnings.warn(stacklevel=level + 1, *args, **kw)
+
+
+class RequirementParseError(ValueError):
+    def __str__(self):
+        return ' '.join(self.args)
+
+
+def parse_requirements(strs):
+    """Yield ``Requirement`` objects for each specification in `strs`
+
+    `strs` must be a string, or a (possibly-nested) iterable thereof.
+    """
+    # create a steppable iterator, so we can handle \-continuations
+    lines = iter(yield_lines(strs))
+
+    for line in lines:
+        # Drop comments -- a hash without a space may be in a URL.
+        if ' #' in line:
+            line = line[:line.find(' #')]
+        # If there is a line continuation, drop it, and append the next line.
+        if line.endswith('\\'):
+            line = line[:-2].strip()
+            try:
+                line += next(lines)
+            except StopIteration:
+                return
+        yield Requirement(line)
+
+
+class Requirement(packaging.requirements.Requirement):
+    def __init__(self, requirement_string):
+        """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!"""
+        try:
+            super(Requirement, self).__init__(requirement_string)
+        except packaging.requirements.InvalidRequirement as e:
+            raise RequirementParseError(str(e))
+        self.unsafe_name = self.name
+        project_name = safe_name(self.name)
+        self.project_name, self.key = project_name, project_name.lower()
+        self.specs = [
+            (spec.operator, spec.version) for spec in self.specifier]
+        self.extras = tuple(map(safe_extra, self.extras))
+        self.hashCmp = (
+            self.key,
+            self.specifier,
+            frozenset(self.extras),
+            str(self.marker) if self.marker else None,
+        )
+        self.__hash = hash(self.hashCmp)
+
+    def __eq__(self, other):
+        return (
+            isinstance(other, Requirement) and
+            self.hashCmp == other.hashCmp
+        )
+
+    def __ne__(self, other):
+        return not self == other
+
+    def __contains__(self, item):
+        if isinstance(item, Distribution):
+            if item.key != self.key:
+                return False
+
+            item = item.version
+
+        # Allow prereleases always in order to match the previous behavior of
+        # this method. In the future this should be smarter and follow PEP 440
+        # more accurately.
+        return self.specifier.contains(item, prereleases=True)
+
+    def __hash__(self):
+        return self.__hash
+
+    def __repr__(self):
+        return "Requirement.parse(%r)" % str(self)
+
+    @staticmethod
+    def parse(s):
+        req, = parse_requirements(s)
+        return req
+
+
+def _always_object(classes):
+    """
+    Ensure object appears in the mro even
+    for old-style classes.
+    """
+    if object not in classes:
+        return classes + (object,)
+    return classes
+
+
+def _find_adapter(registry, ob):
+    """Return an adapter factory for `ob` from `registry`"""
+    types = _always_object(inspect.getmro(getattr(ob, '__class__', type(ob))))
+    for t in types:
+        if t in registry:
+            return registry[t]
+
+
+def ensure_directory(path):
+    """Ensure that the parent directory of `path` exists"""
+    dirname = os.path.dirname(path)
+    py31compat.makedirs(dirname, exist_ok=True)
+
+
+def _bypass_ensure_directory(path):
+    """Sandbox-bypassing version of ensure_directory()"""
+    if not WRITE_SUPPORT:
+        raise IOError('"os.mkdir" not supported on this platform.')
+    dirname, filename = split(path)
+    if dirname and filename and not isdir(dirname):
+        _bypass_ensure_directory(dirname)
+        mkdir(dirname, 0o755)
+
+
+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):
+    old_open = os.open
+    try:
+        # temporarily bypass sandboxing
+        os.open = os_open
+        return tempfile.mkstemp(*args, **kw)
+    finally:
+        # and then put it back
+        os.open = old_open
+
+
+# Silence the PEP440Warning by default, so that end users don't get hit by it
+# randomly just because they use pkg_resources. We want to append the rule
+# because we want earlier uses of filterwarnings to take precedence over this
+# one.
+warnings.filterwarnings("ignore", category=PEP440Warning, append=True)
+
+
+# from jaraco.functools 1.3
+def _call_aside(f, *args, **kwargs):
+    f(*args, **kwargs)
+    return f
+
+
+@_call_aside
+def _initialize(g=globals()):
+    "Set up global resource manager (deliberately not state-saved)"
+    manager = ResourceManager()
+    g['_manager'] = manager
+    g.update(
+        (name, getattr(manager, name))
+        for name in dir(manager)
+        if not name.startswith('_')
+    )
+
+
+@_call_aside
+def _initialize_master_working_set():
+    """
+    Prepare the master working set and make the ``require()``
+    API available.
+
+    This function has explicit effects on the global state
+    of pkg_resources. It is intended to be invoked once at
+    the initialization of this module.
+
+    Invocation by other packages is unsupported and done
+    at their own risk.
+    """
+    working_set = WorkingSet._build_master()
+    _declare_state('object', working_set=working_set)
+
+    require = working_set.require
+    iter_entry_points = working_set.iter_entry_points
+    add_activation_listener = working_set.subscribe
+    run_script = working_set.run_script
+    # backward compatibility
+    run_main = run_script
+    # Activate all distributions already on sys.path with replace=False and
+    # ensure that all distributions added to the working set in the future
+    # (e.g. by calling ``require()``) will get activated as well,
+    # with higher priority (replace=True).
+    tuple(
+        dist.activate(replace=False)
+        for dist in working_set
+    )
+    add_activation_listener(
+        lambda dist: dist.activate(replace=True),
+        existing=False,
+    )
+    working_set.entries = []
+    # match order
+    list(map(working_set.add_entry, sys.path))
+    globals().update(locals())
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/__init__.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/appdirs.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/appdirs.py
new file mode 100644
index 00000000..f4dba095
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/appdirs.py
@@ -0,0 +1,552 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (c) 2005-2010 ActiveState Software Inc.
+# Copyright (c) 2013 Eddy Petrișor
+
+"""Utilities for determining application-specific dirs.
+
+See <http://github.com/ActiveState/appdirs> for details and usage.
+"""
+# Dev Notes:
+# - MSDN on where to store app data files:
+#   http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120
+# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html
+# - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+
+__version_info__ = (1, 4, 0)
+__version__ = '.'.join(map(str, __version_info__))
+
+
+import sys
+import os
+
+PY3 = sys.version_info[0] == 3
+
+if PY3:
+    unicode = str
+
+if sys.platform.startswith('java'):
+    import platform
+    os_name = platform.java_ver()[3][0]
+    if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc.
+        system = 'win32'
+    elif os_name.startswith('Mac'): # "Mac OS X", etc.
+        system = 'darwin'
+    else: # "Linux", "SunOS", "FreeBSD", etc.
+        # Setting this to "linux2" is not ideal, but only Windows or Mac
+        # are actually checked for and the rest of the module expects
+        # *sys.platform* style strings.
+        system = 'linux2'
+else:
+    system = sys.platform
+
+
+
+def user_data_dir(appname=None, appauthor=None, version=None, roaming=False):
+    r"""Return full path to the user-specific data dir for this application.
+
+        "appname" is the name of application.
+            If None, just the system directory is returned.
+        "appauthor" (only used on Windows) is the name of the
+            appauthor or distributing body for this application. Typically
+            it is the owning company name. This falls back to appname. You may
+            pass False to disable it.
+        "version" is an optional version path element to append to the
+            path. You might want to use this if you want multiple versions
+            of your app to be able to run independently. If used, this
+            would typically be "<major>.<minor>".
+            Only applied when appname is present.
+        "roaming" (boolean, default False) can be set True to use the Windows
+            roaming appdata directory. That means that for users on a Windows
+            network setup for roaming profiles, this user data will be
+            sync'd on login. See
+            <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>
+            for a discussion of issues.
+
+    Typical user data directories are:
+        Mac OS X:               ~/Library/Application Support/<AppName>
+        Unix:                   ~/.local/share/<AppName>    # or in $XDG_DATA_HOME, if defined
+        Win XP (not roaming):   C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName>
+        Win XP (roaming):       C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>
+        Win 7  (not roaming):   C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>
+        Win 7  (roaming):       C:\Users\<username>\AppData\Roaming\<AppAuthor>\<AppName>
+
+    For Unix, we follow the XDG spec and support $XDG_DATA_HOME.
+    That means, by default "~/.local/share/<AppName>".
+    """
+    if system == "win32":
+        if appauthor is None:
+            appauthor = appname
+        const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA"
+        path = os.path.normpath(_get_win_folder(const))
+        if appname:
+            if appauthor is not False:
+                path = os.path.join(path, appauthor, appname)
+            else:
+                path = os.path.join(path, appname)
+    elif system == 'darwin':
+        path = os.path.expanduser('~/Library/Application Support/')
+        if appname:
+            path = os.path.join(path, appname)
+    else:
+        path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share"))
+        if appname:
+            path = os.path.join(path, appname)
+    if appname and version:
+        path = os.path.join(path, version)
+    return path
+
+
+def site_data_dir(appname=None, appauthor=None, version=None, multipath=False):
+    """Return full path to the user-shared data dir for this application.
+
+        "appname" is the name of application.
+            If None, just the system directory is returned.
+        "appauthor" (only used on Windows) is the name of the
+            appauthor or distributing body for this application. Typically
+            it is the owning company name. This falls back to appname. You may
+            pass False to disable it.
+        "version" is an optional version path element to append to the
+            path. You might want to use this if you want multiple versions
+            of your app to be able to run independently. If used, this
+            would typically be "<major>.<minor>".
+            Only applied when appname is present.
+        "multipath" is an optional parameter only applicable to *nix
+            which indicates that the entire list of data dirs should be
+            returned. By default, the first item from XDG_DATA_DIRS is
+            returned, or '/usr/local/share/<AppName>',
+            if XDG_DATA_DIRS is not set
+
+    Typical user data directories are:
+        Mac OS X:   /Library/Application Support/<AppName>
+        Unix:       /usr/local/share/<AppName> or /usr/share/<AppName>
+        Win XP:     C:\Documents and Settings\All Users\Application Data\<AppAuthor>\<AppName>
+        Vista:      (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.)
+        Win 7:      C:\ProgramData\<AppAuthor>\<AppName>   # Hidden, but writeable on Win 7.
+
+    For Unix, this is using the $XDG_DATA_DIRS[0] default.
+
+    WARNING: Do not use this on Windows. See the Vista-Fail note above for why.
+    """
+    if system == "win32":
+        if appauthor is None:
+            appauthor = appname
+        path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA"))
+        if appname:
+            if appauthor is not False:
+                path = os.path.join(path, appauthor, appname)
+            else:
+                path = os.path.join(path, appname)
+    elif system == 'darwin':
+        path = os.path.expanduser('/Library/Application Support')
+        if appname:
+            path = os.path.join(path, appname)
+    else:
+        # XDG default for $XDG_DATA_DIRS
+        # only first, if multipath is False
+        path = os.getenv('XDG_DATA_DIRS',
+                         os.pathsep.join(['/usr/local/share', '/usr/share']))
+        pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)]
+        if appname:
+            if version:
+                appname = os.path.join(appname, version)
+            pathlist = [os.sep.join([x, appname]) for x in pathlist]
+
+        if multipath:
+            path = os.pathsep.join(pathlist)
+        else:
+            path = pathlist[0]
+        return path
+
+    if appname and version:
+        path = os.path.join(path, version)
+    return path
+
+
+def user_config_dir(appname=None, appauthor=None, version=None, roaming=False):
+    r"""Return full path to the user-specific config dir for this application.
+
+        "appname" is the name of application.
+            If None, just the system directory is returned.
+        "appauthor" (only used on Windows) is the name of the
+            appauthor or distributing body for this application. Typically
+            it is the owning company name. This falls back to appname. You may
+            pass False to disable it.
+        "version" is an optional version path element to append to the
+            path. You might want to use this if you want multiple versions
+            of your app to be able to run independently. If used, this
+            would typically be "<major>.<minor>".
+            Only applied when appname is present.
+        "roaming" (boolean, default False) can be set True to use the Windows
+            roaming appdata directory. That means that for users on a Windows
+            network setup for roaming profiles, this user data will be
+            sync'd on login. See
+            <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>
+            for a discussion of issues.
+
+    Typical user data directories are:
+        Mac OS X:               same as user_data_dir
+        Unix:                   ~/.config/<AppName>     # or in $XDG_CONFIG_HOME, if defined
+        Win *:                  same as user_data_dir
+
+    For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME.
+    That means, by deafult "~/.config/<AppName>".
+    """
+    if system in ["win32", "darwin"]:
+        path = user_data_dir(appname, appauthor, None, roaming)
+    else:
+        path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config"))
+        if appname:
+            path = os.path.join(path, appname)
+    if appname and version:
+        path = os.path.join(path, version)
+    return path
+
+
+def site_config_dir(appname=None, appauthor=None, version=None, multipath=False):
+    """Return full path to the user-shared data dir for this application.
+
+        "appname" is the name of application.
+            If None, just the system directory is returned.
+        "appauthor" (only used on Windows) is the name of the
+            appauthor or distributing body for this application. Typically
+            it is the owning company name. This falls back to appname. You may
+            pass False to disable it.
+        "version" is an optional version path element to append to the
+            path. You might want to use this if you want multiple versions
+            of your app to be able to run independently. If used, this
+            would typically be "<major>.<minor>".
+            Only applied when appname is present.
+        "multipath" is an optional parameter only applicable to *nix
+            which indicates that the entire list of config dirs should be
+            returned. By default, the first item from XDG_CONFIG_DIRS is
+            returned, or '/etc/xdg/<AppName>', if XDG_CONFIG_DIRS is not set
+
+    Typical user data directories are:
+        Mac OS X:   same as site_data_dir
+        Unix:       /etc/xdg/<AppName> or $XDG_CONFIG_DIRS[i]/<AppName> for each value in
+                    $XDG_CONFIG_DIRS
+        Win *:      same as site_data_dir
+        Vista:      (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.)
+
+    For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False
+
+    WARNING: Do not use this on Windows. See the Vista-Fail note above for why.
+    """
+    if system in ["win32", "darwin"]:
+        path = site_data_dir(appname, appauthor)
+        if appname and version:
+            path = os.path.join(path, version)
+    else:
+        # XDG default for $XDG_CONFIG_DIRS
+        # only first, if multipath is False
+        path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg')
+        pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)]
+        if appname:
+            if version:
+                appname = os.path.join(appname, version)
+            pathlist = [os.sep.join([x, appname]) for x in pathlist]
+
+        if multipath:
+            path = os.pathsep.join(pathlist)
+        else:
+            path = pathlist[0]
+    return path
+
+
+def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True):
+    r"""Return full path to the user-specific cache dir for this application.
+
+        "appname" is the name of application.
+            If None, just the system directory is returned.
+        "appauthor" (only used on Windows) is the name of the
+            appauthor or distributing body for this application. Typically
+            it is the owning company name. This falls back to appname. You may
+            pass False to disable it.
+        "version" is an optional version path element to append to the
+            path. You might want to use this if you want multiple versions
+            of your app to be able to run independently. If used, this
+            would typically be "<major>.<minor>".
+            Only applied when appname is present.
+        "opinion" (boolean) can be False to disable the appending of
+            "Cache" to the base app data dir for Windows. See
+            discussion below.
+
+    Typical user cache directories are:
+        Mac OS X:   ~/Library/Caches/<AppName>
+        Unix:       ~/.cache/<AppName> (XDG default)
+        Win XP:     C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Cache
+        Vista:      C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Cache
+
+    On Windows the only suggestion in the MSDN docs is that local settings go in
+    the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming
+    app data dir (the default returned by `user_data_dir` above). Apps typically
+    put cache data somewhere *under* the given dir here. Some examples:
+        ...\Mozilla\Firefox\Profiles\<ProfileName>\Cache
+        ...\Acme\SuperApp\Cache\1.0
+    OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value.
+    This can be disabled with the `opinion=False` option.
+    """
+    if system == "win32":
+        if appauthor is None:
+            appauthor = appname
+        path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA"))
+        if appname:
+            if appauthor is not False:
+                path = os.path.join(path, appauthor, appname)
+            else:
+                path = os.path.join(path, appname)
+            if opinion:
+                path = os.path.join(path, "Cache")
+    elif system == 'darwin':
+        path = os.path.expanduser('~/Library/Caches')
+        if appname:
+            path = os.path.join(path, appname)
+    else:
+        path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache'))
+        if appname:
+            path = os.path.join(path, appname)
+    if appname and version:
+        path = os.path.join(path, version)
+    return path
+
+
+def user_log_dir(appname=None, appauthor=None, version=None, opinion=True):
+    r"""Return full path to the user-specific log dir for this application.
+
+        "appname" is the name of application.
+            If None, just the system directory is returned.
+        "appauthor" (only used on Windows) is the name of the
+            appauthor or distributing body for this application. Typically
+            it is the owning company name. This falls back to appname. You may
+            pass False to disable it.
+        "version" is an optional version path element to append to the
+            path. You might want to use this if you want multiple versions
+            of your app to be able to run independently. If used, this
+            would typically be "<major>.<minor>".
+            Only applied when appname is present.
+        "opinion" (boolean) can be False to disable the appending of
+            "Logs" to the base app data dir for Windows, and "log" to the
+            base cache dir for Unix. See discussion below.
+
+    Typical user cache directories are:
+        Mac OS X:   ~/Library/Logs/<AppName>
+        Unix:       ~/.cache/<AppName>/log  # or under $XDG_CACHE_HOME if defined
+        Win XP:     C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Logs
+        Vista:      C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Logs
+
+    On Windows the only suggestion in the MSDN docs is that local settings
+    go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in
+    examples of what some windows apps use for a logs dir.)
+
+    OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA`
+    value for Windows and appends "log" to the user cache dir for Unix.
+    This can be disabled with the `opinion=False` option.
+    """
+    if system == "darwin":
+        path = os.path.join(
+            os.path.expanduser('~/Library/Logs'),
+            appname)
+    elif system == "win32":
+        path = user_data_dir(appname, appauthor, version)
+        version = False
+        if opinion:
+            path = os.path.join(path, "Logs")
+    else:
+        path = user_cache_dir(appname, appauthor, version)
+        version = False
+        if opinion:
+            path = os.path.join(path, "log")
+    if appname and version:
+        path = os.path.join(path, version)
+    return path
+
+
+class AppDirs(object):
+    """Convenience wrapper for getting application dirs."""
+    def __init__(self, appname, appauthor=None, version=None, roaming=False,
+                 multipath=False):
+        self.appname = appname
+        self.appauthor = appauthor
+        self.version = version
+        self.roaming = roaming
+        self.multipath = multipath
+
+    @property
+    def user_data_dir(self):
+        return user_data_dir(self.appname, self.appauthor,
+                             version=self.version, roaming=self.roaming)
+
+    @property
+    def site_data_dir(self):
+        return site_data_dir(self.appname, self.appauthor,
+                             version=self.version, multipath=self.multipath)
+
+    @property
+    def user_config_dir(self):
+        return user_config_dir(self.appname, self.appauthor,
+                               version=self.version, roaming=self.roaming)
+
+    @property
+    def site_config_dir(self):
+        return site_config_dir(self.appname, self.appauthor,
+                             version=self.version, multipath=self.multipath)
+
+    @property
+    def user_cache_dir(self):
+        return user_cache_dir(self.appname, self.appauthor,
+                              version=self.version)
+
+    @property
+    def user_log_dir(self):
+        return user_log_dir(self.appname, self.appauthor,
+                            version=self.version)
+
+
+#---- internal support stuff
+
+def _get_win_folder_from_registry(csidl_name):
+    """This is a fallback technique at best. I'm not sure if using the
+    registry for this guarantees us the correct answer for all CSIDL_*
+    names.
+    """
+    import _winreg
+
+    shell_folder_name = {
+        "CSIDL_APPDATA": "AppData",
+        "CSIDL_COMMON_APPDATA": "Common AppData",
+        "CSIDL_LOCAL_APPDATA": "Local AppData",
+    }[csidl_name]
+
+    key = _winreg.OpenKey(
+        _winreg.HKEY_CURRENT_USER,
+        r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
+    )
+    dir, type = _winreg.QueryValueEx(key, shell_folder_name)
+    return dir
+
+
+def _get_win_folder_with_pywin32(csidl_name):
+    from win32com.shell import shellcon, shell
+    dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0)
+    # Try to make this a unicode path because SHGetFolderPath does
+    # not return unicode strings when there is unicode data in the
+    # path.
+    try:
+        dir = unicode(dir)
+
+        # Downgrade to short path name if have highbit chars. See
+        # <http://bugs.activestate.com/show_bug.cgi?id=85099>.
+        has_high_char = False
+        for c in dir:
+            if ord(c) > 255:
+                has_high_char = True
+                break
+        if has_high_char:
+            try:
+                import win32api
+                dir = win32api.GetShortPathName(dir)
+            except ImportError:
+                pass
+    except UnicodeError:
+        pass
+    return dir
+
+
+def _get_win_folder_with_ctypes(csidl_name):
+    import ctypes
+
+    csidl_const = {
+        "CSIDL_APPDATA": 26,
+        "CSIDL_COMMON_APPDATA": 35,
+        "CSIDL_LOCAL_APPDATA": 28,
+    }[csidl_name]
+
+    buf = ctypes.create_unicode_buffer(1024)
+    ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf)
+
+    # Downgrade to short path name if have highbit chars. See
+    # <http://bugs.activestate.com/show_bug.cgi?id=85099>.
+    has_high_char = False
+    for c in buf:
+        if ord(c) > 255:
+            has_high_char = True
+            break
+    if has_high_char:
+        buf2 = ctypes.create_unicode_buffer(1024)
+        if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024):
+            buf = buf2
+
+    return buf.value
+
+def _get_win_folder_with_jna(csidl_name):
+    import array
+    from com.sun import jna
+    from com.sun.jna.platform import win32
+
+    buf_size = win32.WinDef.MAX_PATH * 2
+    buf = array.zeros('c', buf_size)
+    shell = win32.Shell32.INSTANCE
+    shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf)
+    dir = jna.Native.toString(buf.tostring()).rstrip("\0")
+
+    # Downgrade to short path name if have highbit chars. See
+    # <http://bugs.activestate.com/show_bug.cgi?id=85099>.
+    has_high_char = False
+    for c in dir:
+        if ord(c) > 255:
+            has_high_char = True
+            break
+    if has_high_char:
+        buf = array.zeros('c', buf_size)
+        kernel = win32.Kernel32.INSTANCE
+        if kernal.GetShortPathName(dir, buf, buf_size):
+            dir = jna.Native.toString(buf.tostring()).rstrip("\0")
+
+    return dir
+
+if system == "win32":
+    try:
+        import win32com.shell
+        _get_win_folder = _get_win_folder_with_pywin32
+    except ImportError:
+        try:
+            from ctypes import windll
+            _get_win_folder = _get_win_folder_with_ctypes
+        except ImportError:
+            try:
+                import com.sun.jna
+                _get_win_folder = _get_win_folder_with_jna
+            except ImportError:
+                _get_win_folder = _get_win_folder_from_registry
+
+
+#---- self test code
+
+if __name__ == "__main__":
+    appname = "MyApp"
+    appauthor = "MyCompany"
+
+    props = ("user_data_dir", "site_data_dir",
+             "user_config_dir", "site_config_dir",
+             "user_cache_dir", "user_log_dir")
+
+    print("-- app dirs (with optional 'version')")
+    dirs = AppDirs(appname, appauthor, version="1.0")
+    for prop in props:
+        print("%s: %s" % (prop, getattr(dirs, prop)))
+
+    print("\n-- app dirs (without optional 'version')")
+    dirs = AppDirs(appname, appauthor)
+    for prop in props:
+        print("%s: %s" % (prop, getattr(dirs, prop)))
+
+    print("\n-- app dirs (without optional 'appauthor')")
+    dirs = AppDirs(appname)
+    for prop in props:
+        print("%s: %s" % (prop, getattr(dirs, prop)))
+
+    print("\n-- app dirs (with disabled 'appauthor')")
+    dirs = AppDirs(appname, appauthor=False)
+    for prop in props:
+        print("%s: %s" % (prop, getattr(dirs, prop)))
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/__about__.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/__about__.py
new file mode 100644
index 00000000..95d330ef
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/__about__.py
@@ -0,0 +1,21 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+__all__ = [
+    "__title__", "__summary__", "__uri__", "__version__", "__author__",
+    "__email__", "__license__", "__copyright__",
+]
+
+__title__ = "packaging"
+__summary__ = "Core utilities for Python packages"
+__uri__ = "https://github.com/pypa/packaging"
+
+__version__ = "16.8"
+
+__author__ = "Donald Stufft and individual contributors"
+__email__ = "donald@stufft.io"
+
+__license__ = "BSD or Apache License, Version 2.0"
+__copyright__ = "Copyright 2014-2016 %s" % __author__
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/__init__.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/__init__.py
new file mode 100644
index 00000000..5ee62202
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/__init__.py
@@ -0,0 +1,14 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+from .__about__ import (
+    __author__, __copyright__, __email__, __license__, __summary__, __title__,
+    __uri__, __version__
+)
+
+__all__ = [
+    "__title__", "__summary__", "__uri__", "__version__", "__author__",
+    "__email__", "__license__", "__copyright__",
+]
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/_compat.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/_compat.py
new file mode 100644
index 00000000..210bb80b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/_compat.py
@@ -0,0 +1,30 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import sys
+
+
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
+
+# flake8: noqa
+
+if PY3:
+    string_types = str,
+else:
+    string_types = basestring,
+
+
+def with_metaclass(meta, *bases):
+    """
+    Create a base class with a metaclass.
+    """
+    # This requires a bit of explanation: the basic idea is to make a dummy
+    # metaclass for one level of class instantiation that replaces itself with
+    # the actual metaclass.
+    class metaclass(meta):
+        def __new__(cls, name, this_bases, d):
+            return meta(name, bases, d)
+    return type.__new__(metaclass, 'temporary_class', (), {})
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/_structures.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/_structures.py
new file mode 100644
index 00000000..ccc27861
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/_structures.py
@@ -0,0 +1,68 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+
+class Infinity(object):
+
+    def __repr__(self):
+        return "Infinity"
+
+    def __hash__(self):
+        return hash(repr(self))
+
+    def __lt__(self, other):
+        return False
+
+    def __le__(self, other):
+        return False
+
+    def __eq__(self, other):
+        return isinstance(other, self.__class__)
+
+    def __ne__(self, other):
+        return not isinstance(other, self.__class__)
+
+    def __gt__(self, other):
+        return True
+
+    def __ge__(self, other):
+        return True
+
+    def __neg__(self):
+        return NegativeInfinity
+
+Infinity = Infinity()
+
+
+class NegativeInfinity(object):
+
+    def __repr__(self):
+        return "-Infinity"
+
+    def __hash__(self):
+        return hash(repr(self))
+
+    def __lt__(self, other):
+        return True
+
+    def __le__(self, other):
+        return True
+
+    def __eq__(self, other):
+        return isinstance(other, self.__class__)
+
+    def __ne__(self, other):
+        return not isinstance(other, self.__class__)
+
+    def __gt__(self, other):
+        return False
+
+    def __ge__(self, other):
+        return False
+
+    def __neg__(self):
+        return Infinity
+
+NegativeInfinity = NegativeInfinity()
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/markers.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/markers.py
new file mode 100644
index 00000000..892e578e
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/markers.py
@@ -0,0 +1,301 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import operator
+import os
+import platform
+import sys
+
+from pkg_resources.extern.pyparsing import ParseException, ParseResults, stringStart, stringEnd
+from pkg_resources.extern.pyparsing import ZeroOrMore, Group, Forward, QuotedString
+from pkg_resources.extern.pyparsing import Literal as L  # noqa
+
+from ._compat import string_types
+from .specifiers import Specifier, InvalidSpecifier
+
+
+__all__ = [
+    "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName",
+    "Marker", "default_environment",
+]
+
+
+class InvalidMarker(ValueError):
+    """
+    An invalid marker was found, users should refer to PEP 508.
+    """
+
+
+class UndefinedComparison(ValueError):
+    """
+    An invalid operation was attempted on a value that doesn't support it.
+    """
+
+
+class UndefinedEnvironmentName(ValueError):
+    """
+    A name was attempted to be used that does not exist inside of the
+    environment.
+    """
+
+
+class Node(object):
+
+    def __init__(self, value):
+        self.value = value
+
+    def __str__(self):
+        return str(self.value)
+
+    def __repr__(self):
+        return "<{0}({1!r})>".format(self.__class__.__name__, str(self))
+
+    def serialize(self):
+        raise NotImplementedError
+
+
+class Variable(Node):
+
+    def serialize(self):
+        return str(self)
+
+
+class Value(Node):
+
+    def serialize(self):
+        return '"{0}"'.format(self)
+
+
+class Op(Node):
+
+    def serialize(self):
+        return str(self)
+
+
+VARIABLE = (
+    L("implementation_version") |
+    L("platform_python_implementation") |
+    L("implementation_name") |
+    L("python_full_version") |
+    L("platform_release") |
+    L("platform_version") |
+    L("platform_machine") |
+    L("platform_system") |
+    L("python_version") |
+    L("sys_platform") |
+    L("os_name") |
+    L("os.name") |  # PEP-345
+    L("sys.platform") |  # PEP-345
+    L("platform.version") |  # PEP-345
+    L("platform.machine") |  # PEP-345
+    L("platform.python_implementation") |  # PEP-345
+    L("python_implementation") |  # undocumented setuptools legacy
+    L("extra")
+)
+ALIASES = {
+    'os.name': 'os_name',
+    'sys.platform': 'sys_platform',
+    'platform.version': 'platform_version',
+    'platform.machine': 'platform_machine',
+    'platform.python_implementation': 'platform_python_implementation',
+    'python_implementation': 'platform_python_implementation'
+}
+VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0])))
+
+VERSION_CMP = (
+    L("===") |
+    L("==") |
+    L(">=") |
+    L("<=") |
+    L("!=") |
+    L("~=") |
+    L(">") |
+    L("<")
+)
+
+MARKER_OP = VERSION_CMP | L("not in") | L("in")
+MARKER_OP.setParseAction(lambda s, l, t: Op(t[0]))
+
+MARKER_VALUE = QuotedString("'") | QuotedString('"')
+MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0]))
+
+BOOLOP = L("and") | L("or")
+
+MARKER_VAR = VARIABLE | MARKER_VALUE
+
+MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR)
+MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0]))
+
+LPAREN = L("(").suppress()
+RPAREN = L(")").suppress()
+
+MARKER_EXPR = Forward()
+MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN)
+MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR)
+
+MARKER = stringStart + MARKER_EXPR + stringEnd
+
+
+def _coerce_parse_result(results):
+    if isinstance(results, ParseResults):
+        return [_coerce_parse_result(i) for i in results]
+    else:
+        return results
+
+
+def _format_marker(marker, first=True):
+    assert isinstance(marker, (list, tuple, string_types))
+
+    # Sometimes we have a structure like [[...]] which is a single item list
+    # where the single item is itself it's own list. In that case we want skip
+    # the rest of this function so that we don't get extraneous () on the
+    # outside.
+    if (isinstance(marker, list) and len(marker) == 1 and
+            isinstance(marker[0], (list, tuple))):
+        return _format_marker(marker[0])
+
+    if isinstance(marker, list):
+        inner = (_format_marker(m, first=False) for m in marker)
+        if first:
+            return " ".join(inner)
+        else:
+            return "(" + " ".join(inner) + ")"
+    elif isinstance(marker, tuple):
+        return " ".join([m.serialize() for m in marker])
+    else:
+        return marker
+
+
+_operators = {
+    "in": lambda lhs, rhs: lhs in rhs,
+    "not in": lambda lhs, rhs: lhs not in rhs,
+    "<": operator.lt,
+    "<=": operator.le,
+    "==": operator.eq,
+    "!=": operator.ne,
+    ">=": operator.ge,
+    ">": operator.gt,
+}
+
+
+def _eval_op(lhs, op, rhs):
+    try:
+        spec = Specifier("".join([op.serialize(), rhs]))
+    except InvalidSpecifier:
+        pass
+    else:
+        return spec.contains(lhs)
+
+    oper = _operators.get(op.serialize())
+    if oper is None:
+        raise UndefinedComparison(
+            "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs)
+        )
+
+    return oper(lhs, rhs)
+
+
+_undefined = object()
+
+
+def _get_env(environment, name):
+    value = environment.get(name, _undefined)
+
+    if value is _undefined:
+        raise UndefinedEnvironmentName(
+            "{0!r} does not exist in evaluation environment.".format(name)
+        )
+
+    return value
+
+
+def _evaluate_markers(markers, environment):
+    groups = [[]]
+
+    for marker in markers:
+        assert isinstance(marker, (list, tuple, string_types))
+
+        if isinstance(marker, list):
+            groups[-1].append(_evaluate_markers(marker, environment))
+        elif isinstance(marker, tuple):
+            lhs, op, rhs = marker
+
+            if isinstance(lhs, Variable):
+                lhs_value = _get_env(environment, lhs.value)
+                rhs_value = rhs.value
+            else:
+                lhs_value = lhs.value
+                rhs_value = _get_env(environment, rhs.value)
+
+            groups[-1].append(_eval_op(lhs_value, op, rhs_value))
+        else:
+            assert marker in ["and", "or"]
+            if marker == "or":
+                groups.append([])
+
+    return any(all(item) for item in groups)
+
+
+def format_full_version(info):
+    version = '{0.major}.{0.minor}.{0.micro}'.format(info)
+    kind = info.releaselevel
+    if kind != 'final':
+        version += kind[0] + str(info.serial)
+    return version
+
+
+def default_environment():
+    if hasattr(sys, 'implementation'):
+        iver = format_full_version(sys.implementation.version)
+        implementation_name = sys.implementation.name
+    else:
+        iver = '0'
+        implementation_name = ''
+
+    return {
+        "implementation_name": implementation_name,
+        "implementation_version": iver,
+        "os_name": os.name,
+        "platform_machine": platform.machine(),
+        "platform_release": platform.release(),
+        "platform_system": platform.system(),
+        "platform_version": platform.version(),
+        "python_full_version": platform.python_version(),
+        "platform_python_implementation": platform.python_implementation(),
+        "python_version": platform.python_version()[:3],
+        "sys_platform": sys.platform,
+    }
+
+
+class Marker(object):
+
+    def __init__(self, marker):
+        try:
+            self._markers = _coerce_parse_result(MARKER.parseString(marker))
+        except ParseException as e:
+            err_str = "Invalid marker: {0!r}, parse error at {1!r}".format(
+                marker, marker[e.loc:e.loc + 8])
+            raise InvalidMarker(err_str)
+
+    def __str__(self):
+        return _format_marker(self._markers)
+
+    def __repr__(self):
+        return "<Marker({0!r})>".format(str(self))
+
+    def evaluate(self, environment=None):
+        """Evaluate a marker.
+
+        Return the boolean from evaluating the given marker against the
+        environment. environment is an optional argument to override all or
+        part of the determined environment.
+
+        The environment is determined from the current Python process.
+        """
+        current_environment = default_environment()
+        if environment is not None:
+            current_environment.update(environment)
+
+        return _evaluate_markers(self._markers, current_environment)
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/requirements.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/requirements.py
new file mode 100644
index 00000000..0c8c4a38
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/requirements.py
@@ -0,0 +1,127 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import string
+import re
+
+from pkg_resources.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException
+from pkg_resources.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine
+from pkg_resources.extern.pyparsing import Literal as L  # noqa
+from pkg_resources.extern.six.moves.urllib import parse as urlparse
+
+from .markers import MARKER_EXPR, Marker
+from .specifiers import LegacySpecifier, Specifier, SpecifierSet
+
+
+class InvalidRequirement(ValueError):
+    """
+    An invalid requirement was found, users should refer to PEP 508.
+    """
+
+
+ALPHANUM = Word(string.ascii_letters + string.digits)
+
+LBRACKET = L("[").suppress()
+RBRACKET = L("]").suppress()
+LPAREN = L("(").suppress()
+RPAREN = L(")").suppress()
+COMMA = L(",").suppress()
+SEMICOLON = L(";").suppress()
+AT = L("@").suppress()
+
+PUNCTUATION = Word("-_.")
+IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM)
+IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END))
+
+NAME = IDENTIFIER("name")
+EXTRA = IDENTIFIER
+
+URI = Regex(r'[^ ]+')("url")
+URL = (AT + URI)
+
+EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA)
+EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras")
+
+VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE)
+VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE)
+
+VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY
+VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE),
+                       joinString=",", adjacent=False)("_raw_spec")
+_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY))
+_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '')
+
+VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier")
+VERSION_SPEC.setParseAction(lambda s, l, t: t[1])
+
+MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker")
+MARKER_EXPR.setParseAction(
+    lambda s, l, t: Marker(s[t._original_start:t._original_end])
+)
+MARKER_SEPERATOR = SEMICOLON
+MARKER = MARKER_SEPERATOR + MARKER_EXPR
+
+VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER)
+URL_AND_MARKER = URL + Optional(MARKER)
+
+NAMED_REQUIREMENT = \
+    NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER)
+
+REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd
+
+
+class Requirement(object):
+    """Parse a requirement.
+
+    Parse a given requirement string into its parts, such as name, specifier,
+    URL, and extras. Raises InvalidRequirement on a badly-formed requirement
+    string.
+    """
+
+    # TODO: Can we test whether something is contained within a requirement?
+    #       If so how do we do that? Do we need to test against the _name_ of
+    #       the thing as well as the version? What about the markers?
+    # TODO: Can we normalize the name and extra name?
+
+    def __init__(self, requirement_string):
+        try:
+            req = REQUIREMENT.parseString(requirement_string)
+        except ParseException as e:
+            raise InvalidRequirement(
+                "Invalid requirement, parse error at \"{0!r}\"".format(
+                    requirement_string[e.loc:e.loc + 8]))
+
+        self.name = req.name
+        if req.url:
+            parsed_url = urlparse.urlparse(req.url)
+            if not (parsed_url.scheme and parsed_url.netloc) or (
+                    not parsed_url.scheme and not parsed_url.netloc):
+                raise InvalidRequirement("Invalid URL given")
+            self.url = req.url
+        else:
+            self.url = None
+        self.extras = set(req.extras.asList() if req.extras else [])
+        self.specifier = SpecifierSet(req.specifier)
+        self.marker = req.marker if req.marker else None
+
+    def __str__(self):
+        parts = [self.name]
+
+        if self.extras:
+            parts.append("[{0}]".format(",".join(sorted(self.extras))))
+
+        if self.specifier:
+            parts.append(str(self.specifier))
+
+        if self.url:
+            parts.append("@ {0}".format(self.url))
+
+        if self.marker:
+            parts.append("; {0}".format(self.marker))
+
+        return "".join(parts)
+
+    def __repr__(self):
+        return "<Requirement({0!r})>".format(str(self))
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/specifiers.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/specifiers.py
new file mode 100644
index 00000000..7f5a76cf
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/specifiers.py
@@ -0,0 +1,774 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import abc
+import functools
+import itertools
+import re
+
+from ._compat import string_types, with_metaclass
+from .version import Version, LegacyVersion, parse
+
+
+class InvalidSpecifier(ValueError):
+    """
+    An invalid specifier was found, users should refer to PEP 440.
+    """
+
+
+class BaseSpecifier(with_metaclass(abc.ABCMeta, object)):
+
+    @abc.abstractmethod
+    def __str__(self):
+        """
+        Returns the str representation of this Specifier like object. This
+        should be representative of the Specifier itself.
+        """
+
+    @abc.abstractmethod
+    def __hash__(self):
+        """
+        Returns a hash value for this Specifier like object.
+        """
+
+    @abc.abstractmethod
+    def __eq__(self, other):
+        """
+        Returns a boolean representing whether or not the two Specifier like
+        objects are equal.
+        """
+
+    @abc.abstractmethod
+    def __ne__(self, other):
+        """
+        Returns a boolean representing whether or not the two Specifier like
+        objects are not equal.
+        """
+
+    @abc.abstractproperty
+    def prereleases(self):
+        """
+        Returns whether or not pre-releases as a whole are allowed by this
+        specifier.
+        """
+
+    @prereleases.setter
+    def prereleases(self, value):
+        """
+        Sets whether or not pre-releases as a whole are allowed by this
+        specifier.
+        """
+
+    @abc.abstractmethod
+    def contains(self, item, prereleases=None):
+        """
+        Determines if the given item is contained within this specifier.
+        """
+
+    @abc.abstractmethod
+    def filter(self, iterable, prereleases=None):
+        """
+        Takes an iterable of items and filters them so that only items which
+        are contained within this specifier are allowed in it.
+        """
+
+
+class _IndividualSpecifier(BaseSpecifier):
+
+    _operators = {}
+
+    def __init__(self, spec="", prereleases=None):
+        match = self._regex.search(spec)
+        if not match:
+            raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec))
+
+        self._spec = (
+            match.group("operator").strip(),
+            match.group("version").strip(),
+        )
+
+        # Store whether or not this Specifier should accept prereleases
+        self._prereleases = prereleases
+
+    def __repr__(self):
+        pre = (
+            ", prereleases={0!r}".format(self.prereleases)
+            if self._prereleases is not None
+            else ""
+        )
+
+        return "<{0}({1!r}{2})>".format(
+            self.__class__.__name__,
+            str(self),
+            pre,
+        )
+
+    def __str__(self):
+        return "{0}{1}".format(*self._spec)
+
+    def __hash__(self):
+        return hash(self._spec)
+
+    def __eq__(self, other):
+        if isinstance(other, string_types):
+            try:
+                other = self.__class__(other)
+            except InvalidSpecifier:
+                return NotImplemented
+        elif not isinstance(other, self.__class__):
+            return NotImplemented
+
+        return self._spec == other._spec
+
+    def __ne__(self, other):
+        if isinstance(other, string_types):
+            try:
+                other = self.__class__(other)
+            except InvalidSpecifier:
+                return NotImplemented
+        elif not isinstance(other, self.__class__):
+            return NotImplemented
+
+        return self._spec != other._spec
+
+    def _get_operator(self, op):
+        return getattr(self, "_compare_{0}".format(self._operators[op]))
+
+    def _coerce_version(self, version):
+        if not isinstance(version, (LegacyVersion, Version)):
+            version = parse(version)
+        return version
+
+    @property
+    def operator(self):
+        return self._spec[0]
+
+    @property
+    def version(self):
+        return self._spec[1]
+
+    @property
+    def prereleases(self):
+        return self._prereleases
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+    def __contains__(self, item):
+        return self.contains(item)
+
+    def contains(self, item, prereleases=None):
+        # Determine if prereleases are to be allowed or not.
+        if prereleases is None:
+            prereleases = self.prereleases
+
+        # Normalize item to a Version or LegacyVersion, this allows us to have
+        # a shortcut for ``"2.0" in Specifier(">=2")
+        item = self._coerce_version(item)
+
+        # Determine if we should be supporting prereleases in this specifier
+        # or not, if we do not support prereleases than we can short circuit
+        # logic if this version is a prereleases.
+        if item.is_prerelease and not prereleases:
+            return False
+
+        # Actually do the comparison to determine if this item is contained
+        # within this Specifier or not.
+        return self._get_operator(self.operator)(item, self.version)
+
+    def filter(self, iterable, prereleases=None):
+        yielded = False
+        found_prereleases = []
+
+        kw = {"prereleases": prereleases if prereleases is not None else True}
+
+        # Attempt to iterate over all the values in the iterable and if any of
+        # them match, yield them.
+        for version in iterable:
+            parsed_version = self._coerce_version(version)
+
+            if self.contains(parsed_version, **kw):
+                # If our version is a prerelease, and we were not set to allow
+                # prereleases, then we'll store it for later incase nothing
+                # else matches this specifier.
+                if (parsed_version.is_prerelease and not
+                        (prereleases or self.prereleases)):
+                    found_prereleases.append(version)
+                # Either this is not a prerelease, or we should have been
+                # accepting prereleases from the begining.
+                else:
+                    yielded = True
+                    yield version
+
+        # Now that we've iterated over everything, determine if we've yielded
+        # any values, and if we have not and we have any prereleases stored up
+        # then we will go ahead and yield the prereleases.
+        if not yielded and found_prereleases:
+            for version in found_prereleases:
+                yield version
+
+
+class LegacySpecifier(_IndividualSpecifier):
+
+    _regex_str = (
+        r"""
+        (?P<operator>(==|!=|<=|>=|<|>))
+        \s*
+        (?P<version>
+            [^,;\s)]* # Since this is a "legacy" specifier, and the version
+                      # string can be just about anything, we match everything
+                      # except for whitespace, a semi-colon for marker support,
+                      # a closing paren since versions can be enclosed in
+                      # them, and a comma since it's a version separator.
+        )
+        """
+    )
+
+    _regex = re.compile(
+        r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
+
+    _operators = {
+        "==": "equal",
+        "!=": "not_equal",
+        "<=": "less_than_equal",
+        ">=": "greater_than_equal",
+        "<": "less_than",
+        ">": "greater_than",
+    }
+
+    def _coerce_version(self, version):
+        if not isinstance(version, LegacyVersion):
+            version = LegacyVersion(str(version))
+        return version
+
+    def _compare_equal(self, prospective, spec):
+        return prospective == self._coerce_version(spec)
+
+    def _compare_not_equal(self, prospective, spec):
+        return prospective != self._coerce_version(spec)
+
+    def _compare_less_than_equal(self, prospective, spec):
+        return prospective <= self._coerce_version(spec)
+
+    def _compare_greater_than_equal(self, prospective, spec):
+        return prospective >= self._coerce_version(spec)
+
+    def _compare_less_than(self, prospective, spec):
+        return prospective < self._coerce_version(spec)
+
+    def _compare_greater_than(self, prospective, spec):
+        return prospective > self._coerce_version(spec)
+
+
+def _require_version_compare(fn):
+    @functools.wraps(fn)
+    def wrapped(self, prospective, spec):
+        if not isinstance(prospective, Version):
+            return False
+        return fn(self, prospective, spec)
+    return wrapped
+
+
+class Specifier(_IndividualSpecifier):
+
+    _regex_str = (
+        r"""
+        (?P<operator>(~=|==|!=|<=|>=|<|>|===))
+        (?P<version>
+            (?:
+                # The identity operators allow for an escape hatch that will
+                # do an exact string match of the version you wish to install.
+                # This will not be parsed by PEP 440 and we cannot determine
+                # any semantic meaning from it. This operator is discouraged
+                # but included entirely as an escape hatch.
+                (?<====)  # Only match for the identity operator
+                \s*
+                [^\s]*    # We just match everything, except for whitespace
+                          # since we are only testing for strict identity.
+            )
+            |
+            (?:
+                # The (non)equality operators allow for wild card and local
+                # versions to be specified so we have to define these two
+                # operators separately to enable that.
+                (?<===|!=)            # Only match for equals and not equals
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)*   # release
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+
+                # You cannot use a wild card and a dev or local version
+                # together so group them with a | and make them optional.
+                (?:
+                    (?:[-_\.]?dev[-_\.]?[0-9]*)?         # dev release
+                    (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local
+                    |
+                    \.\*  # Wild card syntax of .*
+                )?
+            )
+            |
+            (?:
+                # The compatible operator requires at least two digits in the
+                # release segment.
+                (?<=~=)               # Only match for the compatible operator
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)+   # release  (We have a + instead of a *)
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
+            )
+            |
+            (?:
+                # All other operators only allow a sub set of what the
+                # (non)equality operators do. Specifically they do not allow
+                # local versions to be specified nor do they allow the prefix
+                # matching wild cards.
+                (?<!==|!=|~=)         # We have special cases for these
+                                      # operators so we want to make sure they
+                                      # don't match here.
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)*   # release
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
+            )
+        )
+        """
+    )
+
+    _regex = re.compile(
+        r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
+
+    _operators = {
+        "~=": "compatible",
+        "==": "equal",
+        "!=": "not_equal",
+        "<=": "less_than_equal",
+        ">=": "greater_than_equal",
+        "<": "less_than",
+        ">": "greater_than",
+        "===": "arbitrary",
+    }
+
+    @_require_version_compare
+    def _compare_compatible(self, prospective, spec):
+        # Compatible releases have an equivalent combination of >= and ==. That
+        # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to
+        # implement this in terms of the other specifiers instead of
+        # implementing it ourselves. The only thing we need to do is construct
+        # the other specifiers.
+
+        # We want everything but the last item in the version, but we want to
+        # ignore post and dev releases and we want to treat the pre-release as
+        # it's own separate segment.
+        prefix = ".".join(
+            list(
+                itertools.takewhile(
+                    lambda x: (not x.startswith("post") and not
+                               x.startswith("dev")),
+                    _version_split(spec),
+                )
+            )[:-1]
+        )
+
+        # Add the prefix notation to the end of our string
+        prefix += ".*"
+
+        return (self._get_operator(">=")(prospective, spec) and
+                self._get_operator("==")(prospective, prefix))
+
+    @_require_version_compare
+    def _compare_equal(self, prospective, spec):
+        # We need special logic to handle prefix matching
+        if spec.endswith(".*"):
+            # In the case of prefix matching we want to ignore local segment.
+            prospective = Version(prospective.public)
+            # Split the spec out by dots, and pretend that there is an implicit
+            # dot in between a release segment and a pre-release segment.
+            spec = _version_split(spec[:-2])  # Remove the trailing .*
+
+            # Split the prospective version out by dots, and pretend that there
+            # is an implicit dot in between a release segment and a pre-release
+            # segment.
+            prospective = _version_split(str(prospective))
+
+            # Shorten the prospective version to be the same length as the spec
+            # so that we can determine if the specifier is a prefix of the
+            # prospective version or not.
+            prospective = prospective[:len(spec)]
+
+            # Pad out our two sides with zeros so that they both equal the same
+            # length.
+            spec, prospective = _pad_version(spec, prospective)
+        else:
+            # Convert our spec string into a Version
+            spec = Version(spec)
+
+            # If the specifier does not have a local segment, then we want to
+            # act as if the prospective version also does not have a local
+            # segment.
+            if not spec.local:
+                prospective = Version(prospective.public)
+
+        return prospective == spec
+
+    @_require_version_compare
+    def _compare_not_equal(self, prospective, spec):
+        return not self._compare_equal(prospective, spec)
+
+    @_require_version_compare
+    def _compare_less_than_equal(self, prospective, spec):
+        return prospective <= Version(spec)
+
+    @_require_version_compare
+    def _compare_greater_than_equal(self, prospective, spec):
+        return prospective >= Version(spec)
+
+    @_require_version_compare
+    def _compare_less_than(self, prospective, spec):
+        # Convert our spec to a Version instance, since we'll want to work with
+        # it as a version.
+        spec = Version(spec)
+
+        # Check to see if the prospective version is less than the spec
+        # version. If it's not we can short circuit and just return False now
+        # instead of doing extra unneeded work.
+        if not prospective < spec:
+            return False
+
+        # This special case is here so that, unless the specifier itself
+        # includes is a pre-release version, that we do not accept pre-release
+        # versions for the version mentioned in the specifier (e.g. <3.1 should
+        # not match 3.1.dev0, but should match 3.0.dev0).
+        if not spec.is_prerelease and prospective.is_prerelease:
+            if Version(prospective.base_version) == Version(spec.base_version):
+                return False
+
+        # If we've gotten to here, it means that prospective version is both
+        # less than the spec version *and* it's not a pre-release of the same
+        # version in the spec.
+        return True
+
+    @_require_version_compare
+    def _compare_greater_than(self, prospective, spec):
+        # Convert our spec to a Version instance, since we'll want to work with
+        # it as a version.
+        spec = Version(spec)
+
+        # Check to see if the prospective version is greater than the spec
+        # version. If it's not we can short circuit and just return False now
+        # instead of doing extra unneeded work.
+        if not prospective > spec:
+            return False
+
+        # This special case is here so that, unless the specifier itself
+        # includes is a post-release version, that we do not accept
+        # post-release versions for the version mentioned in the specifier
+        # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0).
+        if not spec.is_postrelease and prospective.is_postrelease:
+            if Version(prospective.base_version) == Version(spec.base_version):
+                return False
+
+        # Ensure that we do not allow a local version of the version mentioned
+        # in the specifier, which is techincally greater than, to match.
+        if prospective.local is not None:
+            if Version(prospective.base_version) == Version(spec.base_version):
+                return False
+
+        # If we've gotten to here, it means that prospective version is both
+        # greater than the spec version *and* it's not a pre-release of the
+        # same version in the spec.
+        return True
+
+    def _compare_arbitrary(self, prospective, spec):
+        return str(prospective).lower() == str(spec).lower()
+
+    @property
+    def prereleases(self):
+        # If there is an explicit prereleases set for this, then we'll just
+        # blindly use that.
+        if self._prereleases is not None:
+            return self._prereleases
+
+        # Look at all of our specifiers and determine if they are inclusive
+        # operators, and if they are if they are including an explicit
+        # prerelease.
+        operator, version = self._spec
+        if operator in ["==", ">=", "<=", "~=", "==="]:
+            # The == specifier can include a trailing .*, if it does we
+            # want to remove before parsing.
+            if operator == "==" and version.endswith(".*"):
+                version = version[:-2]
+
+            # Parse the version, and if it is a pre-release than this
+            # specifier allows pre-releases.
+            if parse(version).is_prerelease:
+                return True
+
+        return False
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+
+_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$")
+
+
+def _version_split(version):
+    result = []
+    for item in version.split("."):
+        match = _prefix_regex.search(item)
+        if match:
+            result.extend(match.groups())
+        else:
+            result.append(item)
+    return result
+
+
+def _pad_version(left, right):
+    left_split, right_split = [], []
+
+    # Get the release segment of our versions
+    left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left)))
+    right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right)))
+
+    # Get the rest of our versions
+    left_split.append(left[len(left_split[0]):])
+    right_split.append(right[len(right_split[0]):])
+
+    # Insert our padding
+    left_split.insert(
+        1,
+        ["0"] * max(0, len(right_split[0]) - len(left_split[0])),
+    )
+    right_split.insert(
+        1,
+        ["0"] * max(0, len(left_split[0]) - len(right_split[0])),
+    )
+
+    return (
+        list(itertools.chain(*left_split)),
+        list(itertools.chain(*right_split)),
+    )
+
+
+class SpecifierSet(BaseSpecifier):
+
+    def __init__(self, specifiers="", prereleases=None):
+        # Split on , to break each indidivual specifier into it's own item, and
+        # strip each item to remove leading/trailing whitespace.
+        specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
+
+        # Parsed each individual specifier, attempting first to make it a
+        # Specifier and falling back to a LegacySpecifier.
+        parsed = set()
+        for specifier in specifiers:
+            try:
+                parsed.add(Specifier(specifier))
+            except InvalidSpecifier:
+                parsed.add(LegacySpecifier(specifier))
+
+        # Turn our parsed specifiers into a frozen set and save them for later.
+        self._specs = frozenset(parsed)
+
+        # Store our prereleases value so we can use it later to determine if
+        # we accept prereleases or not.
+        self._prereleases = prereleases
+
+    def __repr__(self):
+        pre = (
+            ", prereleases={0!r}".format(self.prereleases)
+            if self._prereleases is not None
+            else ""
+        )
+
+        return "<SpecifierSet({0!r}{1})>".format(str(self), pre)
+
+    def __str__(self):
+        return ",".join(sorted(str(s) for s in self._specs))
+
+    def __hash__(self):
+        return hash(self._specs)
+
+    def __and__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        specifier = SpecifierSet()
+        specifier._specs = frozenset(self._specs | other._specs)
+
+        if self._prereleases is None and other._prereleases is not None:
+            specifier._prereleases = other._prereleases
+        elif self._prereleases is not None and other._prereleases is None:
+            specifier._prereleases = self._prereleases
+        elif self._prereleases == other._prereleases:
+            specifier._prereleases = self._prereleases
+        else:
+            raise ValueError(
+                "Cannot combine SpecifierSets with True and False prerelease "
+                "overrides."
+            )
+
+        return specifier
+
+    def __eq__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif isinstance(other, _IndividualSpecifier):
+            other = SpecifierSet(str(other))
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        return self._specs == other._specs
+
+    def __ne__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif isinstance(other, _IndividualSpecifier):
+            other = SpecifierSet(str(other))
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        return self._specs != other._specs
+
+    def __len__(self):
+        return len(self._specs)
+
+    def __iter__(self):
+        return iter(self._specs)
+
+    @property
+    def prereleases(self):
+        # If we have been given an explicit prerelease modifier, then we'll
+        # pass that through here.
+        if self._prereleases is not None:
+            return self._prereleases
+
+        # If we don't have any specifiers, and we don't have a forced value,
+        # then we'll just return None since we don't know if this should have
+        # pre-releases or not.
+        if not self._specs:
+            return None
+
+        # Otherwise we'll see if any of the given specifiers accept
+        # prereleases, if any of them do we'll return True, otherwise False.
+        return any(s.prereleases for s in self._specs)
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+    def __contains__(self, item):
+        return self.contains(item)
+
+    def contains(self, item, prereleases=None):
+        # Ensure that our item is a Version or LegacyVersion instance.
+        if not isinstance(item, (LegacyVersion, Version)):
+            item = parse(item)
+
+        # Determine if we're forcing a prerelease or not, if we're not forcing
+        # one for this particular filter call, then we'll use whatever the
+        # SpecifierSet thinks for whether or not we should support prereleases.
+        if prereleases is None:
+            prereleases = self.prereleases
+
+        # We can determine if we're going to allow pre-releases by looking to
+        # see if any of the underlying items supports them. If none of them do
+        # and this item is a pre-release then we do not allow it and we can
+        # short circuit that here.
+        # Note: This means that 1.0.dev1 would not be contained in something
+        #       like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0
+        if not prereleases and item.is_prerelease:
+            return False
+
+        # We simply dispatch to the underlying specs here to make sure that the
+        # given version is contained within all of them.
+        # Note: This use of all() here means that an empty set of specifiers
+        #       will always return True, this is an explicit design decision.
+        return all(
+            s.contains(item, prereleases=prereleases)
+            for s in self._specs
+        )
+
+    def filter(self, iterable, prereleases=None):
+        # Determine if we're forcing a prerelease or not, if we're not forcing
+        # one for this particular filter call, then we'll use whatever the
+        # SpecifierSet thinks for whether or not we should support prereleases.
+        if prereleases is None:
+            prereleases = self.prereleases
+
+        # If we have any specifiers, then we want to wrap our iterable in the
+        # filter method for each one, this will act as a logical AND amongst
+        # each specifier.
+        if self._specs:
+            for spec in self._specs:
+                iterable = spec.filter(iterable, prereleases=bool(prereleases))
+            return iterable
+        # If we do not have any specifiers, then we need to have a rough filter
+        # which will filter out any pre-releases, unless there are no final
+        # releases, and which will filter out LegacyVersion in general.
+        else:
+            filtered = []
+            found_prereleases = []
+
+            for item in iterable:
+                # Ensure that we some kind of Version class for this item.
+                if not isinstance(item, (LegacyVersion, Version)):
+                    parsed_version = parse(item)
+                else:
+                    parsed_version = item
+
+                # Filter out any item which is parsed as a LegacyVersion
+                if isinstance(parsed_version, LegacyVersion):
+                    continue
+
+                # Store any item which is a pre-release for later unless we've
+                # already found a final version or we are accepting prereleases
+                if parsed_version.is_prerelease and not prereleases:
+                    if not filtered:
+                        found_prereleases.append(item)
+                else:
+                    filtered.append(item)
+
+            # If we've found no items except for pre-releases, then we'll go
+            # ahead and use the pre-releases
+            if not filtered and found_prereleases and prereleases is None:
+                return found_prereleases
+
+            return filtered
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/utils.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/utils.py
new file mode 100644
index 00000000..942387ce
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/utils.py
@@ -0,0 +1,14 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import re
+
+
+_canonicalize_regex = re.compile(r"[-_.]+")
+
+
+def canonicalize_name(name):
+    # This is taken from PEP 503.
+    return _canonicalize_regex.sub("-", name).lower()
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/version.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/version.py
new file mode 100644
index 00000000..83b5ee8c
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/packaging/version.py
@@ -0,0 +1,393 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import collections
+import itertools
+import re
+
+from ._structures import Infinity
+
+
+__all__ = [
+    "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"
+]
+
+
+_Version = collections.namedtuple(
+    "_Version",
+    ["epoch", "release", "dev", "pre", "post", "local"],
+)
+
+
+def parse(version):
+    """
+    Parse the given version string and return either a :class:`Version` object
+    or a :class:`LegacyVersion` object depending on if the given version is
+    a valid PEP 440 version or a legacy version.
+    """
+    try:
+        return Version(version)
+    except InvalidVersion:
+        return LegacyVersion(version)
+
+
+class InvalidVersion(ValueError):
+    """
+    An invalid version was found, users should refer to PEP 440.
+    """
+
+
+class _BaseVersion(object):
+
+    def __hash__(self):
+        return hash(self._key)
+
+    def __lt__(self, other):
+        return self._compare(other, lambda s, o: s < o)
+
+    def __le__(self, other):
+        return self._compare(other, lambda s, o: s <= o)
+
+    def __eq__(self, other):
+        return self._compare(other, lambda s, o: s == o)
+
+    def __ge__(self, other):
+        return self._compare(other, lambda s, o: s >= o)
+
+    def __gt__(self, other):
+        return self._compare(other, lambda s, o: s > o)
+
+    def __ne__(self, other):
+        return self._compare(other, lambda s, o: s != o)
+
+    def _compare(self, other, method):
+        if not isinstance(other, _BaseVersion):
+            return NotImplemented
+
+        return method(self._key, other._key)
+
+
+class LegacyVersion(_BaseVersion):
+
+    def __init__(self, version):
+        self._version = str(version)
+        self._key = _legacy_cmpkey(self._version)
+
+    def __str__(self):
+        return self._version
+
+    def __repr__(self):
+        return "<LegacyVersion({0})>".format(repr(str(self)))
+
+    @property
+    def public(self):
+        return self._version
+
+    @property
+    def base_version(self):
+        return self._version
+
+    @property
+    def local(self):
+        return None
+
+    @property
+    def is_prerelease(self):
+        return False
+
+    @property
+    def is_postrelease(self):
+        return False
+
+
+_legacy_version_component_re = re.compile(
+    r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE,
+)
+
+_legacy_version_replacement_map = {
+    "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@",
+}
+
+
+def _parse_version_parts(s):
+    for part in _legacy_version_component_re.split(s):
+        part = _legacy_version_replacement_map.get(part, part)
+
+        if not part or part == ".":
+            continue
+
+        if part[:1] in "0123456789":
+            # pad for numeric comparison
+            yield part.zfill(8)
+        else:
+            yield "*" + part
+
+    # ensure that alpha/beta/candidate are before final
+    yield "*final"
+
+
+def _legacy_cmpkey(version):
+    # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch
+    # greater than or equal to 0. This will effectively put the LegacyVersion,
+    # which uses the defacto standard originally implemented by setuptools,
+    # as before all PEP 440 versions.
+    epoch = -1
+
+    # This scheme is taken from pkg_resources.parse_version setuptools prior to
+    # it's adoption of the packaging library.
+    parts = []
+    for part in _parse_version_parts(version.lower()):
+        if part.startswith("*"):
+            # remove "-" before a prerelease tag
+            if part < "*final":
+                while parts and parts[-1] == "*final-":
+                    parts.pop()
+
+            # remove trailing zeros from each series of numeric parts
+            while parts and parts[-1] == "00000000":
+                parts.pop()
+
+        parts.append(part)
+    parts = tuple(parts)
+
+    return epoch, parts
+
+# Deliberately not anchored to the start and end of the string, to make it
+# easier for 3rd party code to reuse
+VERSION_PATTERN = r"""
+    v?
+    (?:
+        (?:(?P<epoch>[0-9]+)!)?                           # epoch
+        (?P<release>[0-9]+(?:\.[0-9]+)*)                  # release segment
+        (?P<pre>                                          # pre-release
+            [-_\.]?
+            (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview))
+            [-_\.]?
+            (?P<pre_n>[0-9]+)?
+        )?
+        (?P<post>                                         # post release
+            (?:-(?P<post_n1>[0-9]+))
+            |
+            (?:
+                [-_\.]?
+                (?P<post_l>post|rev|r)
+                [-_\.]?
+                (?P<post_n2>[0-9]+)?
+            )
+        )?
+        (?P<dev>                                          # dev release
+            [-_\.]?
+            (?P<dev_l>dev)
+            [-_\.]?
+            (?P<dev_n>[0-9]+)?
+        )?
+    )
+    (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))?       # local version
+"""
+
+
+class Version(_BaseVersion):
+
+    _regex = re.compile(
+        r"^\s*" + VERSION_PATTERN + r"\s*$",
+        re.VERBOSE | re.IGNORECASE,
+    )
+
+    def __init__(self, version):
+        # Validate the version and parse it into pieces
+        match = self._regex.search(version)
+        if not match:
+            raise InvalidVersion("Invalid version: '{0}'".format(version))
+
+        # Store the parsed out pieces of the version
+        self._version = _Version(
+            epoch=int(match.group("epoch")) if match.group("epoch") else 0,
+            release=tuple(int(i) for i in match.group("release").split(".")),
+            pre=_parse_letter_version(
+                match.group("pre_l"),
+                match.group("pre_n"),
+            ),
+            post=_parse_letter_version(
+                match.group("post_l"),
+                match.group("post_n1") or match.group("post_n2"),
+            ),
+            dev=_parse_letter_version(
+                match.group("dev_l"),
+                match.group("dev_n"),
+            ),
+            local=_parse_local_version(match.group("local")),
+        )
+
+        # Generate a key which will be used for sorting
+        self._key = _cmpkey(
+            self._version.epoch,
+            self._version.release,
+            self._version.pre,
+            self._version.post,
+            self._version.dev,
+            self._version.local,
+        )
+
+    def __repr__(self):
+        return "<Version({0})>".format(repr(str(self)))
+
+    def __str__(self):
+        parts = []
+
+        # Epoch
+        if self._version.epoch != 0:
+            parts.append("{0}!".format(self._version.epoch))
+
+        # Release segment
+        parts.append(".".join(str(x) for x in self._version.release))
+
+        # Pre-release
+        if self._version.pre is not None:
+            parts.append("".join(str(x) for x in self._version.pre))
+
+        # Post-release
+        if self._version.post is not None:
+            parts.append(".post{0}".format(self._version.post[1]))
+
+        # Development release
+        if self._version.dev is not None:
+            parts.append(".dev{0}".format(self._version.dev[1]))
+
+        # Local version segment
+        if self._version.local is not None:
+            parts.append(
+                "+{0}".format(".".join(str(x) for x in self._version.local))
+            )
+
+        return "".join(parts)
+
+    @property
+    def public(self):
+        return str(self).split("+", 1)[0]
+
+    @property
+    def base_version(self):
+        parts = []
+
+        # Epoch
+        if self._version.epoch != 0:
+            parts.append("{0}!".format(self._version.epoch))
+
+        # Release segment
+        parts.append(".".join(str(x) for x in self._version.release))
+
+        return "".join(parts)
+
+    @property
+    def local(self):
+        version_string = str(self)
+        if "+" in version_string:
+            return version_string.split("+", 1)[1]
+
+    @property
+    def is_prerelease(self):
+        return bool(self._version.dev or self._version.pre)
+
+    @property
+    def is_postrelease(self):
+        return bool(self._version.post)
+
+
+def _parse_letter_version(letter, number):
+    if letter:
+        # We consider there to be an implicit 0 in a pre-release if there is
+        # not a numeral associated with it.
+        if number is None:
+            number = 0
+
+        # We normalize any letters to their lower case form
+        letter = letter.lower()
+
+        # We consider some words to be alternate spellings of other words and
+        # in those cases we want to normalize the spellings to our preferred
+        # spelling.
+        if letter == "alpha":
+            letter = "a"
+        elif letter == "beta":
+            letter = "b"
+        elif letter in ["c", "pre", "preview"]:
+            letter = "rc"
+        elif letter in ["rev", "r"]:
+            letter = "post"
+
+        return letter, int(number)
+    if not letter and number:
+        # We assume if we are given a number, but we are not given a letter
+        # then this is using the implicit post release syntax (e.g. 1.0-1)
+        letter = "post"
+
+        return letter, int(number)
+
+
+_local_version_seperators = re.compile(r"[\._-]")
+
+
+def _parse_local_version(local):
+    """
+    Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve").
+    """
+    if local is not None:
+        return tuple(
+            part.lower() if not part.isdigit() else int(part)
+            for part in _local_version_seperators.split(local)
+        )
+
+
+def _cmpkey(epoch, release, pre, post, dev, local):
+    # When we compare a release version, we want to compare it with all of the
+    # trailing zeros removed. So we'll use a reverse the list, drop all the now
+    # leading zeros until we come to something non zero, then take the rest
+    # re-reverse it back into the correct order and make it a tuple and use
+    # that for our sorting key.
+    release = tuple(
+        reversed(list(
+            itertools.dropwhile(
+                lambda x: x == 0,
+                reversed(release),
+            )
+        ))
+    )
+
+    # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
+    # We'll do this by abusing the pre segment, but we _only_ want to do this
+    # if there is not a pre or a post segment. If we have one of those then
+    # the normal sorting rules will handle this case correctly.
+    if pre is None and post is None and dev is not None:
+        pre = -Infinity
+    # Versions without a pre-release (except as noted above) should sort after
+    # those with one.
+    elif pre is None:
+        pre = Infinity
+
+    # Versions without a post segment should sort before those with one.
+    if post is None:
+        post = -Infinity
+
+    # Versions without a development segment should sort after those with one.
+    if dev is None:
+        dev = Infinity
+
+    if local is None:
+        # Versions without a local segment should sort before those with one.
+        local = -Infinity
+    else:
+        # Versions with a local segment need that segment parsed to implement
+        # the sorting rules in PEP440.
+        # - Alpha numeric segments sort before numeric segments
+        # - Alpha numeric segments sort lexicographically
+        # - Numeric segments sort numerically
+        # - Shorter versions sort before longer versions when the prefixes
+        #   match exactly
+        local = tuple(
+            (i, "") if isinstance(i, int) else (-Infinity, i)
+            for i in local
+        )
+
+    return epoch, release, pre, post, dev, local
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/pyparsing.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/pyparsing.py
new file mode 100644
index 00000000..a2122435
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/pyparsing.py
@@ -0,0 +1,5696 @@
+# module pyparsing.py
+#
+# Copyright (c) 2003-2016  Paul T. McGuire
+#
+# 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.
+#
+
+__doc__ = \
+"""
+pyparsing module - Classes and methods to define and execute parsing grammars
+
+The pyparsing module is an alternative approach to creating and executing simple grammars,
+vs. the traditional lex/yacc approach, or the use of regular expressions.  With pyparsing, you
+don't need to learn a new syntax for defining grammars or matching expressions - the parsing module
+provides a library of classes that you use to construct the grammar directly in Python.
+
+Here is a program to parse "Hello, World!" (or any greeting of the form 
+C{"<salutation>, <addressee>!"}), built up using L{Word}, L{Literal}, and L{And} elements 
+(L{'+'<ParserElement.__add__>} operator gives L{And} expressions, strings are auto-converted to
+L{Literal} expressions)::
+
+    from pyparsing import Word, alphas
+
+    # define grammar of a greeting
+    greet = Word(alphas) + "," + Word(alphas) + "!"
+
+    hello = "Hello, World!"
+    print (hello, "->", greet.parseString(hello))
+
+The program outputs the following::
+
+    Hello, World! -> ['Hello', ',', 'World', '!']
+
+The Python representation of the grammar is quite readable, owing to the self-explanatory
+class names, and the use of '+', '|' and '^' operators.
+
+The L{ParseResults} object returned from L{ParserElement.parseString<ParserElement.parseString>} can be accessed as a nested list, a dictionary, or an
+object with named attributes.
+
+The pyparsing module handles some of the problems that are typically vexing when writing text parsers:
+ - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello  ,  World  !", etc.)
+ - quoted strings
+ - embedded comments
+"""
+
+__version__ = "2.1.10"
+__versionTime__ = "07 Oct 2016 01:31 UTC"
+__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
+
+import string
+from weakref import ref as wkref
+import copy
+import sys
+import warnings
+import re
+import sre_constants
+import collections
+import pprint
+import traceback
+import types
+from datetime import datetime
+
+try:
+    from _thread import RLock
+except ImportError:
+    from threading import RLock
+
+try:
+    from collections import OrderedDict as _OrderedDict
+except ImportError:
+    try:
+        from ordereddict import OrderedDict as _OrderedDict
+    except ImportError:
+        _OrderedDict = None
+
+#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) )
+
+__all__ = [
+'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty',
+'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal',
+'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or',
+'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException',
+'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException',
+'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', 
+'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore',
+'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col',
+'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString',
+'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums',
+'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno',
+'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral',
+'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables',
+'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', 
+'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd',
+'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute',
+'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass',
+'CloseMatch', 'tokenMap', 'pyparsing_common',
+]
+
+system_version = tuple(sys.version_info)[:3]
+PY_3 = system_version[0] == 3
+if PY_3:
+    _MAX_INT = sys.maxsize
+    basestring = str
+    unichr = chr
+    _ustr = str
+
+    # build list of single arg builtins, that can be used as parse actions
+    singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max]
+
+else:
+    _MAX_INT = sys.maxint
+    range = xrange
+
+    def _ustr(obj):
+        """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries
+           str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It
+           then < returns the unicode object | encodes it with the default encoding | ... >.
+        """
+        if isinstance(obj,unicode):
+            return obj
+
+        try:
+            # If this works, then _ustr(obj) has the same behaviour as str(obj), so
+            # it won't break any existing code.
+            return str(obj)
+
+        except UnicodeEncodeError:
+            # Else encode it
+            ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace')
+            xmlcharref = Regex('&#\d+;')
+            xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:])
+            return xmlcharref.transformString(ret)
+
+    # build list of single arg builtins, tolerant of Python version, that can be used as parse actions
+    singleArgBuiltins = []
+    import __builtin__
+    for fname in "sum len sorted reversed list tuple set any all min max".split():
+        try:
+            singleArgBuiltins.append(getattr(__builtin__,fname))
+        except AttributeError:
+            continue
+            
+_generatorType = type((y for y in range(1)))
+ 
+def _xml_escape(data):
+    """Escape &, <, >, ", ', etc. in a string of data."""
+
+    # ampersand must be replaced first
+    from_symbols = '&><"\''
+    to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split())
+    for from_,to_ in zip(from_symbols, to_symbols):
+        data = data.replace(from_, to_)
+    return data
+
+class _Constants(object):
+    pass
+
+alphas     = string.ascii_uppercase + string.ascii_lowercase
+nums       = "0123456789"
+hexnums    = nums + "ABCDEFabcdef"
+alphanums  = alphas + nums
+_bslash    = chr(92)
+printables = "".join(c for c in string.printable if c not in string.whitespace)
+
+class ParseBaseException(Exception):
+    """base exception class for all parsing runtime exceptions"""
+    # Performance tuning: we construct a *lot* of these, so keep this
+    # constructor as small and fast as possible
+    def __init__( self, pstr, loc=0, msg=None, elem=None ):
+        self.loc = loc
+        if msg is None:
+            self.msg = pstr
+            self.pstr = ""
+        else:
+            self.msg = msg
+            self.pstr = pstr
+        self.parserElement = elem
+        self.args = (pstr, loc, msg)
+
+    @classmethod
+    def _from_exception(cls, pe):
+        """
+        internal factory method to simplify creating one type of ParseException 
+        from another - avoids having __init__ signature conflicts among subclasses
+        """
+        return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement)
+
+    def __getattr__( self, aname ):
+        """supported attributes by name are:
+            - lineno - returns the line number of the exception text
+            - col - returns the column number of the exception text
+            - line - returns the line containing the exception text
+        """
+        if( aname == "lineno" ):
+            return lineno( self.loc, self.pstr )
+        elif( aname in ("col", "column") ):
+            return col( self.loc, self.pstr )
+        elif( aname == "line" ):
+            return line( self.loc, self.pstr )
+        else:
+            raise AttributeError(aname)
+
+    def __str__( self ):
+        return "%s (at char %d), (line:%d, col:%d)" % \
+                ( self.msg, self.loc, self.lineno, self.column )
+    def __repr__( self ):
+        return _ustr(self)
+    def markInputline( self, markerString = ">!<" ):
+        """Extracts the exception line from the input string, and marks
+           the location of the exception with a special symbol.
+        """
+        line_str = self.line
+        line_column = self.column - 1
+        if markerString:
+            line_str = "".join((line_str[:line_column],
+                                markerString, line_str[line_column:]))
+        return line_str.strip()
+    def __dir__(self):
+        return "lineno col line".split() + dir(type(self))
+
+class ParseException(ParseBaseException):
+    """
+    Exception thrown when parse expressions don't match class;
+    supported attributes by name are:
+     - lineno - returns the line number of the exception text
+     - col - returns the column number of the exception text
+     - line - returns the line containing the exception text
+        
+    Example::
+        try:
+            Word(nums).setName("integer").parseString("ABC")
+        except ParseException as pe:
+            print(pe)
+            print("column: {}".format(pe.col))
+            
+    prints::
+       Expected integer (at char 0), (line:1, col:1)
+        column: 1
+    """
+    pass
+
+class ParseFatalException(ParseBaseException):
+    """user-throwable exception thrown when inconsistent parse content
+       is found; stops all parsing immediately"""
+    pass
+
+class ParseSyntaxException(ParseFatalException):
+    """just like L{ParseFatalException}, but thrown internally when an
+       L{ErrorStop<And._ErrorStop>} ('-' operator) indicates that parsing is to stop 
+       immediately because an unbacktrackable syntax error has been found"""
+    pass
+
+#~ class ReparseException(ParseBaseException):
+    #~ """Experimental class - parse actions can raise this exception to cause
+       #~ pyparsing to reparse the input string:
+        #~ - with a modified input string, and/or
+        #~ - with a modified start location
+       #~ Set the values of the ReparseException in the constructor, and raise the
+       #~ exception in a parse action to cause pyparsing to use the new string/location.
+       #~ Setting the values as None causes no change to be made.
+       #~ """
+    #~ def __init_( self, newstring, restartLoc ):
+        #~ self.newParseText = newstring
+        #~ self.reparseLoc = restartLoc
+
+class RecursiveGrammarException(Exception):
+    """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive"""
+    def __init__( self, parseElementList ):
+        self.parseElementTrace = parseElementList
+
+    def __str__( self ):
+        return "RecursiveGrammarException: %s" % self.parseElementTrace
+
+class _ParseResultsWithOffset(object):
+    def __init__(self,p1,p2):
+        self.tup = (p1,p2)
+    def __getitem__(self,i):
+        return self.tup[i]
+    def __repr__(self):
+        return repr(self.tup[0])
+    def setOffset(self,i):
+        self.tup = (self.tup[0],i)
+
+class ParseResults(object):
+    """
+    Structured parse results, to provide multiple means of access to the parsed data:
+       - as a list (C{len(results)})
+       - by list index (C{results[0], results[1]}, etc.)
+       - by attribute (C{results.<resultsName>} - see L{ParserElement.setResultsName})
+
+    Example::
+        integer = Word(nums)
+        date_str = (integer.setResultsName("year") + '/' 
+                        + integer.setResultsName("month") + '/' 
+                        + integer.setResultsName("day"))
+        # equivalent form:
+        # date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+
+        # parseString returns a ParseResults object
+        result = date_str.parseString("1999/12/31")
+
+        def test(s, fn=repr):
+            print("%s -> %s" % (s, fn(eval(s))))
+        test("list(result)")
+        test("result[0]")
+        test("result['month']")
+        test("result.day")
+        test("'month' in result")
+        test("'minutes' in result")
+        test("result.dump()", str)
+    prints::
+        list(result) -> ['1999', '/', '12', '/', '31']
+        result[0] -> '1999'
+        result['month'] -> '12'
+        result.day -> '31'
+        'month' in result -> True
+        'minutes' in result -> False
+        result.dump() -> ['1999', '/', '12', '/', '31']
+        - day: 31
+        - month: 12
+        - year: 1999
+    """
+    def __new__(cls, toklist=None, name=None, asList=True, modal=True ):
+        if isinstance(toklist, cls):
+            return toklist
+        retobj = object.__new__(cls)
+        retobj.__doinit = True
+        return retobj
+
+    # Performance tuning: we construct a *lot* of these, so keep this
+    # constructor as small and fast as possible
+    def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ):
+        if self.__doinit:
+            self.__doinit = False
+            self.__name = None
+            self.__parent = None
+            self.__accumNames = {}
+            self.__asList = asList
+            self.__modal = modal
+            if toklist is None:
+                toklist = []
+            if isinstance(toklist, list):
+                self.__toklist = toklist[:]
+            elif isinstance(toklist, _generatorType):
+                self.__toklist = list(toklist)
+            else:
+                self.__toklist = [toklist]
+            self.__tokdict = dict()
+
+        if name is not None and name:
+            if not modal:
+                self.__accumNames[name] = 0
+            if isinstance(name,int):
+                name = _ustr(name) # will always return a str, but use _ustr for consistency
+            self.__name = name
+            if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])):
+                if isinstance(toklist,basestring):
+                    toklist = [ toklist ]
+                if asList:
+                    if isinstance(toklist,ParseResults):
+                        self[name] = _ParseResultsWithOffset(toklist.copy(),0)
+                    else:
+                        self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0)
+                    self[name].__name = name
+                else:
+                    try:
+                        self[name] = toklist[0]
+                    except (KeyError,TypeError,IndexError):
+                        self[name] = toklist
+
+    def __getitem__( self, i ):
+        if isinstance( i, (int,slice) ):
+            return self.__toklist[i]
+        else:
+            if i not in self.__accumNames:
+                return self.__tokdict[i][-1][0]
+            else:
+                return ParseResults([ v[0] for v in self.__tokdict[i] ])
+
+    def __setitem__( self, k, v, isinstance=isinstance ):
+        if isinstance(v,_ParseResultsWithOffset):
+            self.__tokdict[k] = self.__tokdict.get(k,list()) + [v]
+            sub = v[0]
+        elif isinstance(k,(int,slice)):
+            self.__toklist[k] = v
+            sub = v
+        else:
+            self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)]
+            sub = v
+        if isinstance(sub,ParseResults):
+            sub.__parent = wkref(self)
+
+    def __delitem__( self, i ):
+        if isinstance(i,(int,slice)):
+            mylen = len( self.__toklist )
+            del self.__toklist[i]
+
+            # convert int to slice
+            if isinstance(i, int):
+                if i < 0:
+                    i += mylen
+                i = slice(i, i+1)
+            # get removed indices
+            removed = list(range(*i.indices(mylen)))
+            removed.reverse()
+            # fixup indices in token dictionary
+            for name,occurrences in self.__tokdict.items():
+                for j in removed:
+                    for k, (value, position) in enumerate(occurrences):
+                        occurrences[k] = _ParseResultsWithOffset(value, position - (position > j))
+        else:
+            del self.__tokdict[i]
+
+    def __contains__( self, k ):
+        return k in self.__tokdict
+
+    def __len__( self ): return len( self.__toklist )
+    def __bool__(self): return ( not not self.__toklist )
+    __nonzero__ = __bool__
+    def __iter__( self ): return iter( self.__toklist )
+    def __reversed__( self ): return iter( self.__toklist[::-1] )
+    def _iterkeys( self ):
+        if hasattr(self.__tokdict, "iterkeys"):
+            return self.__tokdict.iterkeys()
+        else:
+            return iter(self.__tokdict)
+
+    def _itervalues( self ):
+        return (self[k] for k in self._iterkeys())
+            
+    def _iteritems( self ):
+        return ((k, self[k]) for k in self._iterkeys())
+
+    if PY_3:
+        keys = _iterkeys       
+        """Returns an iterator of all named result keys (Python 3.x only)."""
+
+        values = _itervalues
+        """Returns an iterator of all named result values (Python 3.x only)."""
+
+        items = _iteritems
+        """Returns an iterator of all named result key-value tuples (Python 3.x only)."""
+
+    else:
+        iterkeys = _iterkeys
+        """Returns an iterator of all named result keys (Python 2.x only)."""
+
+        itervalues = _itervalues
+        """Returns an iterator of all named result values (Python 2.x only)."""
+
+        iteritems = _iteritems
+        """Returns an iterator of all named result key-value tuples (Python 2.x only)."""
+
+        def keys( self ):
+            """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x)."""
+            return list(self.iterkeys())
+
+        def values( self ):
+            """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x)."""
+            return list(self.itervalues())
+                
+        def items( self ):
+            """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x)."""
+            return list(self.iteritems())
+
+    def haskeys( self ):
+        """Since keys() returns an iterator, this method is helpful in bypassing
+           code that looks for the existence of any defined results names."""
+        return bool(self.__tokdict)
+        
+    def pop( self, *args, **kwargs):
+        """
+        Removes and returns item at specified index (default=C{last}).
+        Supports both C{list} and C{dict} semantics for C{pop()}. If passed no
+        argument or an integer argument, it will use C{list} semantics
+        and pop tokens from the list of parsed tokens. If passed a 
+        non-integer argument (most likely a string), it will use C{dict}
+        semantics and pop the corresponding value from any defined 
+        results names. A second default return value argument is 
+        supported, just as in C{dict.pop()}.
+
+        Example::
+            def remove_first(tokens):
+                tokens.pop(0)
+            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
+            print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321']
+
+            label = Word(alphas)
+            patt = label("LABEL") + OneOrMore(Word(nums))
+            print(patt.parseString("AAB 123 321").dump())
+
+            # Use pop() in a parse action to remove named result (note that corresponding value is not
+            # removed from list form of results)
+            def remove_LABEL(tokens):
+                tokens.pop("LABEL")
+                return tokens
+            patt.addParseAction(remove_LABEL)
+            print(patt.parseString("AAB 123 321").dump())
+        prints::
+            ['AAB', '123', '321']
+            - LABEL: AAB
+
+            ['AAB', '123', '321']
+        """
+        if not args:
+            args = [-1]
+        for k,v in kwargs.items():
+            if k == 'default':
+                args = (args[0], v)
+            else:
+                raise TypeError("pop() got an unexpected keyword argument '%s'" % k)
+        if (isinstance(args[0], int) or 
+                        len(args) == 1 or 
+                        args[0] in self):
+            index = args[0]
+            ret = self[index]
+            del self[index]
+            return ret
+        else:
+            defaultvalue = args[1]
+            return defaultvalue
+
+    def get(self, key, defaultValue=None):
+        """
+        Returns named result matching the given key, or if there is no
+        such name, then returns the given C{defaultValue} or C{None} if no
+        C{defaultValue} is specified.
+
+        Similar to C{dict.get()}.
+        
+        Example::
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
+
+            result = date_str.parseString("1999/12/31")
+            print(result.get("year")) # -> '1999'
+            print(result.get("hour", "not specified")) # -> 'not specified'
+            print(result.get("hour")) # -> None
+        """
+        if key in self:
+            return self[key]
+        else:
+            return defaultValue
+
+    def insert( self, index, insStr ):
+        """
+        Inserts new element at location index in the list of parsed tokens.
+        
+        Similar to C{list.insert()}.
+
+        Example::
+            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
+
+            # use a parse action to insert the parse location in the front of the parsed results
+            def insert_locn(locn, tokens):
+                tokens.insert(0, locn)
+            print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321']
+        """
+        self.__toklist.insert(index, insStr)
+        # fixup indices in token dictionary
+        for name,occurrences in self.__tokdict.items():
+            for k, (value, position) in enumerate(occurrences):
+                occurrences[k] = _ParseResultsWithOffset(value, position + (position > index))
+
+    def append( self, item ):
+        """
+        Add single element to end of ParseResults list of elements.
+
+        Example::
+            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
+            
+            # use a parse action to compute the sum of the parsed integers, and add it to the end
+            def append_sum(tokens):
+                tokens.append(sum(map(int, tokens)))
+            print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444]
+        """
+        self.__toklist.append(item)
+
+    def extend( self, itemseq ):
+        """
+        Add sequence of elements to end of ParseResults list of elements.
+
+        Example::
+            patt = OneOrMore(Word(alphas))
+            
+            # use a parse action to append the reverse of the matched strings, to make a palindrome
+            def make_palindrome(tokens):
+                tokens.extend(reversed([t[::-1] for t in tokens]))
+                return ''.join(tokens)
+            print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl'
+        """
+        if isinstance(itemseq, ParseResults):
+            self += itemseq
+        else:
+            self.__toklist.extend(itemseq)
+
+    def clear( self ):
+        """
+        Clear all elements and results names.
+        """
+        del self.__toklist[:]
+        self.__tokdict.clear()
+
+    def __getattr__( self, name ):
+        try:
+            return self[name]
+        except KeyError:
+            return ""
+            
+        if name in self.__tokdict:
+            if name not in self.__accumNames:
+                return self.__tokdict[name][-1][0]
+            else:
+                return ParseResults([ v[0] for v in self.__tokdict[name] ])
+        else:
+            return ""
+
+    def __add__( self, other ):
+        ret = self.copy()
+        ret += other
+        return ret
+
+    def __iadd__( self, other ):
+        if other.__tokdict:
+            offset = len(self.__toklist)
+            addoffset = lambda a: offset if a<0 else a+offset
+            otheritems = other.__tokdict.items()
+            otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) )
+                                for (k,vlist) in otheritems for v in vlist]
+            for k,v in otherdictitems:
+                self[k] = v
+                if isinstance(v[0],ParseResults):
+                    v[0].__parent = wkref(self)
+            
+        self.__toklist += other.__toklist
+        self.__accumNames.update( other.__accumNames )
+        return self
+
+    def __radd__(self, other):
+        if isinstance(other,int) and other == 0:
+            # useful for merging many ParseResults using sum() builtin
+            return self.copy()
+        else:
+            # this may raise a TypeError - so be it
+            return other + self
+        
+    def __repr__( self ):
+        return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) )
+
+    def __str__( self ):
+        return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']'
+
+    def _asStringList( self, sep='' ):
+        out = []
+        for item in self.__toklist:
+            if out and sep:
+                out.append(sep)
+            if isinstance( item, ParseResults ):
+                out += item._asStringList()
+            else:
+                out.append( _ustr(item) )
+        return out
+
+    def asList( self ):
+        """
+        Returns the parse results as a nested list of matching tokens, all converted to strings.
+
+        Example::
+            patt = OneOrMore(Word(alphas))
+            result = patt.parseString("sldkj lsdkj sldkj")
+            # even though the result prints in string-like form, it is actually a pyparsing ParseResults
+            print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj']
+            
+            # Use asList() to create an actual list
+            result_list = result.asList()
+            print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj']
+        """
+        return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist]
+
+    def asDict( self ):
+        """
+        Returns the named parse results as a nested dictionary.
+
+        Example::
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+            
+            result = date_str.parseString('12/31/1999')
+            print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]})
+            
+            result_dict = result.asDict()
+            print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'}
+
+            # even though a ParseResults supports dict-like access, sometime you just need to have a dict
+            import json
+            print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable
+            print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"}
+        """
+        if PY_3:
+            item_fn = self.items
+        else:
+            item_fn = self.iteritems
+            
+        def toItem(obj):
+            if isinstance(obj, ParseResults):
+                if obj.haskeys():
+                    return obj.asDict()
+                else:
+                    return [toItem(v) for v in obj]
+            else:
+                return obj
+                
+        return dict((k,toItem(v)) for k,v in item_fn())
+
+    def copy( self ):
+        """
+        Returns a new copy of a C{ParseResults} object.
+        """
+        ret = ParseResults( self.__toklist )
+        ret.__tokdict = self.__tokdict.copy()
+        ret.__parent = self.__parent
+        ret.__accumNames.update( self.__accumNames )
+        ret.__name = self.__name
+        return ret
+
+    def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ):
+        """
+        (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names.
+        """
+        nl = "\n"
+        out = []
+        namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items()
+                                                            for v in vlist)
+        nextLevelIndent = indent + "  "
+
+        # collapse out indents if formatting is not desired
+        if not formatted:
+            indent = ""
+            nextLevelIndent = ""
+            nl = ""
+
+        selfTag = None
+        if doctag is not None:
+            selfTag = doctag
+        else:
+            if self.__name:
+                selfTag = self.__name
+
+        if not selfTag:
+            if namedItemsOnly:
+                return ""
+            else:
+                selfTag = "ITEM"
+
+        out += [ nl, indent, "<", selfTag, ">" ]
+
+        for i,res in enumerate(self.__toklist):
+            if isinstance(res,ParseResults):
+                if i in namedItems:
+                    out += [ res.asXML(namedItems[i],
+                                        namedItemsOnly and doctag is None,
+                                        nextLevelIndent,
+                                        formatted)]
+                else:
+                    out += [ res.asXML(None,
+                                        namedItemsOnly and doctag is None,
+                                        nextLevelIndent,
+                                        formatted)]
+            else:
+                # individual token, see if there is a name for it
+                resTag = None
+                if i in namedItems:
+                    resTag = namedItems[i]
+                if not resTag:
+                    if namedItemsOnly:
+                        continue
+                    else:
+                        resTag = "ITEM"
+                xmlBodyText = _xml_escape(_ustr(res))
+                out += [ nl, nextLevelIndent, "<", resTag, ">",
+                                                xmlBodyText,
+                                                "</", resTag, ">" ]
+
+        out += [ nl, indent, "</", selfTag, ">" ]
+        return "".join(out)
+
+    def __lookup(self,sub):
+        for k,vlist in self.__tokdict.items():
+            for v,loc in vlist:
+                if sub is v:
+                    return k
+        return None
+
+    def getName(self):
+        """
+        Returns the results name for this token expression. Useful when several 
+        different expressions might match at a particular location.
+
+        Example::
+            integer = Word(nums)
+            ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d")
+            house_number_expr = Suppress('#') + Word(nums, alphanums)
+            user_data = (Group(house_number_expr)("house_number") 
+                        | Group(ssn_expr)("ssn")
+                        | Group(integer)("age"))
+            user_info = OneOrMore(user_data)
+            
+            result = user_info.parseString("22 111-22-3333 #221B")
+            for item in result:
+                print(item.getName(), ':', item[0])
+        prints::
+            age : 22
+            ssn : 111-22-3333
+            house_number : 221B
+        """
+        if self.__name:
+            return self.__name
+        elif self.__parent:
+            par = self.__parent()
+            if par:
+                return par.__lookup(self)
+            else:
+                return None
+        elif (len(self) == 1 and
+               len(self.__tokdict) == 1 and
+               next(iter(self.__tokdict.values()))[0][1] in (0,-1)):
+            return next(iter(self.__tokdict.keys()))
+        else:
+            return None
+
+    def dump(self, indent='', depth=0, full=True):
+        """
+        Diagnostic method for listing out the contents of a C{ParseResults}.
+        Accepts an optional C{indent} argument so that this string can be embedded
+        in a nested display of other data.
+
+        Example::
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+            
+            result = date_str.parseString('12/31/1999')
+            print(result.dump())
+        prints::
+            ['12', '/', '31', '/', '1999']
+            - day: 1999
+            - month: 31
+            - year: 12
+        """
+        out = []
+        NL = '\n'
+        out.append( indent+_ustr(self.asList()) )
+        if full:
+            if self.haskeys():
+                items = sorted((str(k), v) for k,v in self.items())
+                for k,v in items:
+                    if out:
+                        out.append(NL)
+                    out.append( "%s%s- %s: " % (indent,('  '*depth), k) )
+                    if isinstance(v,ParseResults):
+                        if v:
+                            out.append( v.dump(indent,depth+1) )
+                        else:
+                            out.append(_ustr(v))
+                    else:
+                        out.append(repr(v))
+            elif any(isinstance(vv,ParseResults) for vv in self):
+                v = self
+                for i,vv in enumerate(v):
+                    if isinstance(vv,ParseResults):
+                        out.append("\n%s%s[%d]:\n%s%s%s" % (indent,('  '*(depth)),i,indent,('  '*(depth+1)),vv.dump(indent,depth+1) ))
+                    else:
+                        out.append("\n%s%s[%d]:\n%s%s%s" % (indent,('  '*(depth)),i,indent,('  '*(depth+1)),_ustr(vv)))
+            
+        return "".join(out)
+
+    def pprint(self, *args, **kwargs):
+        """
+        Pretty-printer for parsed results as a list, using the C{pprint} module.
+        Accepts additional positional or keyword args as defined for the 
+        C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint})
+
+        Example::
+            ident = Word(alphas, alphanums)
+            num = Word(nums)
+            func = Forward()
+            term = ident | num | Group('(' + func + ')')
+            func <<= ident + Group(Optional(delimitedList(term)))
+            result = func.parseString("fna a,b,(fnb c,d,200),100")
+            result.pprint(width=40)
+        prints::
+            ['fna',
+             ['a',
+              'b',
+              ['(', 'fnb', ['c', 'd', '200'], ')'],
+              '100']]
+        """
+        pprint.pprint(self.asList(), *args, **kwargs)
+
+    # add support for pickle protocol
+    def __getstate__(self):
+        return ( self.__toklist,
+                 ( self.__tokdict.copy(),
+                   self.__parent is not None and self.__parent() or None,
+                   self.__accumNames,
+                   self.__name ) )
+
+    def __setstate__(self,state):
+        self.__toklist = state[0]
+        (self.__tokdict,
+         par,
+         inAccumNames,
+         self.__name) = state[1]
+        self.__accumNames = {}
+        self.__accumNames.update(inAccumNames)
+        if par is not None:
+            self.__parent = wkref(par)
+        else:
+            self.__parent = None
+
+    def __getnewargs__(self):
+        return self.__toklist, self.__name, self.__asList, self.__modal
+
+    def __dir__(self):
+        return (dir(type(self)) + list(self.keys()))
+
+collections.MutableMapping.register(ParseResults)
+
+def col (loc,strg):
+    """Returns current column within a string, counting newlines as line separators.
+   The first column is number 1.
+
+   Note: the default parsing behavior is to expand tabs in the input string
+   before starting the parsing process.  See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information
+   on parsing strings containing C{<TAB>}s, and suggested methods to maintain a
+   consistent view of the parsed string, the parse location, and line and column
+   positions within the parsed string.
+   """
+    s = strg
+    return 1 if 0<loc<len(s) and s[loc-1] == '\n' else loc - s.rfind("\n", 0, loc)
+
+def lineno(loc,strg):
+    """Returns current line number within a string, counting newlines as line separators.
+   The first line is number 1.
+
+   Note: the default parsing behavior is to expand tabs in the input string
+   before starting the parsing process.  See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information
+   on parsing strings containing C{<TAB>}s, and suggested methods to maintain a
+   consistent view of the parsed string, the parse location, and line and column
+   positions within the parsed string.
+   """
+    return strg.count("\n",0,loc) + 1
+
+def line( loc, strg ):
+    """Returns the line of text containing loc within a string, counting newlines as line separators.
+       """
+    lastCR = strg.rfind("\n", 0, loc)
+    nextCR = strg.find("\n", loc)
+    if nextCR >= 0:
+        return strg[lastCR+1:nextCR]
+    else:
+        return strg[lastCR+1:]
+
+def _defaultStartDebugAction( instring, loc, expr ):
+    print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )))
+
+def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ):
+    print ("Matched " + _ustr(expr) + " -> " + str(toks.asList()))
+
+def _defaultExceptionDebugAction( instring, loc, expr, exc ):
+    print ("Exception raised:" + _ustr(exc))
+
+def nullDebugAction(*args):
+    """'Do-nothing' debug action, to suppress debugging output during parsing."""
+    pass
+
+# Only works on Python 3.x - nonlocal is toxic to Python 2 installs
+#~ 'decorator to trim function calls to match the arity of the target'
+#~ def _trim_arity(func, maxargs=3):
+    #~ if func in singleArgBuiltins:
+        #~ return lambda s,l,t: func(t)
+    #~ limit = 0
+    #~ foundArity = False
+    #~ def wrapper(*args):
+        #~ nonlocal limit,foundArity
+        #~ while 1:
+            #~ try:
+                #~ ret = func(*args[limit:])
+                #~ foundArity = True
+                #~ return ret
+            #~ except TypeError:
+                #~ if limit == maxargs or foundArity:
+                    #~ raise
+                #~ limit += 1
+                #~ continue
+    #~ return wrapper
+
+# this version is Python 2.x-3.x cross-compatible
+'decorator to trim function calls to match the arity of the target'
+def _trim_arity(func, maxargs=2):
+    if func in singleArgBuiltins:
+        return lambda s,l,t: func(t)
+    limit = [0]
+    foundArity = [False]
+    
+    # traceback return data structure changed in Py3.5 - normalize back to plain tuples
+    if system_version[:2] >= (3,5):
+        def extract_stack(limit=0):
+            # special handling for Python 3.5.0 - extra deep call stack by 1
+            offset = -3 if system_version == (3,5,0) else -2
+            frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset]
+            return [(frame_summary.filename, frame_summary.lineno)]
+        def extract_tb(tb, limit=0):
+            frames = traceback.extract_tb(tb, limit=limit)
+            frame_summary = frames[-1]
+            return [(frame_summary.filename, frame_summary.lineno)]
+    else:
+        extract_stack = traceback.extract_stack
+        extract_tb = traceback.extract_tb
+    
+    # synthesize what would be returned by traceback.extract_stack at the call to 
+    # user's parse action 'func', so that we don't incur call penalty at parse time
+    
+    LINE_DIFF = 6
+    # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND 
+    # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!!
+    this_line = extract_stack(limit=2)[-1]
+    pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF)
+
+    def wrapper(*args):
+        while 1:
+            try:
+                ret = func(*args[limit[0]:])
+                foundArity[0] = True
+                return ret
+            except TypeError:
+                # re-raise TypeErrors if they did not come from our arity testing
+                if foundArity[0]:
+                    raise
+                else:
+                    try:
+                        tb = sys.exc_info()[-1]
+                        if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth:
+                            raise
+                    finally:
+                        del tb
+
+                if limit[0] <= maxargs:
+                    limit[0] += 1
+                    continue
+                raise
+
+    # copy func name to wrapper for sensible debug output
+    func_name = "<parse action>"
+    try:
+        func_name = getattr(func, '__name__', 
+                            getattr(func, '__class__').__name__)
+    except Exception:
+        func_name = str(func)
+    wrapper.__name__ = func_name
+
+    return wrapper
+
+class ParserElement(object):
+    """Abstract base level parser element class."""
+    DEFAULT_WHITE_CHARS = " \n\t\r"
+    verbose_stacktrace = False
+
+    @staticmethod
+    def setDefaultWhitespaceChars( chars ):
+        r"""
+        Overrides the default whitespace chars
+
+        Example::
+            # default whitespace chars are space, <TAB> and newline
+            OneOrMore(Word(alphas)).parseString("abc def\nghi jkl")  # -> ['abc', 'def', 'ghi', 'jkl']
+            
+            # change to just treat newline as significant
+            ParserElement.setDefaultWhitespaceChars(" \t")
+            OneOrMore(Word(alphas)).parseString("abc def\nghi jkl")  # -> ['abc', 'def']
+        """
+        ParserElement.DEFAULT_WHITE_CHARS = chars
+
+    @staticmethod
+    def inlineLiteralsUsing(cls):
+        """
+        Set class to be used for inclusion of string literals into a parser.
+        
+        Example::
+            # default literal class used is Literal
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
+
+            date_str.parseString("1999/12/31")  # -> ['1999', '/', '12', '/', '31']
+
+
+            # change to Suppress
+            ParserElement.inlineLiteralsUsing(Suppress)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
+
+            date_str.parseString("1999/12/31")  # -> ['1999', '12', '31']
+        """
+        ParserElement._literalStringClass = cls
+
+    def __init__( self, savelist=False ):
+        self.parseAction = list()
+        self.failAction = None
+        #~ self.name = "<unknown>"  # don't define self.name, let subclasses try/except upcall
+        self.strRepr = None
+        self.resultsName = None
+        self.saveAsList = savelist
+        self.skipWhitespace = True
+        self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
+        self.copyDefaultWhiteChars = True
+        self.mayReturnEmpty = False # used when checking for left-recursion
+        self.keepTabs = False
+        self.ignoreExprs = list()
+        self.debug = False
+        self.streamlined = False
+        self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index
+        self.errmsg = ""
+        self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all)
+        self.debugActions = ( None, None, None ) #custom debug actions
+        self.re = None
+        self.callPreparse = True # used to avoid redundant calls to preParse
+        self.callDuringTry = False
+
+    def copy( self ):
+        """
+        Make a copy of this C{ParserElement}.  Useful for defining different parse actions
+        for the same parsing pattern, using copies of the original parse element.
+        
+        Example::
+            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
+            integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K")
+            integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
+            
+            print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M"))
+        prints::
+            [5120, 100, 655360, 268435456]
+        Equivalent form of C{expr.copy()} is just C{expr()}::
+            integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
+        """
+        cpy = copy.copy( self )
+        cpy.parseAction = self.parseAction[:]
+        cpy.ignoreExprs = self.ignoreExprs[:]
+        if self.copyDefaultWhiteChars:
+            cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
+        return cpy
+
+    def setName( self, name ):
+        """
+        Define name for this expression, makes debugging and exception messages clearer.
+        
+        Example::
+            Word(nums).parseString("ABC")  # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1)
+            Word(nums).setName("integer").parseString("ABC")  # -> Exception: Expected integer (at char 0), (line:1, col:1)
+        """
+        self.name = name
+        self.errmsg = "Expected " + self.name
+        if hasattr(self,"exception"):
+            self.exception.msg = self.errmsg
+        return self
+
+    def setResultsName( self, name, listAllMatches=False ):
+        """
+        Define name for referencing matching tokens as a nested attribute
+        of the returned parse results.
+        NOTE: this returns a *copy* of the original C{ParserElement} object;
+        this is so that the client can define a basic element, such as an
+        integer, and reference it in multiple places with different names.
+
+        You can also set results names using the abbreviated syntax,
+        C{expr("name")} in place of C{expr.setResultsName("name")} - 
+        see L{I{__call__}<__call__>}.
+
+        Example::
+            date_str = (integer.setResultsName("year") + '/' 
+                        + integer.setResultsName("month") + '/' 
+                        + integer.setResultsName("day"))
+
+            # equivalent form:
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+        """
+        newself = self.copy()
+        if name.endswith("*"):
+            name = name[:-1]
+            listAllMatches=True
+        newself.resultsName = name
+        newself.modalResults = not listAllMatches
+        return newself
+
+    def setBreak(self,breakFlag = True):
+        """Method to invoke the Python pdb debugger when this element is
+           about to be parsed. Set C{breakFlag} to True to enable, False to
+           disable.
+        """
+        if breakFlag:
+            _parseMethod = self._parse
+            def breaker(instring, loc, doActions=True, callPreParse=True):
+                import pdb
+                pdb.set_trace()
+                return _parseMethod( instring, loc, doActions, callPreParse )
+            breaker._originalParseMethod = _parseMethod
+            self._parse = breaker
+        else:
+            if hasattr(self._parse,"_originalParseMethod"):
+                self._parse = self._parse._originalParseMethod
+        return self
+
+    def setParseAction( self, *fns, **kwargs ):
+        """
+        Define action to perform when successfully matching parse element definition.
+        Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)},
+        C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where:
+         - s   = the original string being parsed (see note below)
+         - loc = the location of the matching substring
+         - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object
+        If the functions in fns modify the tokens, they can return them as the return
+        value from fn, and the modified list of tokens will replace the original.
+        Otherwise, fn does not need to return any value.
+
+        Optional keyword arguments:
+         - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing
+
+        Note: the default parsing behavior is to expand tabs in the input string
+        before starting the parsing process.  See L{I{parseString}<parseString>} for more information
+        on parsing strings containing C{<TAB>}s, and suggested methods to maintain a
+        consistent view of the parsed string, the parse location, and line and column
+        positions within the parsed string.
+        
+        Example::
+            integer = Word(nums)
+            date_str = integer + '/' + integer + '/' + integer
+
+            date_str.parseString("1999/12/31")  # -> ['1999', '/', '12', '/', '31']
+
+            # use parse action to convert to ints at parse time
+            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
+            date_str = integer + '/' + integer + '/' + integer
+
+            # note that integer fields are now ints, not strings
+            date_str.parseString("1999/12/31")  # -> [1999, '/', 12, '/', 31]
+        """
+        self.parseAction = list(map(_trim_arity, list(fns)))
+        self.callDuringTry = kwargs.get("callDuringTry", False)
+        return self
+
+    def addParseAction( self, *fns, **kwargs ):
+        """
+        Add parse action to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}.
+        
+        See examples in L{I{copy}<copy>}.
+        """
+        self.parseAction += list(map(_trim_arity, list(fns)))
+        self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False)
+        return self
+
+    def addCondition(self, *fns, **kwargs):
+        """Add a boolean predicate function to expression's list of parse actions. See 
+        L{I{setParseAction}<setParseAction>} for function call signatures. Unlike C{setParseAction}, 
+        functions passed to C{addCondition} need to return boolean success/fail of the condition.
+
+        Optional keyword arguments:
+         - message = define a custom message to be used in the raised exception
+         - fatal   = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException
+         
+        Example::
+            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
+            year_int = integer.copy()
+            year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later")
+            date_str = year_int + '/' + integer + '/' + integer
+
+            result = date_str.parseString("1999/12/31")  # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1)
+        """
+        msg = kwargs.get("message", "failed user-defined condition")
+        exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException
+        for fn in fns:
+            def pa(s,l,t):
+                if not bool(_trim_arity(fn)(s,l,t)):
+                    raise exc_type(s,l,msg)
+            self.parseAction.append(pa)
+        self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False)
+        return self
+
+    def setFailAction( self, fn ):
+        """Define action to perform if parsing fails at this expression.
+           Fail acton fn is a callable function that takes the arguments
+           C{fn(s,loc,expr,err)} where:
+            - s = string being parsed
+            - loc = location where expression match was attempted and failed
+            - expr = the parse expression that failed
+            - err = the exception thrown
+           The function returns no value.  It may throw C{L{ParseFatalException}}
+           if it is desired to stop parsing immediately."""
+        self.failAction = fn
+        return self
+
+    def _skipIgnorables( self, instring, loc ):
+        exprsFound = True
+        while exprsFound:
+            exprsFound = False
+            for e in self.ignoreExprs:
+                try:
+                    while 1:
+                        loc,dummy = e._parse( instring, loc )
+                        exprsFound = True
+                except ParseException:
+                    pass
+        return loc
+
+    def preParse( self, instring, loc ):
+        if self.ignoreExprs:
+            loc = self._skipIgnorables( instring, loc )
+
+        if self.skipWhitespace:
+            wt = self.whiteChars
+            instrlen = len(instring)
+            while loc < instrlen and instring[loc] in wt:
+                loc += 1
+
+        return loc
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        return loc, []
+
+    def postParse( self, instring, loc, tokenlist ):
+        return tokenlist
+
+    #~ @profile
+    def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ):
+        debugging = ( self.debug ) #and doActions )
+
+        if debugging or self.failAction:
+            #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))
+            if (self.debugActions[0] ):
+                self.debugActions[0]( instring, loc, self )
+            if callPreParse and self.callPreparse:
+                preloc = self.preParse( instring, loc )
+            else:
+                preloc = loc
+            tokensStart = preloc
+            try:
+                try:
+                    loc,tokens = self.parseImpl( instring, preloc, doActions )
+                except IndexError:
+                    raise ParseException( instring, len(instring), self.errmsg, self )
+            except ParseBaseException as err:
+                #~ print ("Exception raised:", err)
+                if self.debugActions[2]:
+                    self.debugActions[2]( instring, tokensStart, self, err )
+                if self.failAction:
+                    self.failAction( instring, tokensStart, self, err )
+                raise
+        else:
+            if callPreParse and self.callPreparse:
+                preloc = self.preParse( instring, loc )
+            else:
+                preloc = loc
+            tokensStart = preloc
+            if self.mayIndexError or loc >= len(instring):
+                try:
+                    loc,tokens = self.parseImpl( instring, preloc, doActions )
+                except IndexError:
+                    raise ParseException( instring, len(instring), self.errmsg, self )
+            else:
+                loc,tokens = self.parseImpl( instring, preloc, doActions )
+
+        tokens = self.postParse( instring, loc, tokens )
+
+        retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults )
+        if self.parseAction and (doActions or self.callDuringTry):
+            if debugging:
+                try:
+                    for fn in self.parseAction:
+                        tokens = fn( instring, tokensStart, retTokens )
+                        if tokens is not None:
+                            retTokens = ParseResults( tokens,
+                                                      self.resultsName,
+                                                      asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
+                                                      modal=self.modalResults )
+                except ParseBaseException as err:
+                    #~ print "Exception raised in user parse action:", err
+                    if (self.debugActions[2] ):
+                        self.debugActions[2]( instring, tokensStart, self, err )
+                    raise
+            else:
+                for fn in self.parseAction:
+                    tokens = fn( instring, tokensStart, retTokens )
+                    if tokens is not None:
+                        retTokens = ParseResults( tokens,
+                                                  self.resultsName,
+                                                  asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
+                                                  modal=self.modalResults )
+
+        if debugging:
+            #~ print ("Matched",self,"->",retTokens.asList())
+            if (self.debugActions[1] ):
+                self.debugActions[1]( instring, tokensStart, loc, self, retTokens )
+
+        return loc, retTokens
+
+    def tryParse( self, instring, loc ):
+        try:
+            return self._parse( instring, loc, doActions=False )[0]
+        except ParseFatalException:
+            raise ParseException( instring, loc, self.errmsg, self)
+    
+    def canParseNext(self, instring, loc):
+        try:
+            self.tryParse(instring, loc)
+        except (ParseException, IndexError):
+            return False
+        else:
+            return True
+
+    class _UnboundedCache(object):
+        def __init__(self):
+            cache = {}
+            self.not_in_cache = not_in_cache = object()
+
+            def get(self, key):
+                return cache.get(key, not_in_cache)
+
+            def set(self, key, value):
+                cache[key] = value
+
+            def clear(self):
+                cache.clear()
+
+            self.get = types.MethodType(get, self)
+            self.set = types.MethodType(set, self)
+            self.clear = types.MethodType(clear, self)
+
+    if _OrderedDict is not None:
+        class _FifoCache(object):
+            def __init__(self, size):
+                self.not_in_cache = not_in_cache = object()
+
+                cache = _OrderedDict()
+
+                def get(self, key):
+                    return cache.get(key, not_in_cache)
+
+                def set(self, key, value):
+                    cache[key] = value
+                    if len(cache) > size:
+                        cache.popitem(False)
+
+                def clear(self):
+                    cache.clear()
+
+                self.get = types.MethodType(get, self)
+                self.set = types.MethodType(set, self)
+                self.clear = types.MethodType(clear, self)
+
+    else:
+        class _FifoCache(object):
+            def __init__(self, size):
+                self.not_in_cache = not_in_cache = object()
+
+                cache = {}
+                key_fifo = collections.deque([], size)
+
+                def get(self, key):
+                    return cache.get(key, not_in_cache)
+
+                def set(self, key, value):
+                    cache[key] = value
+                    if len(cache) > size:
+                        cache.pop(key_fifo.popleft(), None)
+                    key_fifo.append(key)
+
+                def clear(self):
+                    cache.clear()
+                    key_fifo.clear()
+
+                self.get = types.MethodType(get, self)
+                self.set = types.MethodType(set, self)
+                self.clear = types.MethodType(clear, self)
+
+    # argument cache for optimizing repeated calls when backtracking through recursive expressions
+    packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail
+    packrat_cache_lock = RLock()
+    packrat_cache_stats = [0, 0]
+
+    # this method gets repeatedly called during backtracking with the same arguments -
+    # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression
+    def _parseCache( self, instring, loc, doActions=True, callPreParse=True ):
+        HIT, MISS = 0, 1
+        lookup = (self, instring, loc, callPreParse, doActions)
+        with ParserElement.packrat_cache_lock:
+            cache = ParserElement.packrat_cache
+            value = cache.get(lookup)
+            if value is cache.not_in_cache:
+                ParserElement.packrat_cache_stats[MISS] += 1
+                try:
+                    value = self._parseNoCache(instring, loc, doActions, callPreParse)
+                except ParseBaseException as pe:
+                    # cache a copy of the exception, without the traceback
+                    cache.set(lookup, pe.__class__(*pe.args))
+                    raise
+                else:
+                    cache.set(lookup, (value[0], value[1].copy()))
+                    return value
+            else:
+                ParserElement.packrat_cache_stats[HIT] += 1
+                if isinstance(value, Exception):
+                    raise value
+                return (value[0], value[1].copy())
+
+    _parse = _parseNoCache
+
+    @staticmethod
+    def resetCache():
+        ParserElement.packrat_cache.clear()
+        ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats)
+
+    _packratEnabled = False
+    @staticmethod
+    def enablePackrat(cache_size_limit=128):
+        """Enables "packrat" parsing, which adds memoizing to the parsing logic.
+           Repeated parse attempts at the same string location (which happens
+           often in many complex grammars) can immediately return a cached value,
+           instead of re-executing parsing/validating code.  Memoizing is done of
+           both valid results and parsing exceptions.
+           
+           Parameters:
+            - cache_size_limit - (default=C{128}) - if an integer value is provided
+              will limit the size of the packrat cache; if None is passed, then
+              the cache size will be unbounded; if 0 is passed, the cache will
+              be effectively disabled.
+            
+           This speedup may break existing programs that use parse actions that
+           have side-effects.  For this reason, packrat parsing is disabled when
+           you first import pyparsing.  To activate the packrat feature, your
+           program must call the class method C{ParserElement.enablePackrat()}.  If
+           your program uses C{psyco} to "compile as you go", you must call
+           C{enablePackrat} before calling C{psyco.full()}.  If you do not do this,
+           Python will crash.  For best results, call C{enablePackrat()} immediately
+           after importing pyparsing.
+           
+           Example::
+               import pyparsing
+               pyparsing.ParserElement.enablePackrat()
+        """
+        if not ParserElement._packratEnabled:
+            ParserElement._packratEnabled = True
+            if cache_size_limit is None:
+                ParserElement.packrat_cache = ParserElement._UnboundedCache()
+            else:
+                ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit)
+            ParserElement._parse = ParserElement._parseCache
+
+    def parseString( self, instring, parseAll=False ):
+        """
+        Execute the parse expression with the given string.
+        This is the main interface to the client code, once the complete
+        expression has been built.
+
+        If you want the grammar to require that the entire input string be
+        successfully parsed, then set C{parseAll} to True (equivalent to ending
+        the grammar with C{L{StringEnd()}}).
+
+        Note: C{parseString} implicitly calls C{expandtabs()} on the input string,
+        in order to report proper column numbers in parse actions.
+        If the input string contains tabs and
+        the grammar uses parse actions that use the C{loc} argument to index into the
+        string being parsed, you can ensure you have a consistent view of the input
+        string by:
+         - calling C{parseWithTabs} on your grammar before calling C{parseString}
+           (see L{I{parseWithTabs}<parseWithTabs>})
+         - define your parse action using the full C{(s,loc,toks)} signature, and
+           reference the input string using the parse action's C{s} argument
+         - explictly expand the tabs in your input string before calling
+           C{parseString}
+        
+        Example::
+            Word('a').parseString('aaaaabaaa')  # -> ['aaaaa']
+            Word('a').parseString('aaaaabaaa', parseAll=True)  # -> Exception: Expected end of text
+        """
+        ParserElement.resetCache()
+        if not self.streamlined:
+            self.streamline()
+            #~ self.saveAsList = True
+        for e in self.ignoreExprs:
+            e.streamline()
+        if not self.keepTabs:
+            instring = instring.expandtabs()
+        try:
+            loc, tokens = self._parse( instring, 0 )
+            if parseAll:
+                loc = self.preParse( instring, loc )
+                se = Empty() + StringEnd()
+                se._parse( instring, loc )
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+        else:
+            return tokens
+
+    def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ):
+        """
+        Scan the input string for expression matches.  Each match will return the
+        matching tokens, start location, and end location.  May be called with optional
+        C{maxMatches} argument, to clip scanning after 'n' matches are found.  If
+        C{overlap} is specified, then overlapping matches will be reported.
+
+        Note that the start and end locations are reported relative to the string
+        being parsed.  See L{I{parseString}<parseString>} for more information on parsing
+        strings with embedded tabs.
+
+        Example::
+            source = "sldjf123lsdjjkf345sldkjf879lkjsfd987"
+            print(source)
+            for tokens,start,end in Word(alphas).scanString(source):
+                print(' '*start + '^'*(end-start))
+                print(' '*start + tokens[0])
+        
+        prints::
+        
+            sldjf123lsdjjkf345sldkjf879lkjsfd987
+            ^^^^^
+            sldjf
+                    ^^^^^^^
+                    lsdjjkf
+                              ^^^^^^
+                              sldkjf
+                                       ^^^^^^
+                                       lkjsfd
+        """
+        if not self.streamlined:
+            self.streamline()
+        for e in self.ignoreExprs:
+            e.streamline()
+
+        if not self.keepTabs:
+            instring = _ustr(instring).expandtabs()
+        instrlen = len(instring)
+        loc = 0
+        preparseFn = self.preParse
+        parseFn = self._parse
+        ParserElement.resetCache()
+        matches = 0
+        try:
+            while loc <= instrlen and matches < maxMatches:
+                try:
+                    preloc = preparseFn( instring, loc )
+                    nextLoc,tokens = parseFn( instring, preloc, callPreParse=False )
+                except ParseException:
+                    loc = preloc+1
+                else:
+                    if nextLoc > loc:
+                        matches += 1
+                        yield tokens, preloc, nextLoc
+                        if overlap:
+                            nextloc = preparseFn( instring, loc )
+                            if nextloc > loc:
+                                loc = nextLoc
+                            else:
+                                loc += 1
+                        else:
+                            loc = nextLoc
+                    else:
+                        loc = preloc+1
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def transformString( self, instring ):
+        """
+        Extension to C{L{scanString}}, to modify matching text with modified tokens that may
+        be returned from a parse action.  To use C{transformString}, define a grammar and
+        attach a parse action to it that modifies the returned token list.
+        Invoking C{transformString()} on a target string will then scan for matches,
+        and replace the matched text patterns according to the logic in the parse
+        action.  C{transformString()} returns the resulting transformed string.
+        
+        Example::
+            wd = Word(alphas)
+            wd.setParseAction(lambda toks: toks[0].title())
+            
+            print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york."))
+        Prints::
+            Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York.
+        """
+        out = []
+        lastE = 0
+        # force preservation of <TAB>s, to minimize unwanted transformation of string, and to
+        # keep string locs straight between transformString and scanString
+        self.keepTabs = True
+        try:
+            for t,s,e in self.scanString( instring ):
+                out.append( instring[lastE:s] )
+                if t:
+                    if isinstance(t,ParseResults):
+                        out += t.asList()
+                    elif isinstance(t,list):
+                        out += t
+                    else:
+                        out.append(t)
+                lastE = e
+            out.append(instring[lastE:])
+            out = [o for o in out if o]
+            return "".join(map(_ustr,_flatten(out)))
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def searchString( self, instring, maxMatches=_MAX_INT ):
+        """
+        Another extension to C{L{scanString}}, simplifying the access to the tokens found
+        to match the given parse expression.  May be called with optional
+        C{maxMatches} argument, to clip searching after 'n' matches are found.
+        
+        Example::
+            # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters
+            cap_word = Word(alphas.upper(), alphas.lower())
+            
+            print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))
+        prints::
+            ['More', 'Iron', 'Lead', 'Gold', 'I']
+        """
+        try:
+            return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ])
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False):
+        """
+        Generator method to split a string using the given expression as a separator.
+        May be called with optional C{maxsplit} argument, to limit the number of splits;
+        and the optional C{includeSeparators} argument (default=C{False}), if the separating
+        matching text should be included in the split results.
+        
+        Example::        
+            punc = oneOf(list(".,;:/-!?"))
+            print(list(punc.split("This, this?, this sentence, is badly punctuated!")))
+        prints::
+            ['This', ' this', '', ' this sentence', ' is badly punctuated', '']
+        """
+        splits = 0
+        last = 0
+        for t,s,e in self.scanString(instring, maxMatches=maxsplit):
+            yield instring[last:s]
+            if includeSeparators:
+                yield t[0]
+            last = e
+        yield instring[last:]
+
+    def __add__(self, other ):
+        """
+        Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement
+        converts them to L{Literal}s by default.
+        
+        Example::
+            greet = Word(alphas) + "," + Word(alphas) + "!"
+            hello = "Hello, World!"
+            print (hello, "->", greet.parseString(hello))
+        Prints::
+            Hello, World! -> ['Hello', ',', 'World', '!']
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return And( [ self, other ] )
+
+    def __radd__(self, other ):
+        """
+        Implementation of + operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other + self
+
+    def __sub__(self, other):
+        """
+        Implementation of - operator, returns C{L{And}} with error stop
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return And( [ self, And._ErrorStop(), other ] )
+
+    def __rsub__(self, other ):
+        """
+        Implementation of - operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other - self
+
+    def __mul__(self,other):
+        """
+        Implementation of * operator, allows use of C{expr * 3} in place of
+        C{expr + expr + expr}.  Expressions may also me multiplied by a 2-integer
+        tuple, similar to C{{min,max}} multipliers in regular expressions.  Tuples
+        may also include C{None} as in:
+         - C{expr*(n,None)} or C{expr*(n,)} is equivalent
+              to C{expr*n + L{ZeroOrMore}(expr)}
+              (read as "at least n instances of C{expr}")
+         - C{expr*(None,n)} is equivalent to C{expr*(0,n)}
+              (read as "0 to n instances of C{expr}")
+         - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)}
+         - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)}
+
+        Note that C{expr*(None,n)} does not raise an exception if
+        more than n exprs exist in the input stream; that is,
+        C{expr*(None,n)} does not enforce a maximum number of expr
+        occurrences.  If this behavior is desired, then write
+        C{expr*(None,n) + ~expr}
+        """
+        if isinstance(other,int):
+            minElements, optElements = other,0
+        elif isinstance(other,tuple):
+            other = (other + (None, None))[:2]
+            if other[0] is None:
+                other = (0, other[1])
+            if isinstance(other[0],int) and other[1] is None:
+                if other[0] == 0:
+                    return ZeroOrMore(self)
+                if other[0] == 1:
+                    return OneOrMore(self)
+                else:
+                    return self*other[0] + ZeroOrMore(self)
+            elif isinstance(other[0],int) and isinstance(other[1],int):
+                minElements, optElements = other
+                optElements -= minElements
+            else:
+                raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1]))
+        else:
+            raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other))
+
+        if minElements < 0:
+            raise ValueError("cannot multiply ParserElement by negative value")
+        if optElements < 0:
+            raise ValueError("second tuple value must be greater or equal to first tuple value")
+        if minElements == optElements == 0:
+            raise ValueError("cannot multiply ParserElement by 0 or (0,0)")
+
+        if (optElements):
+            def makeOptionalList(n):
+                if n>1:
+                    return Optional(self + makeOptionalList(n-1))
+                else:
+                    return Optional(self)
+            if minElements:
+                if minElements == 1:
+                    ret = self + makeOptionalList(optElements)
+                else:
+                    ret = And([self]*minElements) + makeOptionalList(optElements)
+            else:
+                ret = makeOptionalList(optElements)
+        else:
+            if minElements == 1:
+                ret = self
+            else:
+                ret = And([self]*minElements)
+        return ret
+
+    def __rmul__(self, other):
+        return self.__mul__(other)
+
+    def __or__(self, other ):
+        """
+        Implementation of | operator - returns C{L{MatchFirst}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return MatchFirst( [ self, other ] )
+
+    def __ror__(self, other ):
+        """
+        Implementation of | operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other | self
+
+    def __xor__(self, other ):
+        """
+        Implementation of ^ operator - returns C{L{Or}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return Or( [ self, other ] )
+
+    def __rxor__(self, other ):
+        """
+        Implementation of ^ operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other ^ self
+
+    def __and__(self, other ):
+        """
+        Implementation of & operator - returns C{L{Each}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return Each( [ self, other ] )
+
+    def __rand__(self, other ):
+        """
+        Implementation of & operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other & self
+
+    def __invert__( self ):
+        """
+        Implementation of ~ operator - returns C{L{NotAny}}
+        """
+        return NotAny( self )
+
+    def __call__(self, name=None):
+        """
+        Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}.
+        
+        If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be
+        passed as C{True}.
+           
+        If C{name} is omitted, same as calling C{L{copy}}.
+
+        Example::
+            # these are equivalent
+            userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno")
+            userdata = Word(alphas)("name") + Word(nums+"-")("socsecno")             
+        """
+        if name is not None:
+            return self.setResultsName(name)
+        else:
+            return self.copy()
+
+    def suppress( self ):
+        """
+        Suppresses the output of this C{ParserElement}; useful to keep punctuation from
+        cluttering up returned output.
+        """
+        return Suppress( self )
+
+    def leaveWhitespace( self ):
+        """
+        Disables the skipping of whitespace before matching the characters in the
+        C{ParserElement}'s defined pattern.  This is normally only used internally by
+        the pyparsing module, but may be needed in some whitespace-sensitive grammars.
+        """
+        self.skipWhitespace = False
+        return self
+
+    def setWhitespaceChars( self, chars ):
+        """
+        Overrides the default whitespace chars
+        """
+        self.skipWhitespace = True
+        self.whiteChars = chars
+        self.copyDefaultWhiteChars = False
+        return self
+
+    def parseWithTabs( self ):
+        """
+        Overrides default behavior to expand C{<TAB>}s to spaces before parsing the input string.
+        Must be called before C{parseString} when the input grammar contains elements that
+        match C{<TAB>} characters.
+        """
+        self.keepTabs = True
+        return self
+
+    def ignore( self, other ):
+        """
+        Define expression to be ignored (e.g., comments) while doing pattern
+        matching; may be called repeatedly, to define multiple comment or other
+        ignorable patterns.
+        
+        Example::
+            patt = OneOrMore(Word(alphas))
+            patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj']
+            
+            patt.ignore(cStyleComment)
+            patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd']
+        """
+        if isinstance(other, basestring):
+            other = Suppress(other)
+
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                self.ignoreExprs.append(other)
+        else:
+            self.ignoreExprs.append( Suppress( other.copy() ) )
+        return self
+
+    def setDebugActions( self, startAction, successAction, exceptionAction ):
+        """
+        Enable display of debugging messages while doing pattern matching.
+        """
+        self.debugActions = (startAction or _defaultStartDebugAction,
+                             successAction or _defaultSuccessDebugAction,
+                             exceptionAction or _defaultExceptionDebugAction)
+        self.debug = True
+        return self
+
+    def setDebug( self, flag=True ):
+        """
+        Enable display of debugging messages while doing pattern matching.
+        Set C{flag} to True to enable, False to disable.
+
+        Example::
+            wd = Word(alphas).setName("alphaword")
+            integer = Word(nums).setName("numword")
+            term = wd | integer
+            
+            # turn on debugging for wd
+            wd.setDebug()
+
+            OneOrMore(term).parseString("abc 123 xyz 890")
+        
+        prints::
+            Match alphaword at loc 0(1,1)
+            Matched alphaword -> ['abc']
+            Match alphaword at loc 3(1,4)
+            Exception raised:Expected alphaword (at char 4), (line:1, col:5)
+            Match alphaword at loc 7(1,8)
+            Matched alphaword -> ['xyz']
+            Match alphaword at loc 11(1,12)
+            Exception raised:Expected alphaword (at char 12), (line:1, col:13)
+            Match alphaword at loc 15(1,16)
+            Exception raised:Expected alphaword (at char 15), (line:1, col:16)
+
+        The output shown is that produced by the default debug actions - custom debug actions can be
+        specified using L{setDebugActions}. Prior to attempting
+        to match the C{wd} expression, the debugging message C{"Match <exprname> at loc <n>(<line>,<col>)"}
+        is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"}
+        message is shown. Also note the use of L{setName} to assign a human-readable name to the expression,
+        which makes debugging and exception messages easier to understand - for instance, the default
+        name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}.
+        """
+        if flag:
+            self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction )
+        else:
+            self.debug = False
+        return self
+
+    def __str__( self ):
+        return self.name
+
+    def __repr__( self ):
+        return _ustr(self)
+
+    def streamline( self ):
+        self.streamlined = True
+        self.strRepr = None
+        return self
+
+    def checkRecursion( self, parseElementList ):
+        pass
+
+    def validate( self, validateTrace=[] ):
+        """
+        Check defined expressions for valid structure, check for infinite recursive definitions.
+        """
+        self.checkRecursion( [] )
+
+    def parseFile( self, file_or_filename, parseAll=False ):
+        """
+        Execute the parse expression on the given file or filename.
+        If a filename is specified (instead of a file object),
+        the entire file is opened, read, and closed before parsing.
+        """
+        try:
+            file_contents = file_or_filename.read()
+        except AttributeError:
+            with open(file_or_filename, "r") as f:
+                file_contents = f.read()
+        try:
+            return self.parseString(file_contents, parseAll)
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def __eq__(self,other):
+        if isinstance(other, ParserElement):
+            return self is other or vars(self) == vars(other)
+        elif isinstance(other, basestring):
+            return self.matches(other)
+        else:
+            return super(ParserElement,self)==other
+
+    def __ne__(self,other):
+        return not (self == other)
+
+    def __hash__(self):
+        return hash(id(self))
+
+    def __req__(self,other):
+        return self == other
+
+    def __rne__(self,other):
+        return not (self == other)
+
+    def matches(self, testString, parseAll=True):
+        """
+        Method for quick testing of a parser against a test string. Good for simple 
+        inline microtests of sub expressions while building up larger parser.
+           
+        Parameters:
+         - testString - to test against this expression for a match
+         - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests
+            
+        Example::
+            expr = Word(nums)
+            assert expr.matches("100")
+        """
+        try:
+            self.parseString(_ustr(testString), parseAll=parseAll)
+            return True
+        except ParseBaseException:
+            return False
+                
+    def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False):
+        """
+        Execute the parse expression on a series of test strings, showing each
+        test, the parsed results or where the parse failed. Quick and easy way to
+        run a parse expression against a list of sample strings.
+           
+        Parameters:
+         - tests - a list of separate test strings, or a multiline string of test strings
+         - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests           
+         - comment - (default=C{'#'}) - expression for indicating embedded comments in the test 
+              string; pass None to disable comment filtering
+         - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline;
+              if False, only dump nested list
+         - printResults - (default=C{True}) prints test output to stdout
+         - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing
+
+        Returns: a (success, results) tuple, where success indicates that all tests succeeded
+        (or failed if C{failureTests} is True), and the results contain a list of lines of each 
+        test's output
+        
+        Example::
+            number_expr = pyparsing_common.number.copy()
+
+            result = number_expr.runTests('''
+                # unsigned integer
+                100
+                # negative integer
+                -100
+                # float with scientific notation
+                6.02e23
+                # integer with scientific notation
+                1e-12
+                ''')
+            print("Success" if result[0] else "Failed!")
+
+            result = number_expr.runTests('''
+                # stray character
+                100Z
+                # missing leading digit before '.'
+                -.100
+                # too many '.'
+                3.14.159
+                ''', failureTests=True)
+            print("Success" if result[0] else "Failed!")
+        prints::
+            # unsigned integer
+            100
+            [100]
+
+            # negative integer
+            -100
+            [-100]
+
+            # float with scientific notation
+            6.02e23
+            [6.02e+23]
+
+            # integer with scientific notation
+            1e-12
+            [1e-12]
+
+            Success
+            
+            # stray character
+            100Z
+               ^
+            FAIL: Expected end of text (at char 3), (line:1, col:4)
+
+            # missing leading digit before '.'
+            -.100
+            ^
+            FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1)
+
+            # too many '.'
+            3.14.159
+                ^
+            FAIL: Expected end of text (at char 4), (line:1, col:5)
+
+            Success
+
+        Each test string must be on a single line. If you want to test a string that spans multiple
+        lines, create a test like this::
+
+            expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines")
+        
+        (Note that this is a raw string literal, you must include the leading 'r'.)
+        """
+        if isinstance(tests, basestring):
+            tests = list(map(str.strip, tests.rstrip().splitlines()))
+        if isinstance(comment, basestring):
+            comment = Literal(comment)
+        allResults = []
+        comments = []
+        success = True
+        for t in tests:
+            if comment is not None and comment.matches(t, False) or comments and not t:
+                comments.append(t)
+                continue
+            if not t:
+                continue
+            out = ['\n'.join(comments), t]
+            comments = []
+            try:
+                t = t.replace(r'\n','\n')
+                result = self.parseString(t, parseAll=parseAll)
+                out.append(result.dump(full=fullDump))
+                success = success and not failureTests
+            except ParseBaseException as pe:
+                fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else ""
+                if '\n' in t:
+                    out.append(line(pe.loc, t))
+                    out.append(' '*(col(pe.loc,t)-1) + '^' + fatal)
+                else:
+                    out.append(' '*pe.loc + '^' + fatal)
+                out.append("FAIL: " + str(pe))
+                success = success and failureTests
+                result = pe
+            except Exception as exc:
+                out.append("FAIL-EXCEPTION: " + str(exc))
+                success = success and failureTests
+                result = exc
+
+            if printResults:
+                if fullDump:
+                    out.append('')
+                print('\n'.join(out))
+
+            allResults.append((t, result))
+        
+        return success, allResults
+
+        
+class Token(ParserElement):
+    """
+    Abstract C{ParserElement} subclass, for defining atomic matching patterns.
+    """
+    def __init__( self ):
+        super(Token,self).__init__( savelist=False )
+
+
+class Empty(Token):
+    """
+    An empty token, will always match.
+    """
+    def __init__( self ):
+        super(Empty,self).__init__()
+        self.name = "Empty"
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+
+
+class NoMatch(Token):
+    """
+    A token that will never match.
+    """
+    def __init__( self ):
+        super(NoMatch,self).__init__()
+        self.name = "NoMatch"
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+        self.errmsg = "Unmatchable token"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        raise ParseException(instring, loc, self.errmsg, self)
+
+
+class Literal(Token):
+    """
+    Token to exactly match a specified string.
+    
+    Example::
+        Literal('blah').parseString('blah')  # -> ['blah']
+        Literal('blah').parseString('blahfooblah')  # -> ['blah']
+        Literal('blah').parseString('bla')  # -> Exception: Expected "blah"
+    
+    For case-insensitive matching, use L{CaselessLiteral}.
+    
+    For keyword matching (force word break before and after the matched string),
+    use L{Keyword} or L{CaselessKeyword}.
+    """
+    def __init__( self, matchString ):
+        super(Literal,self).__init__()
+        self.match = matchString
+        self.matchLen = len(matchString)
+        try:
+            self.firstMatchChar = matchString[0]
+        except IndexError:
+            warnings.warn("null string passed to Literal; use Empty() instead",
+                            SyntaxWarning, stacklevel=2)
+            self.__class__ = Empty
+        self.name = '"%s"' % _ustr(self.match)
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = False
+        self.mayIndexError = False
+
+    # Performance tuning: this routine gets called a *lot*
+    # if this is a single character match string  and the first character matches,
+    # short-circuit as quickly as possible, and avoid calling startswith
+    #~ @profile
+    def parseImpl( self, instring, loc, doActions=True ):
+        if (instring[loc] == self.firstMatchChar and
+            (self.matchLen==1 or instring.startswith(self.match,loc)) ):
+            return loc+self.matchLen, self.match
+        raise ParseException(instring, loc, self.errmsg, self)
+_L = Literal
+ParserElement._literalStringClass = Literal
+
+class Keyword(Token):
+    """
+    Token to exactly match a specified string as a keyword, that is, it must be
+    immediately followed by a non-keyword character.  Compare with C{L{Literal}}:
+     - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}.
+     - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'}
+    Accepts two optional constructor arguments in addition to the keyword string:
+     - C{identChars} is a string of characters that would be valid identifier characters,
+          defaulting to all alphanumerics + "_" and "$"
+     - C{caseless} allows case-insensitive matching, default is C{False}.
+       
+    Example::
+        Keyword("start").parseString("start")  # -> ['start']
+        Keyword("start").parseString("starting")  # -> Exception
+
+    For case-insensitive matching, use L{CaselessKeyword}.
+    """
+    DEFAULT_KEYWORD_CHARS = alphanums+"_$"
+
+    def __init__( self, matchString, identChars=None, caseless=False ):
+        super(Keyword,self).__init__()
+        if identChars is None:
+            identChars = Keyword.DEFAULT_KEYWORD_CHARS
+        self.match = matchString
+        self.matchLen = len(matchString)
+        try:
+            self.firstMatchChar = matchString[0]
+        except IndexError:
+            warnings.warn("null string passed to Keyword; use Empty() instead",
+                            SyntaxWarning, stacklevel=2)
+        self.name = '"%s"' % self.match
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = False
+        self.mayIndexError = False
+        self.caseless = caseless
+        if caseless:
+            self.caselessmatch = matchString.upper()
+            identChars = identChars.upper()
+        self.identChars = set(identChars)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.caseless:
+            if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
+                 (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and
+                 (loc == 0 or instring[loc-1].upper() not in self.identChars) ):
+                return loc+self.matchLen, self.match
+        else:
+            if (instring[loc] == self.firstMatchChar and
+                (self.matchLen==1 or instring.startswith(self.match,loc)) and
+                (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and
+                (loc == 0 or instring[loc-1] not in self.identChars) ):
+                return loc+self.matchLen, self.match
+        raise ParseException(instring, loc, self.errmsg, self)
+
+    def copy(self):
+        c = super(Keyword,self).copy()
+        c.identChars = Keyword.DEFAULT_KEYWORD_CHARS
+        return c
+
+    @staticmethod
+    def setDefaultKeywordChars( chars ):
+        """Overrides the default Keyword chars
+        """
+        Keyword.DEFAULT_KEYWORD_CHARS = chars
+
+class CaselessLiteral(Literal):
+    """
+    Token to match a specified string, ignoring case of letters.
+    Note: the matched results will always be in the case of the given
+    match string, NOT the case of the input text.
+
+    Example::
+        OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD']
+        
+    (Contrast with example for L{CaselessKeyword}.)
+    """
+    def __init__( self, matchString ):
+        super(CaselessLiteral,self).__init__( matchString.upper() )
+        # Preserve the defining literal.
+        self.returnString = matchString
+        self.name = "'%s'" % self.returnString
+        self.errmsg = "Expected " + self.name
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if instring[ loc:loc+self.matchLen ].upper() == self.match:
+            return loc+self.matchLen, self.returnString
+        raise ParseException(instring, loc, self.errmsg, self)
+
+class CaselessKeyword(Keyword):
+    """
+    Caseless version of L{Keyword}.
+
+    Example::
+        OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD']
+        
+    (Contrast with example for L{CaselessLiteral}.)
+    """
+    def __init__( self, matchString, identChars=None ):
+        super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True )
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
+             (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ):
+            return loc+self.matchLen, self.match
+        raise ParseException(instring, loc, self.errmsg, self)
+
+class CloseMatch(Token):
+    """
+    A variation on L{Literal} which matches "close" matches, that is, 
+    strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters:
+     - C{match_string} - string to be matched
+     - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match
+    
+    The results from a successful parse will contain the matched text from the input string and the following named results:
+     - C{mismatches} - a list of the positions within the match_string where mismatches were found
+     - C{original} - the original match_string used to compare against the input string
+    
+    If C{mismatches} is an empty list, then the match was an exact match.
+    
+    Example::
+        patt = CloseMatch("ATCATCGAATGGA")
+        patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']})
+        patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1)
+
+        # exact match
+        patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']})
+
+        # close match allowing up to 2 mismatches
+        patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2)
+        patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']})
+    """
+    def __init__(self, match_string, maxMismatches=1):
+        super(CloseMatch,self).__init__()
+        self.name = match_string
+        self.match_string = match_string
+        self.maxMismatches = maxMismatches
+        self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches)
+        self.mayIndexError = False
+        self.mayReturnEmpty = False
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        start = loc
+        instrlen = len(instring)
+        maxloc = start + len(self.match_string)
+
+        if maxloc <= instrlen:
+            match_string = self.match_string
+            match_stringloc = 0
+            mismatches = []
+            maxMismatches = self.maxMismatches
+
+            for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)):
+                src,mat = s_m
+                if src != mat:
+                    mismatches.append(match_stringloc)
+                    if len(mismatches) > maxMismatches:
+                        break
+            else:
+                loc = match_stringloc + 1
+                results = ParseResults([instring[start:loc]])
+                results['original'] = self.match_string
+                results['mismatches'] = mismatches
+                return loc, results
+
+        raise ParseException(instring, loc, self.errmsg, self)
+
+
+class Word(Token):
+    """
+    Token for matching words composed of allowed character sets.
+    Defined with string containing all allowed initial characters,
+    an optional string containing allowed body characters (if omitted,
+    defaults to the initial character set), and an optional minimum,
+    maximum, and/or exact length.  The default value for C{min} is 1 (a
+    minimum value < 1 is not valid); the default values for C{max} and C{exact}
+    are 0, meaning no maximum or exact length restriction. An optional
+    C{excludeChars} parameter can list characters that might be found in 
+    the input C{bodyChars} string; useful to define a word of all printables
+    except for one or two characters, for instance.
+    
+    L{srange} is useful for defining custom character set strings for defining 
+    C{Word} expressions, using range notation from regular expression character sets.
+    
+    A common mistake is to use C{Word} to match a specific literal string, as in 
+    C{Word("Address")}. Remember that C{Word} uses the string argument to define
+    I{sets} of matchable characters. This expression would match "Add", "AAA",
+    "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'.
+    To match an exact literal string, use L{Literal} or L{Keyword}.
+
+    pyparsing includes helper strings for building Words:
+     - L{alphas}
+     - L{nums}
+     - L{alphanums}
+     - L{hexnums}
+     - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.)
+     - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.)
+     - L{printables} (any non-whitespace character)
+
+    Example::
+        # a word composed of digits
+        integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9"))
+        
+        # a word with a leading capital, and zero or more lowercase
+        capital_word = Word(alphas.upper(), alphas.lower())
+
+        # hostnames are alphanumeric, with leading alpha, and '-'
+        hostname = Word(alphas, alphanums+'-')
+        
+        # roman numeral (not a strict parser, accepts invalid mix of characters)
+        roman = Word("IVXLCDM")
+        
+        # any string of non-whitespace characters, except for ','
+        csv_value = Word(printables, excludeChars=",")
+    """
+    def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ):
+        super(Word,self).__init__()
+        if excludeChars:
+            initChars = ''.join(c for c in initChars if c not in excludeChars)
+            if bodyChars:
+                bodyChars = ''.join(c for c in bodyChars if c not in excludeChars)
+        self.initCharsOrig = initChars
+        self.initChars = set(initChars)
+        if bodyChars :
+            self.bodyCharsOrig = bodyChars
+            self.bodyChars = set(bodyChars)
+        else:
+            self.bodyCharsOrig = initChars
+            self.bodyChars = set(initChars)
+
+        self.maxSpecified = max > 0
+
+        if min < 1:
+            raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted")
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayIndexError = False
+        self.asKeyword = asKeyword
+
+        if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0):
+            if self.bodyCharsOrig == self.initCharsOrig:
+                self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig)
+            elif len(self.initCharsOrig) == 1:
+                self.reString = "%s[%s]*" % \
+                                      (re.escape(self.initCharsOrig),
+                                      _escapeRegexRangeChars(self.bodyCharsOrig),)
+            else:
+                self.reString = "[%s][%s]*" % \
+                                      (_escapeRegexRangeChars(self.initCharsOrig),
+                                      _escapeRegexRangeChars(self.bodyCharsOrig),)
+            if self.asKeyword:
+                self.reString = r"\b"+self.reString+r"\b"
+            try:
+                self.re = re.compile( self.reString )
+            except Exception:
+                self.re = None
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.re:
+            result = self.re.match(instring,loc)
+            if not result:
+                raise ParseException(instring, loc, self.errmsg, self)
+
+            loc = result.end()
+            return loc, result.group()
+
+        if not(instring[ loc ] in self.initChars):
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        start = loc
+        loc += 1
+        instrlen = len(instring)
+        bodychars = self.bodyChars
+        maxloc = start + self.maxLen
+        maxloc = min( maxloc, instrlen )
+        while loc < maxloc and instring[loc] in bodychars:
+            loc += 1
+
+        throwException = False
+        if loc - start < self.minLen:
+            throwException = True
+        if self.maxSpecified and loc < instrlen and instring[loc] in bodychars:
+            throwException = True
+        if self.asKeyword:
+            if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars):
+                throwException = True
+
+        if throwException:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        return loc, instring[start:loc]
+
+    def __str__( self ):
+        try:
+            return super(Word,self).__str__()
+        except Exception:
+            pass
+
+
+        if self.strRepr is None:
+
+            def charsAsStr(s):
+                if len(s)>4:
+                    return s[:4]+"..."
+                else:
+                    return s
+
+            if ( self.initCharsOrig != self.bodyCharsOrig ):
+                self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) )
+            else:
+                self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig)
+
+        return self.strRepr
+
+
+class Regex(Token):
+    """
+    Token for matching strings that match a given regular expression.
+    Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module.
+    If the given regex contains named groups (defined using C{(?P<name>...)}), these will be preserved as 
+    named parse results.
+
+    Example::
+        realnum = Regex(r"[+-]?\d+\.\d*")
+        date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)')
+        # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression
+        roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})")
+    """
+    compiledREtype = type(re.compile("[A-Z]"))
+    def __init__( self, pattern, flags=0):
+        """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags."""
+        super(Regex,self).__init__()
+
+        if isinstance(pattern, basestring):
+            if not pattern:
+                warnings.warn("null string passed to Regex; use Empty() instead",
+                        SyntaxWarning, stacklevel=2)
+
+            self.pattern = pattern
+            self.flags = flags
+
+            try:
+                self.re = re.compile(self.pattern, self.flags)
+                self.reString = self.pattern
+            except sre_constants.error:
+                warnings.warn("invalid pattern (%s) passed to Regex" % pattern,
+                    SyntaxWarning, stacklevel=2)
+                raise
+
+        elif isinstance(pattern, Regex.compiledREtype):
+            self.re = pattern
+            self.pattern = \
+            self.reString = str(pattern)
+            self.flags = flags
+            
+        else:
+            raise ValueError("Regex may only be constructed with a string or a compiled RE object")
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayIndexError = False
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        result = self.re.match(instring,loc)
+        if not result:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        loc = result.end()
+        d = result.groupdict()
+        ret = ParseResults(result.group())
+        if d:
+            for k in d:
+                ret[k] = d[k]
+        return loc,ret
+
+    def __str__( self ):
+        try:
+            return super(Regex,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "Re:(%s)" % repr(self.pattern)
+
+        return self.strRepr
+
+
+class QuotedString(Token):
+    r"""
+    Token for matching strings that are delimited by quoting characters.
+    
+    Defined with the following parameters:
+        - quoteChar - string of one or more characters defining the quote delimiting string
+        - escChar - character to escape quotes, typically backslash (default=C{None})
+        - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None})
+        - multiline - boolean indicating whether quotes can span multiple lines (default=C{False})
+        - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True})
+        - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar)
+        - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True})
+
+    Example::
+        qs = QuotedString('"')
+        print(qs.searchString('lsjdf "This is the quote" sldjf'))
+        complex_qs = QuotedString('{{', endQuoteChar='}}')
+        print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf'))
+        sql_qs = QuotedString('"', escQuote='""')
+        print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf'))
+    prints::
+        [['This is the quote']]
+        [['This is the "quote"']]
+        [['This is the quote with "embedded" quotes']]
+    """
+    def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True):
+        super(QuotedString,self).__init__()
+
+        # remove white space from quote chars - wont work anyway
+        quoteChar = quoteChar.strip()
+        if not quoteChar:
+            warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
+            raise SyntaxError()
+
+        if endQuoteChar is None:
+            endQuoteChar = quoteChar
+        else:
+            endQuoteChar = endQuoteChar.strip()
+            if not endQuoteChar:
+                warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
+                raise SyntaxError()
+
+        self.quoteChar = quoteChar
+        self.quoteCharLen = len(quoteChar)
+        self.firstQuoteChar = quoteChar[0]
+        self.endQuoteChar = endQuoteChar
+        self.endQuoteCharLen = len(endQuoteChar)
+        self.escChar = escChar
+        self.escQuote = escQuote
+        self.unquoteResults = unquoteResults
+        self.convertWhitespaceEscapes = convertWhitespaceEscapes
+
+        if multiline:
+            self.flags = re.MULTILINE | re.DOTALL
+            self.pattern = r'%s(?:[^%s%s]' % \
+                ( re.escape(self.quoteChar),
+                  _escapeRegexRangeChars(self.endQuoteChar[0]),
+                  (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
+        else:
+            self.flags = 0
+            self.pattern = r'%s(?:[^%s\n\r%s]' % \
+                ( re.escape(self.quoteChar),
+                  _escapeRegexRangeChars(self.endQuoteChar[0]),
+                  (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
+        if len(self.endQuoteChar) > 1:
+            self.pattern += (
+                '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]),
+                                               _escapeRegexRangeChars(self.endQuoteChar[i]))
+                                    for i in range(len(self.endQuoteChar)-1,0,-1)) + ')'
+                )
+        if escQuote:
+            self.pattern += (r'|(?:%s)' % re.escape(escQuote))
+        if escChar:
+            self.pattern += (r'|(?:%s.)' % re.escape(escChar))
+            self.escCharReplacePattern = re.escape(self.escChar)+"(.)"
+        self.pattern += (r')*%s' % re.escape(self.endQuoteChar))
+
+        try:
+            self.re = re.compile(self.pattern, self.flags)
+            self.reString = self.pattern
+        except sre_constants.error:
+            warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern,
+                SyntaxWarning, stacklevel=2)
+            raise
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayIndexError = False
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None
+        if not result:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        loc = result.end()
+        ret = result.group()
+
+        if self.unquoteResults:
+
+            # strip off quotes
+            ret = ret[self.quoteCharLen:-self.endQuoteCharLen]
+
+            if isinstance(ret,basestring):
+                # replace escaped whitespace
+                if '\\' in ret and self.convertWhitespaceEscapes:
+                    ws_map = {
+                        r'\t' : '\t',
+                        r'\n' : '\n',
+                        r'\f' : '\f',
+                        r'\r' : '\r',
+                    }
+                    for wslit,wschar in ws_map.items():
+                        ret = ret.replace(wslit, wschar)
+
+                # replace escaped characters
+                if self.escChar:
+                    ret = re.sub(self.escCharReplacePattern,"\g<1>",ret)
+
+                # replace escaped quotes
+                if self.escQuote:
+                    ret = ret.replace(self.escQuote, self.endQuoteChar)
+
+        return loc, ret
+
+    def __str__( self ):
+        try:
+            return super(QuotedString,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar)
+
+        return self.strRepr
+
+
+class CharsNotIn(Token):
+    """
+    Token for matching words composed of characters I{not} in a given set (will
+    include whitespace in matched characters if not listed in the provided exclusion set - see example).
+    Defined with string containing all disallowed characters, and an optional
+    minimum, maximum, and/or exact length.  The default value for C{min} is 1 (a
+    minimum value < 1 is not valid); the default values for C{max} and C{exact}
+    are 0, meaning no maximum or exact length restriction.
+
+    Example::
+        # define a comma-separated-value as anything that is not a ','
+        csv_value = CharsNotIn(',')
+        print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213"))
+    prints::
+        ['dkls', 'lsdkjf', 's12 34', '@!#', '213']
+    """
+    def __init__( self, notChars, min=1, max=0, exact=0 ):
+        super(CharsNotIn,self).__init__()
+        self.skipWhitespace = False
+        self.notChars = notChars
+
+        if min < 1:
+            raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted")
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = ( self.minLen == 0 )
+        self.mayIndexError = False
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if instring[loc] in self.notChars:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        start = loc
+        loc += 1
+        notchars = self.notChars
+        maxlen = min( start+self.maxLen, len(instring) )
+        while loc < maxlen and \
+              (instring[loc] not in notchars):
+            loc += 1
+
+        if loc - start < self.minLen:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        return loc, instring[start:loc]
+
+    def __str__( self ):
+        try:
+            return super(CharsNotIn, self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            if len(self.notChars) > 4:
+                self.strRepr = "!W:(%s...)" % self.notChars[:4]
+            else:
+                self.strRepr = "!W:(%s)" % self.notChars
+
+        return self.strRepr
+
+class White(Token):
+    """
+    Special matching class for matching whitespace.  Normally, whitespace is ignored
+    by pyparsing grammars.  This class is included when some whitespace structures
+    are significant.  Define with a string containing the whitespace characters to be
+    matched; default is C{" \\t\\r\\n"}.  Also takes optional C{min}, C{max}, and C{exact} arguments,
+    as defined for the C{L{Word}} class.
+    """
+    whiteStrs = {
+        " " : "<SPC>",
+        "\t": "<TAB>",
+        "\n": "<LF>",
+        "\r": "<CR>",
+        "\f": "<FF>",
+        }
+    def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0):
+        super(White,self).__init__()
+        self.matchWhite = ws
+        self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) )
+        #~ self.leaveWhitespace()
+        self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite))
+        self.mayReturnEmpty = True
+        self.errmsg = "Expected " + self.name
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if not(instring[ loc ] in self.matchWhite):
+            raise ParseException(instring, loc, self.errmsg, self)
+        start = loc
+        loc += 1
+        maxloc = start + self.maxLen
+        maxloc = min( maxloc, len(instring) )
+        while loc < maxloc and instring[loc] in self.matchWhite:
+            loc += 1
+
+        if loc - start < self.minLen:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        return loc, instring[start:loc]
+
+
+class _PositionToken(Token):
+    def __init__( self ):
+        super(_PositionToken,self).__init__()
+        self.name=self.__class__.__name__
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+
+class GoToColumn(_PositionToken):
+    """
+    Token to advance to a specific column of input text; useful for tabular report scraping.
+    """
+    def __init__( self, colno ):
+        super(GoToColumn,self).__init__()
+        self.col = colno
+
+    def preParse( self, instring, loc ):
+        if col(loc,instring) != self.col:
+            instrlen = len(instring)
+            if self.ignoreExprs:
+                loc = self._skipIgnorables( instring, loc )
+            while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col :
+                loc += 1
+        return loc
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        thiscol = col( loc, instring )
+        if thiscol > self.col:
+            raise ParseException( instring, loc, "Text not in expected column", self )
+        newloc = loc + self.col - thiscol
+        ret = instring[ loc: newloc ]
+        return newloc, ret
+
+
+class LineStart(_PositionToken):
+    """
+    Matches if current position is at the beginning of a line within the parse string
+    
+    Example::
+    
+        test = '''\
+        AAA this line
+        AAA and this line
+          AAA but not this one
+        B AAA and definitely not this one
+        '''
+
+        for t in (LineStart() + 'AAA' + restOfLine).searchString(test):
+            print(t)
+    
+    Prints::
+        ['AAA', ' this line']
+        ['AAA', ' and this line']    
+
+    """
+    def __init__( self ):
+        super(LineStart,self).__init__()
+        self.errmsg = "Expected start of line"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if col(loc, instring) == 1:
+            return loc, []
+        raise ParseException(instring, loc, self.errmsg, self)
+
+class LineEnd(_PositionToken):
+    """
+    Matches if current position is at the end of a line within the parse string
+    """
+    def __init__( self ):
+        super(LineEnd,self).__init__()
+        self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") )
+        self.errmsg = "Expected end of line"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc<len(instring):
+            if instring[loc] == "\n":
+                return loc+1, "\n"
+            else:
+                raise ParseException(instring, loc, self.errmsg, self)
+        elif loc == len(instring):
+            return loc+1, []
+        else:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+class StringStart(_PositionToken):
+    """
+    Matches if current position is at the beginning of the parse string
+    """
+    def __init__( self ):
+        super(StringStart,self).__init__()
+        self.errmsg = "Expected start of text"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc != 0:
+            # see if entire string up to here is just whitespace and ignoreables
+            if loc != self.preParse( instring, 0 ):
+                raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+class StringEnd(_PositionToken):
+    """
+    Matches if current position is at the end of the parse string
+    """
+    def __init__( self ):
+        super(StringEnd,self).__init__()
+        self.errmsg = "Expected end of text"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc < len(instring):
+            raise ParseException(instring, loc, self.errmsg, self)
+        elif loc == len(instring):
+            return loc+1, []
+        elif loc > len(instring):
+            return loc, []
+        else:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+class WordStart(_PositionToken):
+    """
+    Matches if the current position is at the beginning of a Word, and
+    is not preceded by any character in a given set of C{wordChars}
+    (default=C{printables}). To emulate the C{\b} behavior of regular expressions,
+    use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of
+    the string being parsed, or at the beginning of a line.
+    """
+    def __init__(self, wordChars = printables):
+        super(WordStart,self).__init__()
+        self.wordChars = set(wordChars)
+        self.errmsg = "Not at the start of a word"
+
+    def parseImpl(self, instring, loc, doActions=True ):
+        if loc != 0:
+            if (instring[loc-1] in self.wordChars or
+                instring[loc] not in self.wordChars):
+                raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+class WordEnd(_PositionToken):
+    """
+    Matches if the current position is at the end of a Word, and
+    is not followed by any character in a given set of C{wordChars}
+    (default=C{printables}). To emulate the C{\b} behavior of regular expressions,
+    use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of
+    the string being parsed, or at the end of a line.
+    """
+    def __init__(self, wordChars = printables):
+        super(WordEnd,self).__init__()
+        self.wordChars = set(wordChars)
+        self.skipWhitespace = False
+        self.errmsg = "Not at the end of a word"
+
+    def parseImpl(self, instring, loc, doActions=True ):
+        instrlen = len(instring)
+        if instrlen>0 and loc<instrlen:
+            if (instring[loc] in self.wordChars or
+                instring[loc-1] not in self.wordChars):
+                raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+
+class ParseExpression(ParserElement):
+    """
+    Abstract subclass of ParserElement, for combining and post-processing parsed tokens.
+    """
+    def __init__( self, exprs, savelist = False ):
+        super(ParseExpression,self).__init__(savelist)
+        if isinstance( exprs, _generatorType ):
+            exprs = list(exprs)
+
+        if isinstance( exprs, basestring ):
+            self.exprs = [ ParserElement._literalStringClass( exprs ) ]
+        elif isinstance( exprs, collections.Iterable ):
+            exprs = list(exprs)
+            # if sequence of strings provided, wrap with Literal
+            if all(isinstance(expr, basestring) for expr in exprs):
+                exprs = map(ParserElement._literalStringClass, exprs)
+            self.exprs = list(exprs)
+        else:
+            try:
+                self.exprs = list( exprs )
+            except TypeError:
+                self.exprs = [ exprs ]
+        self.callPreparse = False
+
+    def __getitem__( self, i ):
+        return self.exprs[i]
+
+    def append( self, other ):
+        self.exprs.append( other )
+        self.strRepr = None
+        return self
+
+    def leaveWhitespace( self ):
+        """Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on
+           all contained expressions."""
+        self.skipWhitespace = False
+        self.exprs = [ e.copy() for e in self.exprs ]
+        for e in self.exprs:
+            e.leaveWhitespace()
+        return self
+
+    def ignore( self, other ):
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                super( ParseExpression, self).ignore( other )
+                for e in self.exprs:
+                    e.ignore( self.ignoreExprs[-1] )
+        else:
+            super( ParseExpression, self).ignore( other )
+            for e in self.exprs:
+                e.ignore( self.ignoreExprs[-1] )
+        return self
+
+    def __str__( self ):
+        try:
+            return super(ParseExpression,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) )
+        return self.strRepr
+
+    def streamline( self ):
+        super(ParseExpression,self).streamline()
+
+        for e in self.exprs:
+            e.streamline()
+
+        # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d )
+        # but only if there are no parse actions or resultsNames on the nested And's
+        # (likewise for Or's and MatchFirst's)
+        if ( len(self.exprs) == 2 ):
+            other = self.exprs[0]
+            if ( isinstance( other, self.__class__ ) and
+                  not(other.parseAction) and
+                  other.resultsName is None and
+                  not other.debug ):
+                self.exprs = other.exprs[:] + [ self.exprs[1] ]
+                self.strRepr = None
+                self.mayReturnEmpty |= other.mayReturnEmpty
+                self.mayIndexError  |= other.mayIndexError
+
+            other = self.exprs[-1]
+            if ( isinstance( other, self.__class__ ) and
+                  not(other.parseAction) and
+                  other.resultsName is None and
+                  not other.debug ):
+                self.exprs = self.exprs[:-1] + other.exprs[:]
+                self.strRepr = None
+                self.mayReturnEmpty |= other.mayReturnEmpty
+                self.mayIndexError  |= other.mayIndexError
+
+        self.errmsg = "Expected " + _ustr(self)
+        
+        return self
+
+    def setResultsName( self, name, listAllMatches=False ):
+        ret = super(ParseExpression,self).setResultsName(name,listAllMatches)
+        return ret
+
+    def validate( self, validateTrace=[] ):
+        tmp = validateTrace[:]+[self]
+        for e in self.exprs:
+            e.validate(tmp)
+        self.checkRecursion( [] )
+        
+    def copy(self):
+        ret = super(ParseExpression,self).copy()
+        ret.exprs = [e.copy() for e in self.exprs]
+        return ret
+
+class And(ParseExpression):
+    """
+    Requires all given C{ParseExpression}s to be found in the given order.
+    Expressions may be separated by whitespace.
+    May be constructed using the C{'+'} operator.
+    May also be constructed using the C{'-'} operator, which will suppress backtracking.
+
+    Example::
+        integer = Word(nums)
+        name_expr = OneOrMore(Word(alphas))
+
+        expr = And([integer("id"),name_expr("name"),integer("age")])
+        # more easily written as:
+        expr = integer("id") + name_expr("name") + integer("age")
+    """
+
+    class _ErrorStop(Empty):
+        def __init__(self, *args, **kwargs):
+            super(And._ErrorStop,self).__init__(*args, **kwargs)
+            self.name = '-'
+            self.leaveWhitespace()
+
+    def __init__( self, exprs, savelist = True ):
+        super(And,self).__init__(exprs, savelist)
+        self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
+        self.setWhitespaceChars( self.exprs[0].whiteChars )
+        self.skipWhitespace = self.exprs[0].skipWhitespace
+        self.callPreparse = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        # pass False as last arg to _parse for first element, since we already
+        # pre-parsed the string as part of our And pre-parsing
+        loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False )
+        errorStop = False
+        for e in self.exprs[1:]:
+            if isinstance(e, And._ErrorStop):
+                errorStop = True
+                continue
+            if errorStop:
+                try:
+                    loc, exprtokens = e._parse( instring, loc, doActions )
+                except ParseSyntaxException:
+                    raise
+                except ParseBaseException as pe:
+                    pe.__traceback__ = None
+                    raise ParseSyntaxException._from_exception(pe)
+                except IndexError:
+                    raise ParseSyntaxException(instring, len(instring), self.errmsg, self)
+            else:
+                loc, exprtokens = e._parse( instring, loc, doActions )
+            if exprtokens or exprtokens.haskeys():
+                resultlist += exprtokens
+        return loc, resultlist
+
+    def __iadd__(self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        return self.append( other ) #And( [ self, other ] )
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+            if not e.mayReturnEmpty:
+                break
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+
+class Or(ParseExpression):
+    """
+    Requires that at least one C{ParseExpression} is found.
+    If two expressions match, the expression that matches the longest string will be used.
+    May be constructed using the C{'^'} operator.
+
+    Example::
+        # construct Or using '^' operator
+        
+        number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums))
+        print(number.searchString("123 3.1416 789"))
+    prints::
+        [['123'], ['3.1416'], ['789']]
+    """
+    def __init__( self, exprs, savelist = False ):
+        super(Or,self).__init__(exprs, savelist)
+        if self.exprs:
+            self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs)
+        else:
+            self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        maxExcLoc = -1
+        maxException = None
+        matches = []
+        for e in self.exprs:
+            try:
+                loc2 = e.tryParse( instring, loc )
+            except ParseException as err:
+                err.__traceback__ = None
+                if err.loc > maxExcLoc:
+                    maxException = err
+                    maxExcLoc = err.loc
+            except IndexError:
+                if len(instring) > maxExcLoc:
+                    maxException = ParseException(instring,len(instring),e.errmsg,self)
+                    maxExcLoc = len(instring)
+            else:
+                # save match among all matches, to retry longest to shortest
+                matches.append((loc2, e))
+
+        if matches:
+            matches.sort(key=lambda x: -x[0])
+            for _,e in matches:
+                try:
+                    return e._parse( instring, loc, doActions )
+                except ParseException as err:
+                    err.__traceback__ = None
+                    if err.loc > maxExcLoc:
+                        maxException = err
+                        maxExcLoc = err.loc
+
+        if maxException is not None:
+            maxException.msg = self.errmsg
+            raise maxException
+        else:
+            raise ParseException(instring, loc, "no defined alternatives to match", self)
+
+
+    def __ixor__(self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        return self.append( other ) #Or( [ self, other ] )
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class MatchFirst(ParseExpression):
+    """
+    Requires that at least one C{ParseExpression} is found.
+    If two expressions match, the first one listed is the one that will match.
+    May be constructed using the C{'|'} operator.
+
+    Example::
+        # construct MatchFirst using '|' operator
+        
+        # watch the order of expressions to match
+        number = Word(nums) | Combine(Word(nums) + '.' + Word(nums))
+        print(number.searchString("123 3.1416 789")) #  Fail! -> [['123'], ['3'], ['1416'], ['789']]
+
+        # put more selective expression first
+        number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums)
+        print(number.searchString("123 3.1416 789")) #  Better -> [['123'], ['3.1416'], ['789']]
+    """
+    def __init__( self, exprs, savelist = False ):
+        super(MatchFirst,self).__init__(exprs, savelist)
+        if self.exprs:
+            self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs)
+        else:
+            self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        maxExcLoc = -1
+        maxException = None
+        for e in self.exprs:
+            try:
+                ret = e._parse( instring, loc, doActions )
+                return ret
+            except ParseException as err:
+                if err.loc > maxExcLoc:
+                    maxException = err
+                    maxExcLoc = err.loc
+            except IndexError:
+                if len(instring) > maxExcLoc:
+                    maxException = ParseException(instring,len(instring),e.errmsg,self)
+                    maxExcLoc = len(instring)
+
+        # only got here if no expression matched, raise exception for match that made it the furthest
+        else:
+            if maxException is not None:
+                maxException.msg = self.errmsg
+                raise maxException
+            else:
+                raise ParseException(instring, loc, "no defined alternatives to match", self)
+
+    def __ior__(self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        return self.append( other ) #MatchFirst( [ self, other ] )
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class Each(ParseExpression):
+    """
+    Requires all given C{ParseExpression}s to be found, but in any order.
+    Expressions may be separated by whitespace.
+    May be constructed using the C{'&'} operator.
+
+    Example::
+        color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN")
+        shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON")
+        integer = Word(nums)
+        shape_attr = "shape:" + shape_type("shape")
+        posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn")
+        color_attr = "color:" + color("color")
+        size_attr = "size:" + integer("size")
+
+        # use Each (using operator '&') to accept attributes in any order 
+        # (shape and posn are required, color and size are optional)
+        shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr)
+
+        shape_spec.runTests('''
+            shape: SQUARE color: BLACK posn: 100, 120
+            shape: CIRCLE size: 50 color: BLUE posn: 50,80
+            color:GREEN size:20 shape:TRIANGLE posn:20,40
+            '''
+            )
+    prints::
+        shape: SQUARE color: BLACK posn: 100, 120
+        ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']]
+        - color: BLACK
+        - posn: ['100', ',', '120']
+          - x: 100
+          - y: 120
+        - shape: SQUARE
+
+
+        shape: CIRCLE size: 50 color: BLUE posn: 50,80
+        ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']]
+        - color: BLUE
+        - posn: ['50', ',', '80']
+          - x: 50
+          - y: 80
+        - shape: CIRCLE
+        - size: 50
+
+
+        color: GREEN size: 20 shape: TRIANGLE posn: 20,40
+        ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']]
+        - color: GREEN
+        - posn: ['20', ',', '40']
+          - x: 20
+          - y: 40
+        - shape: TRIANGLE
+        - size: 20
+    """
+    def __init__( self, exprs, savelist = True ):
+        super(Each,self).__init__(exprs, savelist)
+        self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
+        self.skipWhitespace = True
+        self.initExprGroups = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.initExprGroups:
+            self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional))
+            opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ]
+            opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)]
+            self.optionals = opt1 + opt2
+            self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ]
+            self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ]
+            self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ]
+            self.required += self.multirequired
+            self.initExprGroups = False
+        tmpLoc = loc
+        tmpReqd = self.required[:]
+        tmpOpt  = self.optionals[:]
+        matchOrder = []
+
+        keepMatching = True
+        while keepMatching:
+            tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired
+            failed = []
+            for e in tmpExprs:
+                try:
+                    tmpLoc = e.tryParse( instring, tmpLoc )
+                except ParseException:
+                    failed.append(e)
+                else:
+                    matchOrder.append(self.opt1map.get(id(e),e))
+                    if e in tmpReqd:
+                        tmpReqd.remove(e)
+                    elif e in tmpOpt:
+                        tmpOpt.remove(e)
+            if len(failed) == len(tmpExprs):
+                keepMatching = False
+
+        if tmpReqd:
+            missing = ", ".join(_ustr(e) for e in tmpReqd)
+            raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing )
+
+        # add any unmatched Optionals, in case they have default values defined
+        matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt]
+
+        resultlist = []
+        for e in matchOrder:
+            loc,results = e._parse(instring,loc,doActions)
+            resultlist.append(results)
+
+        finalResults = sum(resultlist, ParseResults([]))
+        return loc, finalResults
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class ParseElementEnhance(ParserElement):
+    """
+    Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens.
+    """
+    def __init__( self, expr, savelist=False ):
+        super(ParseElementEnhance,self).__init__(savelist)
+        if isinstance( expr, basestring ):
+            if issubclass(ParserElement._literalStringClass, Token):
+                expr = ParserElement._literalStringClass(expr)
+            else:
+                expr = ParserElement._literalStringClass(Literal(expr))
+        self.expr = expr
+        self.strRepr = None
+        if expr is not None:
+            self.mayIndexError = expr.mayIndexError
+            self.mayReturnEmpty = expr.mayReturnEmpty
+            self.setWhitespaceChars( expr.whiteChars )
+            self.skipWhitespace = expr.skipWhitespace
+            self.saveAsList = expr.saveAsList
+            self.callPreparse = expr.callPreparse
+            self.ignoreExprs.extend(expr.ignoreExprs)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.expr is not None:
+            return self.expr._parse( instring, loc, doActions, callPreParse=False )
+        else:
+            raise ParseException("",loc,self.errmsg,self)
+
+    def leaveWhitespace( self ):
+        self.skipWhitespace = False
+        self.expr = self.expr.copy()
+        if self.expr is not None:
+            self.expr.leaveWhitespace()
+        return self
+
+    def ignore( self, other ):
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                super( ParseElementEnhance, self).ignore( other )
+                if self.expr is not None:
+                    self.expr.ignore( self.ignoreExprs[-1] )
+        else:
+            super( ParseElementEnhance, self).ignore( other )
+            if self.expr is not None:
+                self.expr.ignore( self.ignoreExprs[-1] )
+        return self
+
+    def streamline( self ):
+        super(ParseElementEnhance,self).streamline()
+        if self.expr is not None:
+            self.expr.streamline()
+        return self
+
+    def checkRecursion( self, parseElementList ):
+        if self in parseElementList:
+            raise RecursiveGrammarException( parseElementList+[self] )
+        subRecCheckList = parseElementList[:] + [ self ]
+        if self.expr is not None:
+            self.expr.checkRecursion( subRecCheckList )
+
+    def validate( self, validateTrace=[] ):
+        tmp = validateTrace[:]+[self]
+        if self.expr is not None:
+            self.expr.validate(tmp)
+        self.checkRecursion( [] )
+
+    def __str__( self ):
+        try:
+            return super(ParseElementEnhance,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None and self.expr is not None:
+            self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) )
+        return self.strRepr
+
+
+class FollowedBy(ParseElementEnhance):
+    """
+    Lookahead matching of the given parse expression.  C{FollowedBy}
+    does I{not} advance the parsing position within the input string, it only
+    verifies that the specified parse expression matches at the current
+    position.  C{FollowedBy} always returns a null token list.
+
+    Example::
+        # use FollowedBy to match a label only if it is followed by a ':'
+        data_word = Word(alphas)
+        label = data_word + FollowedBy(':')
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        
+        OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint()
+    prints::
+        [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']]
+    """
+    def __init__( self, expr ):
+        super(FollowedBy,self).__init__(expr)
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        self.expr.tryParse( instring, loc )
+        return loc, []
+
+
+class NotAny(ParseElementEnhance):
+    """
+    Lookahead to disallow matching with the given parse expression.  C{NotAny}
+    does I{not} advance the parsing position within the input string, it only
+    verifies that the specified parse expression does I{not} match at the current
+    position.  Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny}
+    always returns a null token list.  May be constructed using the '~' operator.
+
+    Example::
+        
+    """
+    def __init__( self, expr ):
+        super(NotAny,self).__init__(expr)
+        #~ self.leaveWhitespace()
+        self.skipWhitespace = False  # do NOT use self.leaveWhitespace(), don't want to propagate to exprs
+        self.mayReturnEmpty = True
+        self.errmsg = "Found unwanted token, "+_ustr(self.expr)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.expr.canParseNext(instring, loc):
+            raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "~{" + _ustr(self.expr) + "}"
+
+        return self.strRepr
+
+class _MultipleMatch(ParseElementEnhance):
+    def __init__( self, expr, stopOn=None):
+        super(_MultipleMatch, self).__init__(expr)
+        self.saveAsList = True
+        ender = stopOn
+        if isinstance(ender, basestring):
+            ender = ParserElement._literalStringClass(ender)
+        self.not_ender = ~ender if ender is not None else None
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        self_expr_parse = self.expr._parse
+        self_skip_ignorables = self._skipIgnorables
+        check_ender = self.not_ender is not None
+        if check_ender:
+            try_not_ender = self.not_ender.tryParse
+        
+        # must be at least one (but first see if we are the stopOn sentinel;
+        # if so, fail)
+        if check_ender:
+            try_not_ender(instring, loc)
+        loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False )
+        try:
+            hasIgnoreExprs = (not not self.ignoreExprs)
+            while 1:
+                if check_ender:
+                    try_not_ender(instring, loc)
+                if hasIgnoreExprs:
+                    preloc = self_skip_ignorables( instring, loc )
+                else:
+                    preloc = loc
+                loc, tmptokens = self_expr_parse( instring, preloc, doActions )
+                if tmptokens or tmptokens.haskeys():
+                    tokens += tmptokens
+        except (ParseException,IndexError):
+            pass
+
+        return loc, tokens
+        
+class OneOrMore(_MultipleMatch):
+    """
+    Repetition of one or more of the given expression.
+    
+    Parameters:
+     - expr - expression that must match one or more times
+     - stopOn - (default=C{None}) - expression for a terminating sentinel
+          (only required if the sentinel would ordinarily match the repetition 
+          expression)          
+
+    Example::
+        data_word = Word(alphas)
+        label = data_word + FollowedBy(':')
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join))
+
+        text = "shape: SQUARE posn: upper left color: BLACK"
+        OneOrMore(attr_expr).parseString(text).pprint()  # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']]
+
+        # use stopOn attribute for OneOrMore to avoid reading label string as part of the data
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']]
+        
+        # could also be written as
+        (attr_expr * (1,)).parseString(text).pprint()
+    """
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + _ustr(self.expr) + "}..."
+
+        return self.strRepr
+
+class ZeroOrMore(_MultipleMatch):
+    """
+    Optional repetition of zero or more of the given expression.
+    
+    Parameters:
+     - expr - expression that must match zero or more times
+     - stopOn - (default=C{None}) - expression for a terminating sentinel
+          (only required if the sentinel would ordinarily match the repetition 
+          expression)          
+
+    Example: similar to L{OneOrMore}
+    """
+    def __init__( self, expr, stopOn=None):
+        super(ZeroOrMore,self).__init__(expr, stopOn=stopOn)
+        self.mayReturnEmpty = True
+        
+    def parseImpl( self, instring, loc, doActions=True ):
+        try:
+            return super(ZeroOrMore, self).parseImpl(instring, loc, doActions)
+        except (ParseException,IndexError):
+            return loc, []
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "[" + _ustr(self.expr) + "]..."
+
+        return self.strRepr
+
+class _NullToken(object):
+    def __bool__(self):
+        return False
+    __nonzero__ = __bool__
+    def __str__(self):
+        return ""
+
+_optionalNotMatched = _NullToken()
+class Optional(ParseElementEnhance):
+    """
+    Optional matching of the given expression.
+
+    Parameters:
+     - expr - expression that must match zero or more times
+     - default (optional) - value to be returned if the optional expression is not found.
+
+    Example::
+        # US postal code can be a 5-digit zip, plus optional 4-digit qualifier
+        zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4)))
+        zip.runTests('''
+            # traditional ZIP code
+            12345
+            
+            # ZIP+4 form
+            12101-0001
+            
+            # invalid ZIP
+            98765-
+            ''')
+    prints::
+        # traditional ZIP code
+        12345
+        ['12345']
+
+        # ZIP+4 form
+        12101-0001
+        ['12101-0001']
+
+        # invalid ZIP
+        98765-
+             ^
+        FAIL: Expected end of text (at char 5), (line:1, col:6)
+    """
+    def __init__( self, expr, default=_optionalNotMatched ):
+        super(Optional,self).__init__( expr, savelist=False )
+        self.saveAsList = self.expr.saveAsList
+        self.defaultValue = default
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        try:
+            loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False )
+        except (ParseException,IndexError):
+            if self.defaultValue is not _optionalNotMatched:
+                if self.expr.resultsName:
+                    tokens = ParseResults([ self.defaultValue ])
+                    tokens[self.expr.resultsName] = self.defaultValue
+                else:
+                    tokens = [ self.defaultValue ]
+            else:
+                tokens = []
+        return loc, tokens
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "[" + _ustr(self.expr) + "]"
+
+        return self.strRepr
+
+class SkipTo(ParseElementEnhance):
+    """
+    Token for skipping over all undefined text until the matched expression is found.
+
+    Parameters:
+     - expr - target expression marking the end of the data to be skipped
+     - include - (default=C{False}) if True, the target expression is also parsed 
+          (the skipped text and target expression are returned as a 2-element list).
+     - ignore - (default=C{None}) used to define grammars (typically quoted strings and 
+          comments) that might contain false matches to the target expression
+     - failOn - (default=C{None}) define expressions that are not allowed to be 
+          included in the skipped test; if found before the target expression is found, 
+          the SkipTo is not a match
+
+    Example::
+        report = '''
+            Outstanding Issues Report - 1 Jan 2000
+
+               # | Severity | Description                               |  Days Open
+            -----+----------+-------------------------------------------+-----------
+             101 | Critical | Intermittent system crash                 |          6
+              94 | Cosmetic | Spelling error on Login ('log|n')         |         14
+              79 | Minor    | System slow when running too many reports |         47
+            '''
+        integer = Word(nums)
+        SEP = Suppress('|')
+        # use SkipTo to simply match everything up until the next SEP
+        # - ignore quoted strings, so that a '|' character inside a quoted string does not match
+        # - parse action will call token.strip() for each matched token, i.e., the description body
+        string_data = SkipTo(SEP, ignore=quotedString)
+        string_data.setParseAction(tokenMap(str.strip))
+        ticket_expr = (integer("issue_num") + SEP 
+                      + string_data("sev") + SEP 
+                      + string_data("desc") + SEP 
+                      + integer("days_open"))
+        
+        for tkt in ticket_expr.searchString(report):
+            print tkt.dump()
+    prints::
+        ['101', 'Critical', 'Intermittent system crash', '6']
+        - days_open: 6
+        - desc: Intermittent system crash
+        - issue_num: 101
+        - sev: Critical
+        ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14']
+        - days_open: 14
+        - desc: Spelling error on Login ('log|n')
+        - issue_num: 94
+        - sev: Cosmetic
+        ['79', 'Minor', 'System slow when running too many reports', '47']
+        - days_open: 47
+        - desc: System slow when running too many reports
+        - issue_num: 79
+        - sev: Minor
+    """
+    def __init__( self, other, include=False, ignore=None, failOn=None ):
+        super( SkipTo, self ).__init__( other )
+        self.ignoreExpr = ignore
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+        self.includeMatch = include
+        self.asList = False
+        if isinstance(failOn, basestring):
+            self.failOn = ParserElement._literalStringClass(failOn)
+        else:
+            self.failOn = failOn
+        self.errmsg = "No match found for "+_ustr(self.expr)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        startloc = loc
+        instrlen = len(instring)
+        expr = self.expr
+        expr_parse = self.expr._parse
+        self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None
+        self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None
+        
+        tmploc = loc
+        while tmploc <= instrlen:
+            if self_failOn_canParseNext is not None:
+                # break if failOn expression matches
+                if self_failOn_canParseNext(instring, tmploc):
+                    break
+                    
+            if self_ignoreExpr_tryParse is not None:
+                # advance past ignore expressions
+                while 1:
+                    try:
+                        tmploc = self_ignoreExpr_tryParse(instring, tmploc)
+                    except ParseBaseException:
+                        break
+            
+            try:
+                expr_parse(instring, tmploc, doActions=False, callPreParse=False)
+            except (ParseException, IndexError):
+                # no match, advance loc in string
+                tmploc += 1
+            else:
+                # matched skipto expr, done
+                break
+
+        else:
+            # ran off the end of the input string without matching skipto expr, fail
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        # build up return values
+        loc = tmploc
+        skiptext = instring[startloc:loc]
+        skipresult = ParseResults(skiptext)
+        
+        if self.includeMatch:
+            loc, mat = expr_parse(instring,loc,doActions,callPreParse=False)
+            skipresult += mat
+
+        return loc, skipresult
+
+class Forward(ParseElementEnhance):
+    """
+    Forward declaration of an expression to be defined later -
+    used for recursive grammars, such as algebraic infix notation.
+    When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator.
+
+    Note: take care when assigning to C{Forward} not to overlook precedence of operators.
+    Specifically, '|' has a lower precedence than '<<', so that::
+        fwdExpr << a | b | c
+    will actually be evaluated as::
+        (fwdExpr << a) | b | c
+    thereby leaving b and c out as parseable alternatives.  It is recommended that you
+    explicitly group the values inserted into the C{Forward}::
+        fwdExpr << (a | b | c)
+    Converting to use the '<<=' operator instead will avoid this problem.
+
+    See L{ParseResults.pprint} for an example of a recursive parser created using
+    C{Forward}.
+    """
+    def __init__( self, other=None ):
+        super(Forward,self).__init__( other, savelist=False )
+
+    def __lshift__( self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass(other)
+        self.expr = other
+        self.strRepr = None
+        self.mayIndexError = self.expr.mayIndexError
+        self.mayReturnEmpty = self.expr.mayReturnEmpty
+        self.setWhitespaceChars( self.expr.whiteChars )
+        self.skipWhitespace = self.expr.skipWhitespace
+        self.saveAsList = self.expr.saveAsList
+        self.ignoreExprs.extend(self.expr.ignoreExprs)
+        return self
+        
+    def __ilshift__(self, other):
+        return self << other
+    
+    def leaveWhitespace( self ):
+        self.skipWhitespace = False
+        return self
+
+    def streamline( self ):
+        if not self.streamlined:
+            self.streamlined = True
+            if self.expr is not None:
+                self.expr.streamline()
+        return self
+
+    def validate( self, validateTrace=[] ):
+        if self not in validateTrace:
+            tmp = validateTrace[:]+[self]
+            if self.expr is not None:
+                self.expr.validate(tmp)
+        self.checkRecursion([])
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+        return self.__class__.__name__ + ": ..."
+
+        # stubbed out for now - creates awful memory and perf issues
+        self._revertClass = self.__class__
+        self.__class__ = _ForwardNoRecurse
+        try:
+            if self.expr is not None:
+                retString = _ustr(self.expr)
+            else:
+                retString = "None"
+        finally:
+            self.__class__ = self._revertClass
+        return self.__class__.__name__ + ": " + retString
+
+    def copy(self):
+        if self.expr is not None:
+            return super(Forward,self).copy()
+        else:
+            ret = Forward()
+            ret <<= self
+            return ret
+
+class _ForwardNoRecurse(Forward):
+    def __str__( self ):
+        return "..."
+
+class TokenConverter(ParseElementEnhance):
+    """
+    Abstract subclass of C{ParseExpression}, for converting parsed results.
+    """
+    def __init__( self, expr, savelist=False ):
+        super(TokenConverter,self).__init__( expr )#, savelist )
+        self.saveAsList = False
+
+class Combine(TokenConverter):
+    """
+    Converter to concatenate all matching tokens to a single string.
+    By default, the matching patterns must also be contiguous in the input string;
+    this can be disabled by specifying C{'adjacent=False'} in the constructor.
+
+    Example::
+        real = Word(nums) + '.' + Word(nums)
+        print(real.parseString('3.1416')) # -> ['3', '.', '1416']
+        # will also erroneously match the following
+        print(real.parseString('3. 1416')) # -> ['3', '.', '1416']
+
+        real = Combine(Word(nums) + '.' + Word(nums))
+        print(real.parseString('3.1416')) # -> ['3.1416']
+        # no match when there are internal spaces
+        print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...)
+    """
+    def __init__( self, expr, joinString="", adjacent=True ):
+        super(Combine,self).__init__( expr )
+        # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself
+        if adjacent:
+            self.leaveWhitespace()
+        self.adjacent = adjacent
+        self.skipWhitespace = True
+        self.joinString = joinString
+        self.callPreparse = True
+
+    def ignore( self, other ):
+        if self.adjacent:
+            ParserElement.ignore(self, other)
+        else:
+            super( Combine, self).ignore( other )
+        return self
+
+    def postParse( self, instring, loc, tokenlist ):
+        retToks = tokenlist.copy()
+        del retToks[:]
+        retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults)
+
+        if self.resultsName and retToks.haskeys():
+            return [ retToks ]
+        else:
+            return retToks
+
+class Group(TokenConverter):
+    """
+    Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions.
+
+    Example::
+        ident = Word(alphas)
+        num = Word(nums)
+        term = ident | num
+        func = ident + Optional(delimitedList(term))
+        print(func.parseString("fn a,b,100"))  # -> ['fn', 'a', 'b', '100']
+
+        func = ident + Group(Optional(delimitedList(term)))
+        print(func.parseString("fn a,b,100"))  # -> ['fn', ['a', 'b', '100']]
+    """
+    def __init__( self, expr ):
+        super(Group,self).__init__( expr )
+        self.saveAsList = True
+
+    def postParse( self, instring, loc, tokenlist ):
+        return [ tokenlist ]
+
+class Dict(TokenConverter):
+    """
+    Converter to return a repetitive expression as a list, but also as a dictionary.
+    Each element can also be referenced using the first token in the expression as its key.
+    Useful for tabular report scraping when the first column can be used as a item key.
+
+    Example::
+        data_word = Word(alphas)
+        label = data_word + FollowedBy(':')
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join))
+
+        text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
+        attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        
+        # print attributes as plain groups
+        print(OneOrMore(attr_expr).parseString(text).dump())
+        
+        # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names
+        result = Dict(OneOrMore(Group(attr_expr))).parseString(text)
+        print(result.dump())
+        
+        # access named fields as dict entries, or output as dict
+        print(result['shape'])        
+        print(result.asDict())
+    prints::
+        ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap']
+
+        [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
+        - color: light blue
+        - posn: upper left
+        - shape: SQUARE
+        - texture: burlap
+        SQUARE
+        {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'}
+    See more examples at L{ParseResults} of accessing fields by results name.
+    """
+    def __init__( self, expr ):
+        super(Dict,self).__init__( expr )
+        self.saveAsList = True
+
+    def postParse( self, instring, loc, tokenlist ):
+        for i,tok in enumerate(tokenlist):
+            if len(tok) == 0:
+                continue
+            ikey = tok[0]
+            if isinstance(ikey,int):
+                ikey = _ustr(tok[0]).strip()
+            if len(tok)==1:
+                tokenlist[ikey] = _ParseResultsWithOffset("",i)
+            elif len(tok)==2 and not isinstance(tok[1],ParseResults):
+                tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i)
+            else:
+                dictvalue = tok.copy() #ParseResults(i)
+                del dictvalue[0]
+                if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()):
+                    tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i)
+                else:
+                    tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i)
+
+        if self.resultsName:
+            return [ tokenlist ]
+        else:
+            return tokenlist
+
+
+class Suppress(TokenConverter):
+    """
+    Converter for ignoring the results of a parsed expression.
+
+    Example::
+        source = "a, b, c,d"
+        wd = Word(alphas)
+        wd_list1 = wd + ZeroOrMore(',' + wd)
+        print(wd_list1.parseString(source))
+
+        # often, delimiters that are useful during parsing are just in the
+        # way afterward - use Suppress to keep them out of the parsed output
+        wd_list2 = wd + ZeroOrMore(Suppress(',') + wd)
+        print(wd_list2.parseString(source))
+    prints::
+        ['a', ',', 'b', ',', 'c', ',', 'd']
+        ['a', 'b', 'c', 'd']
+    (See also L{delimitedList}.)
+    """
+    def postParse( self, instring, loc, tokenlist ):
+        return []
+
+    def suppress( self ):
+        return self
+
+
+class OnlyOnce(object):
+    """
+    Wrapper for parse actions, to ensure they are only called once.
+    """
+    def __init__(self, methodCall):
+        self.callable = _trim_arity(methodCall)
+        self.called = False
+    def __call__(self,s,l,t):
+        if not self.called:
+            results = self.callable(s,l,t)
+            self.called = True
+            return results
+        raise ParseException(s,l,"")
+    def reset(self):
+        self.called = False
+
+def traceParseAction(f):
+    """
+    Decorator for debugging parse actions. 
+    
+    When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".}
+    When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised.
+
+    Example::
+        wd = Word(alphas)
+
+        @traceParseAction
+        def remove_duplicate_chars(tokens):
+            return ''.join(sorted(set(''.join(tokens)))
+
+        wds = OneOrMore(wd).setParseAction(remove_duplicate_chars)
+        print(wds.parseString("slkdjs sld sldd sdlf sdljf"))
+    prints::
+        >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {}))
+        <<leaving remove_duplicate_chars (ret: 'dfjkls')
+        ['dfjkls']
+    """
+    f = _trim_arity(f)
+    def z(*paArgs):
+        thisFunc = f.__name__
+        s,l,t = paArgs[-3:]
+        if len(paArgs)>3:
+            thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc
+        sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) )
+        try:
+            ret = f(*paArgs)
+        except Exception as exc:
+            sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) )
+            raise
+        sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) )
+        return ret
+    try:
+        z.__name__ = f.__name__
+    except AttributeError:
+        pass
+    return z
+
+#
+# global helpers
+#
+def delimitedList( expr, delim=",", combine=False ):
+    """
+    Helper to define a delimited list of expressions - the delimiter defaults to ','.
+    By default, the list elements and delimiters can have intervening whitespace, and
+    comments, but this can be overridden by passing C{combine=True} in the constructor.
+    If C{combine} is set to C{True}, the matching tokens are returned as a single token
+    string, with the delimiters included; otherwise, the matching tokens are returned
+    as a list of tokens, with the delimiters suppressed.
+
+    Example::
+        delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc']
+        delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE']
+    """
+    dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..."
+    if combine:
+        return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName)
+    else:
+        return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName)
+
+def countedArray( expr, intExpr=None ):
+    """
+    Helper to define a counted list of expressions.
+    This helper defines a pattern of the form::
+        integer expr expr expr...
+    where the leading integer tells how many expr expressions follow.
+    The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed.
+    
+    If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value.
+
+    Example::
+        countedArray(Word(alphas)).parseString('2 ab cd ef')  # -> ['ab', 'cd']
+
+        # in this parser, the leading integer value is given in binary,
+        # '10' indicating that 2 values are in the array
+        binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2))
+        countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef')  # -> ['ab', 'cd']
+    """
+    arrayExpr = Forward()
+    def countFieldParseAction(s,l,t):
+        n = t[0]
+        arrayExpr << (n and Group(And([expr]*n)) or Group(empty))
+        return []
+    if intExpr is None:
+        intExpr = Word(nums).setParseAction(lambda t:int(t[0]))
+    else:
+        intExpr = intExpr.copy()
+    intExpr.setName("arrayLen")
+    intExpr.addParseAction(countFieldParseAction, callDuringTry=True)
+    return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...')
+
+def _flatten(L):
+    ret = []
+    for i in L:
+        if isinstance(i,list):
+            ret.extend(_flatten(i))
+        else:
+            ret.append(i)
+    return ret
+
+def matchPreviousLiteral(expr):
+    """
+    Helper to define an expression that is indirectly defined from
+    the tokens matched in a previous expression, that is, it looks
+    for a 'repeat' of a previous expression.  For example::
+        first = Word(nums)
+        second = matchPreviousLiteral(first)
+        matchExpr = first + ":" + second
+    will match C{"1:1"}, but not C{"1:2"}.  Because this matches a
+    previous literal, will also match the leading C{"1:1"} in C{"1:10"}.
+    If this is not desired, use C{matchPreviousExpr}.
+    Do I{not} use with packrat parsing enabled.
+    """
+    rep = Forward()
+    def copyTokenToRepeater(s,l,t):
+        if t:
+            if len(t) == 1:
+                rep << t[0]
+            else:
+                # flatten t tokens
+                tflat = _flatten(t.asList())
+                rep << And(Literal(tt) for tt in tflat)
+        else:
+            rep << Empty()
+    expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
+    rep.setName('(prev) ' + _ustr(expr))
+    return rep
+
+def matchPreviousExpr(expr):
+    """
+    Helper to define an expression that is indirectly defined from
+    the tokens matched in a previous expression, that is, it looks
+    for a 'repeat' of a previous expression.  For example::
+        first = Word(nums)
+        second = matchPreviousExpr(first)
+        matchExpr = first + ":" + second
+    will match C{"1:1"}, but not C{"1:2"}.  Because this matches by
+    expressions, will I{not} match the leading C{"1:1"} in C{"1:10"};
+    the expressions are evaluated first, and then compared, so
+    C{"1"} is compared with C{"10"}.
+    Do I{not} use with packrat parsing enabled.
+    """
+    rep = Forward()
+    e2 = expr.copy()
+    rep <<= e2
+    def copyTokenToRepeater(s,l,t):
+        matchTokens = _flatten(t.asList())
+        def mustMatchTheseTokens(s,l,t):
+            theseTokens = _flatten(t.asList())
+            if  theseTokens != matchTokens:
+                raise ParseException("",0,"")
+        rep.setParseAction( mustMatchTheseTokens, callDuringTry=True )
+    expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
+    rep.setName('(prev) ' + _ustr(expr))
+    return rep
+
+def _escapeRegexRangeChars(s):
+    #~  escape these chars: ^-]
+    for c in r"\^-]":
+        s = s.replace(c,_bslash+c)
+    s = s.replace("\n",r"\n")
+    s = s.replace("\t",r"\t")
+    return _ustr(s)
+
+def oneOf( strs, caseless=False, useRegex=True ):
+    """
+    Helper to quickly define a set of alternative Literals, and makes sure to do
+    longest-first testing when there is a conflict, regardless of the input order,
+    but returns a C{L{MatchFirst}} for best performance.
+
+    Parameters:
+     - strs - a string of space-delimited literals, or a collection of string literals
+     - caseless - (default=C{False}) - treat all literals as caseless
+     - useRegex - (default=C{True}) - as an optimization, will generate a Regex
+          object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or
+          if creating a C{Regex} raises an exception)
+
+    Example::
+        comp_oper = oneOf("< = > <= >= !=")
+        var = Word(alphas)
+        number = Word(nums)
+        term = var | number
+        comparison_expr = term + comp_oper + term
+        print(comparison_expr.searchString("B = 12  AA=23 B<=AA AA>12"))
+    prints::
+        [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']]
+    """
+    if caseless:
+        isequal = ( lambda a,b: a.upper() == b.upper() )
+        masks = ( lambda a,b: b.upper().startswith(a.upper()) )
+        parseElementClass = CaselessLiteral
+    else:
+        isequal = ( lambda a,b: a == b )
+        masks = ( lambda a,b: b.startswith(a) )
+        parseElementClass = Literal
+
+    symbols = []
+    if isinstance(strs,basestring):
+        symbols = strs.split()
+    elif isinstance(strs, collections.Iterable):
+        symbols = list(strs)
+    else:
+        warnings.warn("Invalid argument to oneOf, expected string or iterable",
+                SyntaxWarning, stacklevel=2)
+    if not symbols:
+        return NoMatch()
+
+    i = 0
+    while i < len(symbols)-1:
+        cur = symbols[i]
+        for j,other in enumerate(symbols[i+1:]):
+            if ( isequal(other, cur) ):
+                del symbols[i+j+1]
+                break
+            elif ( masks(cur, other) ):
+                del symbols[i+j+1]
+                symbols.insert(i,other)
+                cur = other
+                break
+        else:
+            i += 1
+
+    if not caseless and useRegex:
+        #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] ))
+        try:
+            if len(symbols)==len("".join(symbols)):
+                return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols))
+            else:
+                return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols))
+        except Exception:
+            warnings.warn("Exception creating Regex for oneOf, building MatchFirst",
+                    SyntaxWarning, stacklevel=2)
+
+
+    # last resort, just use MatchFirst
+    return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols))
+
+def dictOf( key, value ):
+    """
+    Helper to easily and clearly define a dictionary by specifying the respective patterns
+    for the key and value.  Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens
+    in the proper order.  The key pattern can include delimiting markers or punctuation,
+    as long as they are suppressed, thereby leaving the significant key text.  The value
+    pattern can include named results, so that the C{Dict} results can include named token
+    fields.
+
+    Example::
+        text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
+        attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        print(OneOrMore(attr_expr).parseString(text).dump())
+        
+        attr_label = label
+        attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)
+
+        # similar to Dict, but simpler call format
+        result = dictOf(attr_label, attr_value).parseString(text)
+        print(result.dump())
+        print(result['shape'])
+        print(result.shape)  # object attribute access works too
+        print(result.asDict())
+    prints::
+        [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
+        - color: light blue
+        - posn: upper left
+        - shape: SQUARE
+        - texture: burlap
+        SQUARE
+        SQUARE
+        {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'}
+    """
+    return Dict( ZeroOrMore( Group ( key + value ) ) )
+
+def originalTextFor(expr, asString=True):
+    """
+    Helper to return the original, untokenized text for a given expression.  Useful to
+    restore the parsed fields of an HTML start tag into the raw tag text itself, or to
+    revert separate tokens with intervening whitespace back to the original matching
+    input text. By default, returns astring containing the original parsed text.  
+       
+    If the optional C{asString} argument is passed as C{False}, then the return value is a 
+    C{L{ParseResults}} containing any results names that were originally matched, and a 
+    single token containing the original matched text from the input string.  So if 
+    the expression passed to C{L{originalTextFor}} contains expressions with defined
+    results names, you must set C{asString} to C{False} if you want to preserve those
+    results name values.
+
+    Example::
+        src = "this is test <b> bold <i>text</i> </b> normal text "
+        for tag in ("b","i"):
+            opener,closer = makeHTMLTags(tag)
+            patt = originalTextFor(opener + SkipTo(closer) + closer)
+            print(patt.searchString(src)[0])
+    prints::
+        ['<b> bold <i>text</i> </b>']
+        ['<i>text</i>']
+    """
+    locMarker = Empty().setParseAction(lambda s,loc,t: loc)
+    endlocMarker = locMarker.copy()
+    endlocMarker.callPreparse = False
+    matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end")
+    if asString:
+        extractText = lambda s,l,t: s[t._original_start:t._original_end]
+    else:
+        def extractText(s,l,t):
+            t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]]
+    matchExpr.setParseAction(extractText)
+    matchExpr.ignoreExprs = expr.ignoreExprs
+    return matchExpr
+
+def ungroup(expr): 
+    """
+    Helper to undo pyparsing's default grouping of And expressions, even
+    if all but one are non-empty.
+    """
+    return TokenConverter(expr).setParseAction(lambda t:t[0])
+
+def locatedExpr(expr):
+    """
+    Helper to decorate a returned token with its starting and ending locations in the input string.
+    This helper adds the following results names:
+     - locn_start = location where matched expression begins
+     - locn_end = location where matched expression ends
+     - value = the actual parsed results
+
+    Be careful if the input text contains C{<TAB>} characters, you may want to call
+    C{L{ParserElement.parseWithTabs}}
+
+    Example::
+        wd = Word(alphas)
+        for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"):
+            print(match)
+    prints::
+        [[0, 'ljsdf', 5]]
+        [[8, 'lksdjjf', 15]]
+        [[18, 'lkkjj', 23]]
+    """
+    locator = Empty().setParseAction(lambda s,l,t: l)
+    return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end"))
+
+
+# convenience constants for positional expressions
+empty       = Empty().setName("empty")
+lineStart   = LineStart().setName("lineStart")
+lineEnd     = LineEnd().setName("lineEnd")
+stringStart = StringStart().setName("stringStart")
+stringEnd   = StringEnd().setName("stringEnd")
+
+_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1])
+_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16)))
+_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8)))
+_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(printables, excludeChars=r'\]', exact=1) | Regex(r"\w", re.UNICODE)
+_charRange = Group(_singleChar + Suppress("-") + _singleChar)
+_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]"
+
+def srange(s):
+    r"""
+    Helper to easily define string ranges for use in Word construction.  Borrows
+    syntax from regexp '[]' string range definitions::
+        srange("[0-9]")   -> "0123456789"
+        srange("[a-z]")   -> "abcdefghijklmnopqrstuvwxyz"
+        srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_"
+    The input string must be enclosed in []'s, and the returned string is the expanded
+    character set joined into a single string.
+    The values enclosed in the []'s may be:
+     - a single character
+     - an escaped character with a leading backslash (such as C{\-} or C{\]})
+     - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) 
+         (C{\0x##} is also supported for backwards compatibility) 
+     - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character)
+     - a range of any of the above, separated by a dash (C{'a-z'}, etc.)
+     - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.)
+    """
+    _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1))
+    try:
+        return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body)
+    except Exception:
+        return ""
+
+def matchOnlyAtCol(n):
+    """
+    Helper method for defining parse actions that require matching at a specific
+    column in the input text.
+    """
+    def verifyCol(strg,locn,toks):
+        if col(locn,strg) != n:
+            raise ParseException(strg,locn,"matched token not at column %d" % n)
+    return verifyCol
+
+def replaceWith(replStr):
+    """
+    Helper method for common parse actions that simply return a literal value.  Especially
+    useful when used with C{L{transformString<ParserElement.transformString>}()}.
+
+    Example::
+        num = Word(nums).setParseAction(lambda toks: int(toks[0]))
+        na = oneOf("N/A NA").setParseAction(replaceWith(math.nan))
+        term = na | num
+        
+        OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234]
+    """
+    return lambda s,l,t: [replStr]
+
+def removeQuotes(s,l,t):
+    """
+    Helper parse action for removing quotation marks from parsed quoted strings.
+
+    Example::
+        # by default, quotation marks are included in parsed results
+        quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"]
+
+        # use removeQuotes to strip quotation marks from parsed results
+        quotedString.setParseAction(removeQuotes)
+        quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"]
+    """
+    return t[0][1:-1]
+
+def tokenMap(func, *args):
+    """
+    Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional 
+    args are passed, they are forwarded to the given function as additional arguments after
+    the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the
+    parsed data to an integer using base 16.
+
+    Example (compare the last to example in L{ParserElement.transformString}::
+        hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16))
+        hex_ints.runTests('''
+            00 11 22 aa FF 0a 0d 1a
+            ''')
+        
+        upperword = Word(alphas).setParseAction(tokenMap(str.upper))
+        OneOrMore(upperword).runTests('''
+            my kingdom for a horse
+            ''')
+
+        wd = Word(alphas).setParseAction(tokenMap(str.title))
+        OneOrMore(wd).setParseAction(' '.join).runTests('''
+            now is the winter of our discontent made glorious summer by this sun of york
+            ''')
+    prints::
+        00 11 22 aa FF 0a 0d 1a
+        [0, 17, 34, 170, 255, 10, 13, 26]
+
+        my kingdom for a horse
+        ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE']
+
+        now is the winter of our discontent made glorious summer by this sun of york
+        ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York']
+    """
+    def pa(s,l,t):
+        return [func(tokn, *args) for tokn in t]
+
+    try:
+        func_name = getattr(func, '__name__', 
+                            getattr(func, '__class__').__name__)
+    except Exception:
+        func_name = str(func)
+    pa.__name__ = func_name
+
+    return pa
+
+upcaseTokens = tokenMap(lambda t: _ustr(t).upper())
+"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}"""
+
+downcaseTokens = tokenMap(lambda t: _ustr(t).lower())
+"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}"""
+    
+def _makeTags(tagStr, xml):
+    """Internal helper to construct opening and closing tag expressions, given a tag name"""
+    if isinstance(tagStr,basestring):
+        resname = tagStr
+        tagStr = Keyword(tagStr, caseless=not xml)
+    else:
+        resname = tagStr.name
+
+    tagAttrName = Word(alphas,alphanums+"_-:")
+    if (xml):
+        tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes )
+        openTag = Suppress("<") + tagStr("tag") + \
+                Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \
+                Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
+    else:
+        printablesLessRAbrack = "".join(c for c in printables if c not in ">")
+        tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack)
+        openTag = Suppress("<") + tagStr("tag") + \
+                Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \
+                Optional( Suppress("=") + tagAttrValue ) ))) + \
+                Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
+    closeTag = Combine(_L("</") + tagStr + ">")
+
+    openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname)
+    closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname)
+    openTag.tag = resname
+    closeTag.tag = resname
+    return openTag, closeTag
+
+def makeHTMLTags(tagStr):
+    """
+    Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches
+    tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values.
+
+    Example::
+        text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>'
+        # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple
+        a,a_end = makeHTMLTags("A")
+        link_expr = a + SkipTo(a_end)("link_text") + a_end
+        
+        for link in link_expr.searchString(text):
+            # attributes in the <A> tag (like "href" shown here) are also accessible as named results
+            print(link.link_text, '->', link.href)
+    prints::
+        pyparsing -> http://pyparsing.wikispaces.com
+    """
+    return _makeTags( tagStr, False )
+
+def makeXMLTags(tagStr):
+    """
+    Helper to construct opening and closing tag expressions for XML, given a tag name. Matches
+    tags only in the given upper/lower case.
+
+    Example: similar to L{makeHTMLTags}
+    """
+    return _makeTags( tagStr, True )
+
+def withAttribute(*args,**attrDict):
+    """
+    Helper to create a validating parse action to be used with start tags created
+    with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag
+    with a required attribute value, to avoid false matches on common tags such as
+    C{<TD>} or C{<DIV>}.
+
+    Call C{withAttribute} with a series of attribute names and values. Specify the list
+    of filter attributes names and values as:
+     - keyword arguments, as in C{(align="right")}, or
+     - as an explicit dict with C{**} operator, when an attribute name is also a Python
+          reserved word, as in C{**{"class":"Customer", "align":"right"}}
+     - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") )
+    For attribute names with a namespace prefix, you must use the second form.  Attribute
+    names are matched insensitive to upper/lower case.
+       
+    If just testing for C{class} (with or without a namespace), use C{L{withClass}}.
+
+    To verify that the attribute exists, but without specifying a value, pass
+    C{withAttribute.ANY_VALUE} as the value.
+
+    Example::
+        html = '''
+            <div>
+            Some text
+            <div type="grid">1 4 0 1 0</div>
+            <div type="graph">1,3 2,3 1,1</div>
+            <div>this has no type</div>
+            </div>
+                
+        '''
+        div,div_end = makeHTMLTags("div")
+
+        # only match div tag having a type attribute with value "grid"
+        div_grid = div().setParseAction(withAttribute(type="grid"))
+        grid_expr = div_grid + SkipTo(div | div_end)("body")
+        for grid_header in grid_expr.searchString(html):
+            print(grid_header.body)
+        
+        # construct a match with any div tag having a type attribute, regardless of the value
+        div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE))
+        div_expr = div_any_type + SkipTo(div | div_end)("body")
+        for div_header in div_expr.searchString(html):
+            print(div_header.body)
+    prints::
+        1 4 0 1 0
+
+        1 4 0 1 0
+        1,3 2,3 1,1
+    """
+    if args:
+        attrs = args[:]
+    else:
+        attrs = attrDict.items()
+    attrs = [(k,v) for k,v in attrs]
+    def pa(s,l,tokens):
+        for attrName,attrValue in attrs:
+            if attrName not in tokens:
+                raise ParseException(s,l,"no matching attribute " + attrName)
+            if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue:
+                raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" %
+                                            (attrName, tokens[attrName], attrValue))
+    return pa
+withAttribute.ANY_VALUE = object()
+
+def withClass(classname, namespace=''):
+    """
+    Simplified version of C{L{withAttribute}} when matching on a div class - made
+    difficult because C{class} is a reserved word in Python.
+
+    Example::
+        html = '''
+            <div>
+            Some text
+            <div class="grid">1 4 0 1 0</div>
+            <div class="graph">1,3 2,3 1,1</div>
+            <div>this &lt;div&gt; has no class</div>
+            </div>
+                
+        '''
+        div,div_end = makeHTMLTags("div")
+        div_grid = div().setParseAction(withClass("grid"))
+        
+        grid_expr = div_grid + SkipTo(div | div_end)("body")
+        for grid_header in grid_expr.searchString(html):
+            print(grid_header.body)
+        
+        div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE))
+        div_expr = div_any_type + SkipTo(div | div_end)("body")
+        for div_header in div_expr.searchString(html):
+            print(div_header.body)
+    prints::
+        1 4 0 1 0
+
+        1 4 0 1 0
+        1,3 2,3 1,1
+    """
+    classattr = "%s:class" % namespace if namespace else "class"
+    return withAttribute(**{classattr : classname})        
+
+opAssoc = _Constants()
+opAssoc.LEFT = object()
+opAssoc.RIGHT = object()
+
+def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ):
+    """
+    Helper method for constructing grammars of expressions made up of
+    operators working in a precedence hierarchy.  Operators may be unary or
+    binary, left- or right-associative.  Parse actions can also be attached
+    to operator expressions. The generated parser will also recognize the use 
+    of parentheses to override operator precedences (see example below).
+    
+    Note: if you define a deep operator list, you may see performance issues
+    when using infixNotation. See L{ParserElement.enablePackrat} for a
+    mechanism to potentially improve your parser performance.
+
+    Parameters:
+     - baseExpr - expression representing the most basic element for the nested
+     - opList - list of tuples, one for each operator precedence level in the
+      expression grammar; each tuple is of the form
+      (opExpr, numTerms, rightLeftAssoc, parseAction), where:
+       - opExpr is the pyparsing expression for the operator;
+          may also be a string, which will be converted to a Literal;
+          if numTerms is 3, opExpr is a tuple of two expressions, for the
+          two operators separating the 3 terms
+       - numTerms is the number of terms for this operator (must
+          be 1, 2, or 3)
+       - rightLeftAssoc is the indicator whether the operator is
+          right or left associative, using the pyparsing-defined
+          constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}.
+       - parseAction is the parse action to be associated with
+          expressions matching this operator expression (the
+          parse action tuple member may be omitted)
+     - lpar - expression for matching left-parentheses (default=C{Suppress('(')})
+     - rpar - expression for matching right-parentheses (default=C{Suppress(')')})
+
+    Example::
+        # simple example of four-function arithmetic with ints and variable names
+        integer = pyparsing_common.signed_integer
+        varname = pyparsing_common.identifier 
+        
+        arith_expr = infixNotation(integer | varname,
+            [
+            ('-', 1, opAssoc.RIGHT),
+            (oneOf('* /'), 2, opAssoc.LEFT),
+            (oneOf('+ -'), 2, opAssoc.LEFT),
+            ])
+        
+        arith_expr.runTests('''
+            5+3*6
+            (5+3)*6
+            -2--11
+            ''', fullDump=False)
+    prints::
+        5+3*6
+        [[5, '+', [3, '*', 6]]]
+
+        (5+3)*6
+        [[[5, '+', 3], '*', 6]]
+
+        -2--11
+        [[['-', 2], '-', ['-', 11]]]
+    """
+    ret = Forward()
+    lastExpr = baseExpr | ( lpar + ret + rpar )
+    for i,operDef in enumerate(opList):
+        opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4]
+        termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr
+        if arity == 3:
+            if opExpr is None or len(opExpr) != 2:
+                raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions")
+            opExpr1, opExpr2 = opExpr
+        thisExpr = Forward().setName(termName)
+        if rightLeftAssoc == opAssoc.LEFT:
+            if arity == 1:
+                matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) )
+            elif arity == 2:
+                if opExpr is not None:
+                    matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) )
+                else:
+                    matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) )
+            elif arity == 3:
+                matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \
+                            Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr )
+            else:
+                raise ValueError("operator must be unary (1), binary (2), or ternary (3)")
+        elif rightLeftAssoc == opAssoc.RIGHT:
+            if arity == 1:
+                # try to avoid LR with this extra test
+                if not isinstance(opExpr, Optional):
+                    opExpr = Optional(opExpr)
+                matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr )
+            elif arity == 2:
+                if opExpr is not None:
+                    matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) )
+                else:
+                    matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) )
+            elif arity == 3:
+                matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \
+                            Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr )
+            else:
+                raise ValueError("operator must be unary (1), binary (2), or ternary (3)")
+        else:
+            raise ValueError("operator must indicate right or left associativity")
+        if pa:
+            matchExpr.setParseAction( pa )
+        thisExpr <<= ( matchExpr.setName(termName) | lastExpr )
+        lastExpr = thisExpr
+    ret <<= lastExpr
+    return ret
+
+operatorPrecedence = infixNotation
+"""(Deprecated) Former name of C{L{infixNotation}}, will be dropped in a future release."""
+
+dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes")
+sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes")
+quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'|
+                       Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes")
+unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal")
+
+def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()):
+    """
+    Helper method for defining nested lists enclosed in opening and closing
+    delimiters ("(" and ")" are the default).
+
+    Parameters:
+     - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression
+     - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression
+     - content - expression for items within the nested lists (default=C{None})
+     - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString})
+
+    If an expression is not provided for the content argument, the nested
+    expression will capture all whitespace-delimited content between delimiters
+    as a list of separate values.
+
+    Use the C{ignoreExpr} argument to define expressions that may contain
+    opening or closing characters that should not be treated as opening
+    or closing characters for nesting, such as quotedString or a comment
+    expression.  Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}.
+    The default is L{quotedString}, but if no expressions are to be ignored,
+    then pass C{None} for this argument.
+
+    Example::
+        data_type = oneOf("void int short long char float double")
+        decl_data_type = Combine(data_type + Optional(Word('*')))
+        ident = Word(alphas+'_', alphanums+'_')
+        number = pyparsing_common.number
+        arg = Group(decl_data_type + ident)
+        LPAR,RPAR = map(Suppress, "()")
+
+        code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment))
+
+        c_function = (decl_data_type("type") 
+                      + ident("name")
+                      + LPAR + Optional(delimitedList(arg), [])("args") + RPAR 
+                      + code_body("body"))
+        c_function.ignore(cStyleComment)
+        
+        source_code = '''
+            int is_odd(int x) { 
+                return (x%2); 
+            }
+                
+            int dec_to_hex(char hchar) { 
+                if (hchar >= '0' && hchar <= '9') { 
+                    return (ord(hchar)-ord('0')); 
+                } else { 
+                    return (10+ord(hchar)-ord('A'));
+                } 
+            }
+        '''
+        for func in c_function.searchString(source_code):
+            print("%(name)s (%(type)s) args: %(args)s" % func)
+
+    prints::
+        is_odd (int) args: [['int', 'x']]
+        dec_to_hex (int) args: [['char', 'hchar']]
+    """
+    if opener == closer:
+        raise ValueError("opening and closing strings cannot be the same")
+    if content is None:
+        if isinstance(opener,basestring) and isinstance(closer,basestring):
+            if len(opener) == 1 and len(closer)==1:
+                if ignoreExpr is not None:
+                    content = (Combine(OneOrMore(~ignoreExpr +
+                                    CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1))
+                                ).setParseAction(lambda t:t[0].strip()))
+                else:
+                    content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS
+                                ).setParseAction(lambda t:t[0].strip()))
+            else:
+                if ignoreExpr is not None:
+                    content = (Combine(OneOrMore(~ignoreExpr + 
+                                    ~Literal(opener) + ~Literal(closer) +
+                                    CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1))
+                                ).setParseAction(lambda t:t[0].strip()))
+                else:
+                    content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) +
+                                    CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1))
+                                ).setParseAction(lambda t:t[0].strip()))
+        else:
+            raise ValueError("opening and closing arguments must be strings if no content expression is given")
+    ret = Forward()
+    if ignoreExpr is not None:
+        ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) )
+    else:
+        ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content )  + Suppress(closer) )
+    ret.setName('nested %s%s expression' % (opener,closer))
+    return ret
+
+def indentedBlock(blockStatementExpr, indentStack, indent=True):
+    """
+    Helper method for defining space-delimited indentation blocks, such as
+    those used to define block statements in Python source code.
+
+    Parameters:
+     - blockStatementExpr - expression defining syntax of statement that
+            is repeated within the indented block
+     - indentStack - list created by caller to manage indentation stack
+            (multiple statementWithIndentedBlock expressions within a single grammar
+            should share a common indentStack)
+     - indent - boolean indicating whether block must be indented beyond the
+            the current level; set to False for block of left-most statements
+            (default=C{True})
+
+    A valid block must contain at least one C{blockStatement}.
+
+    Example::
+        data = '''
+        def A(z):
+          A1
+          B = 100
+          G = A2
+          A2
+          A3
+        B
+        def BB(a,b,c):
+          BB1
+          def BBA():
+            bba1
+            bba2
+            bba3
+        C
+        D
+        def spam(x,y):
+             def eggs(z):
+                 pass
+        '''
+
+
+        indentStack = [1]
+        stmt = Forward()
+
+        identifier = Word(alphas, alphanums)
+        funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":")
+        func_body = indentedBlock(stmt, indentStack)
+        funcDef = Group( funcDecl + func_body )
+
+        rvalue = Forward()
+        funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")")
+        rvalue << (funcCall | identifier | Word(nums))
+        assignment = Group(identifier + "=" + rvalue)
+        stmt << ( funcDef | assignment | identifier )
+
+        module_body = OneOrMore(stmt)
+
+        parseTree = module_body.parseString(data)
+        parseTree.pprint()
+    prints::
+        [['def',
+          'A',
+          ['(', 'z', ')'],
+          ':',
+          [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]],
+         'B',
+         ['def',
+          'BB',
+          ['(', 'a', 'b', 'c', ')'],
+          ':',
+          [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]],
+         'C',
+         'D',
+         ['def',
+          'spam',
+          ['(', 'x', 'y', ')'],
+          ':',
+          [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] 
+    """
+    def checkPeerIndent(s,l,t):
+        if l >= len(s): return
+        curCol = col(l,s)
+        if curCol != indentStack[-1]:
+            if curCol > indentStack[-1]:
+                raise ParseFatalException(s,l,"illegal nesting")
+            raise ParseException(s,l,"not a peer entry")
+
+    def checkSubIndent(s,l,t):
+        curCol = col(l,s)
+        if curCol > indentStack[-1]:
+            indentStack.append( curCol )
+        else:
+            raise ParseException(s,l,"not a subentry")
+
+    def checkUnindent(s,l,t):
+        if l >= len(s): return
+        curCol = col(l,s)
+        if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]):
+            raise ParseException(s,l,"not an unindent")
+        indentStack.pop()
+
+    NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress())
+    INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT')
+    PEER   = Empty().setParseAction(checkPeerIndent).setName('')
+    UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT')
+    if indent:
+        smExpr = Group( Optional(NL) +
+            #~ FollowedBy(blockStatementExpr) +
+            INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT)
+    else:
+        smExpr = Group( Optional(NL) +
+            (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) )
+    blockStatementExpr.ignore(_bslash + LineEnd())
+    return smExpr.setName('indented block')
+
+alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]")
+punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]")
+
+anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag'))
+_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\''))
+commonHTMLEntity = Regex('&(?P<entity>' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity")
+def replaceHTMLEntity(t):
+    """Helper parser action to replace common HTML entities with their special characters"""
+    return _htmlEntityMap.get(t.entity)
+
+# it's easy to get these comment structures wrong - they're very common, so may as well make them available
+cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment")
+"Comment of the form C{/* ... */}"
+
+htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment")
+"Comment of the form C{<!-- ... -->}"
+
+restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line")
+dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment")
+"Comment of the form C{// ... (to end of line)}"
+
+cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment")
+"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}"
+
+javaStyleComment = cppStyleComment
+"Same as C{L{cppStyleComment}}"
+
+pythonStyleComment = Regex(r"#.*").setName("Python style comment")
+"Comment of the form C{# ... (to end of line)}"
+
+_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') +
+                                  Optional( Word(" \t") +
+                                            ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem")
+commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList")
+"""(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas.
+   This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}."""
+
+# some other useful expressions - using lower-case class name since we are really using this as a namespace
+class pyparsing_common:
+    """
+    Here are some common low-level expressions that may be useful in jump-starting parser development:
+     - numeric forms (L{integers<integer>}, L{reals<real>}, L{scientific notation<sci_real>})
+     - common L{programming identifiers<identifier>}
+     - network addresses (L{MAC<mac_address>}, L{IPv4<ipv4_address>}, L{IPv6<ipv6_address>})
+     - ISO8601 L{dates<iso8601_date>} and L{datetime<iso8601_datetime>}
+     - L{UUID<uuid>}
+     - L{comma-separated list<comma_separated_list>}
+    Parse actions:
+     - C{L{convertToInteger}}
+     - C{L{convertToFloat}}
+     - C{L{convertToDate}}
+     - C{L{convertToDatetime}}
+     - C{L{stripHTMLTags}}
+     - C{L{upcaseTokens}}
+     - C{L{downcaseTokens}}
+
+    Example::
+        pyparsing_common.number.runTests('''
+            # any int or real number, returned as the appropriate type
+            100
+            -100
+            +100
+            3.14159
+            6.02e23
+            1e-12
+            ''')
+
+        pyparsing_common.fnumber.runTests('''
+            # any int or real number, returned as float
+            100
+            -100
+            +100
+            3.14159
+            6.02e23
+            1e-12
+            ''')
+
+        pyparsing_common.hex_integer.runTests('''
+            # hex numbers
+            100
+            FF
+            ''')
+
+        pyparsing_common.fraction.runTests('''
+            # fractions
+            1/2
+            -3/4
+            ''')
+
+        pyparsing_common.mixed_integer.runTests('''
+            # mixed fractions
+            1
+            1/2
+            -3/4
+            1-3/4
+            ''')
+
+        import uuid
+        pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID))
+        pyparsing_common.uuid.runTests('''
+            # uuid
+            12345678-1234-5678-1234-567812345678
+            ''')
+    prints::
+        # any int or real number, returned as the appropriate type
+        100
+        [100]
+
+        -100
+        [-100]
+
+        +100
+        [100]
+
+        3.14159
+        [3.14159]
+
+        6.02e23
+        [6.02e+23]
+
+        1e-12
+        [1e-12]
+
+        # any int or real number, returned as float
+        100
+        [100.0]
+
+        -100
+        [-100.0]
+
+        +100
+        [100.0]
+
+        3.14159
+        [3.14159]
+
+        6.02e23
+        [6.02e+23]
+
+        1e-12
+        [1e-12]
+
+        # hex numbers
+        100
+        [256]
+
+        FF
+        [255]
+
+        # fractions
+        1/2
+        [0.5]
+
+        -3/4
+        [-0.75]
+
+        # mixed fractions
+        1
+        [1]
+
+        1/2
+        [0.5]
+
+        -3/4
+        [-0.75]
+
+        1-3/4
+        [1.75]
+
+        # uuid
+        12345678-1234-5678-1234-567812345678
+        [UUID('12345678-1234-5678-1234-567812345678')]
+    """
+
+    convertToInteger = tokenMap(int)
+    """
+    Parse action for converting parsed integers to Python int
+    """
+
+    convertToFloat = tokenMap(float)
+    """
+    Parse action for converting parsed numbers to Python float
+    """
+
+    integer = Word(nums).setName("integer").setParseAction(convertToInteger)
+    """expression that parses an unsigned integer, returns an int"""
+
+    hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16))
+    """expression that parses a hexadecimal integer, returns an int"""
+
+    signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger)
+    """expression that parses an integer with optional leading sign, returns an int"""
+
+    fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction")
+    """fractional expression of an integer divided by an integer, returns a float"""
+    fraction.addParseAction(lambda t: t[0]/t[-1])
+
+    mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction")
+    """mixed integer of the form 'integer - fraction', with optional leading integer, returns float"""
+    mixed_integer.addParseAction(sum)
+
+    real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat)
+    """expression that parses a floating point number and returns a float"""
+
+    sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat)
+    """expression that parses a floating point number with optional scientific notation and returns a float"""
+
+    # streamlining this expression makes the docs nicer-looking
+    number = (sci_real | real | signed_integer).streamline()
+    """any numeric expression, returns the corresponding Python type"""
+
+    fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat)
+    """any int or real number, returned as float"""
+    
+    identifier = Word(alphas+'_', alphanums+'_').setName("identifier")
+    """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')"""
+    
+    ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address")
+    "IPv4 address (C{0.0.0.0 - 255.255.255.255})"
+
+    _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer")
+    _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address")
+    _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address")
+    _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8)
+    _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address")
+    ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address")
+    "IPv6 address (long, short, or mixed form)"
+    
+    mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address")
+    "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)"
+
+    @staticmethod
+    def convertToDate(fmt="%Y-%m-%d"):
+        """
+        Helper to create a parse action for converting parsed date string to Python datetime.date
+
+        Params -
+         - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"})
+
+        Example::
+            date_expr = pyparsing_common.iso8601_date.copy()
+            date_expr.setParseAction(pyparsing_common.convertToDate())
+            print(date_expr.parseString("1999-12-31"))
+        prints::
+            [datetime.date(1999, 12, 31)]
+        """
+        def cvt_fn(s,l,t):
+            try:
+                return datetime.strptime(t[0], fmt).date()
+            except ValueError as ve:
+                raise ParseException(s, l, str(ve))
+        return cvt_fn
+
+    @staticmethod
+    def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"):
+        """
+        Helper to create a parse action for converting parsed datetime string to Python datetime.datetime
+
+        Params -
+         - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"})
+
+        Example::
+            dt_expr = pyparsing_common.iso8601_datetime.copy()
+            dt_expr.setParseAction(pyparsing_common.convertToDatetime())
+            print(dt_expr.parseString("1999-12-31T23:59:59.999"))
+        prints::
+            [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)]
+        """
+        def cvt_fn(s,l,t):
+            try:
+                return datetime.strptime(t[0], fmt)
+            except ValueError as ve:
+                raise ParseException(s, l, str(ve))
+        return cvt_fn
+
+    iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date")
+    "ISO8601 date (C{yyyy-mm-dd})"
+
+    iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime")
+    "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}"
+
+    uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID")
+    "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})"
+
+    _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress()
+    @staticmethod
+    def stripHTMLTags(s, l, tokens):
+        """
+        Parse action to remove HTML tags from web page HTML source
+
+        Example::
+            # strip HTML links from normal text 
+            text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>'
+            td,td_end = makeHTMLTags("TD")
+            table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end
+            
+            print(table_text.parseString(text).body) # -> 'More info at the pyparsing wiki page'
+        """
+        return pyparsing_common._html_stripper.transformString(tokens[0])
+
+    _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') 
+                                        + Optional( White(" \t") ) ) ).streamline().setName("commaItem")
+    comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list")
+    """Predefined expression of 1 or more printable words or quoted strings, separated by commas."""
+
+    upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper()))
+    """Parse action to convert tokens to upper case."""
+
+    downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower()))
+    """Parse action to convert tokens to lower case."""
+
+
+if __name__ == "__main__":
+
+    selectToken    = CaselessLiteral("select")
+    fromToken      = CaselessLiteral("from")
+
+    ident          = Word(alphas, alphanums + "_$")
+
+    columnName     = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens)
+    columnNameList = Group(delimitedList(columnName)).setName("columns")
+    columnSpec     = ('*' | columnNameList)
+
+    tableName      = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens)
+    tableNameList  = Group(delimitedList(tableName)).setName("tables")
+    
+    simpleSQL      = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables")
+
+    # demo runTests method, including embedded comments in test string
+    simpleSQL.runTests("""
+        # '*' as column list and dotted table name
+        select * from SYS.XYZZY
+
+        # caseless match on "SELECT", and casts back to "select"
+        SELECT * from XYZZY, ABC
+
+        # list of column names, and mixed case SELECT keyword
+        Select AA,BB,CC from Sys.dual
+
+        # multiple tables
+        Select A, B, C from Sys.dual, Table2
+
+        # invalid SELECT keyword - should fail
+        Xelect A, B, C from Sys.dual
+
+        # incomplete command - should fail
+        Select
+
+        # invalid column name - should fail
+        Select ^^^ frox Sys.dual
+
+        """)
+
+    pyparsing_common.number.runTests("""
+        100
+        -100
+        +100
+        3.14159
+        6.02e23
+        1e-12
+        """)
+
+    # any int or real number, returned as float
+    pyparsing_common.fnumber.runTests("""
+        100
+        -100
+        +100
+        3.14159
+        6.02e23
+        1e-12
+        """)
+
+    pyparsing_common.hex_integer.runTests("""
+        100
+        FF
+        """)
+
+    import uuid
+    pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID))
+    pyparsing_common.uuid.runTests("""
+        12345678-1234-5678-1234-567812345678
+        """)
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/six.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/six.py
new file mode 100644
index 00000000..190c0239
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/_vendor/six.py
@@ -0,0 +1,868 @@
+"""Utilities for writing code that runs on Python 2 and 3"""
+
+# Copyright (c) 2010-2015 Benjamin Peterson
+#
+# 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 __future__ import absolute_import
+
+import functools
+import itertools
+import operator
+import sys
+import types
+
+__author__ = "Benjamin Peterson <benjamin@python.org>"
+__version__ = "1.10.0"
+
+
+# Useful for very coarse version differentiation.
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
+PY34 = sys.version_info[0:2] >= (3, 4)
+
+if PY3:
+    string_types = str,
+    integer_types = int,
+    class_types = type,
+    text_type = str
+    binary_type = bytes
+
+    MAXSIZE = sys.maxsize
+else:
+    string_types = basestring,
+    integer_types = (int, long)
+    class_types = (type, types.ClassType)
+    text_type = unicode
+    binary_type = str
+
+    if sys.platform.startswith("java"):
+        # Jython always uses 32 bits.
+        MAXSIZE = int((1 << 31) - 1)
+    else:
+        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
+        class X(object):
+
+            def __len__(self):
+                return 1 << 31
+        try:
+            len(X())
+        except OverflowError:
+            # 32-bit
+            MAXSIZE = int((1 << 31) - 1)
+        else:
+            # 64-bit
+            MAXSIZE = int((1 << 63) - 1)
+        del X
+
+
+def _add_doc(func, doc):
+    """Add documentation to a function."""
+    func.__doc__ = doc
+
+
+def _import_module(name):
+    """Import module, returning the module after the last dot."""
+    __import__(name)
+    return sys.modules[name]
+
+
+class _LazyDescr(object):
+
+    def __init__(self, name):
+        self.name = name
+
+    def __get__(self, obj, tp):
+        result = self._resolve()
+        setattr(obj, self.name, result)  # Invokes __set__.
+        try:
+            # This is a bit ugly, but it avoids running this again by
+            # removing this descriptor.
+            delattr(obj.__class__, self.name)
+        except AttributeError:
+            pass
+        return result
+
+
+class MovedModule(_LazyDescr):
+
+    def __init__(self, name, old, new=None):
+        super(MovedModule, self).__init__(name)
+        if PY3:
+            if new is None:
+                new = name
+            self.mod = new
+        else:
+            self.mod = old
+
+    def _resolve(self):
+        return _import_module(self.mod)
+
+    def __getattr__(self, attr):
+        _module = self._resolve()
+        value = getattr(_module, attr)
+        setattr(self, attr, value)
+        return value
+
+
+class _LazyModule(types.ModuleType):
+
+    def __init__(self, name):
+        super(_LazyModule, self).__init__(name)
+        self.__doc__ = self.__class__.__doc__
+
+    def __dir__(self):
+        attrs = ["__doc__", "__name__"]
+        attrs += [attr.name for attr in self._moved_attributes]
+        return attrs
+
+    # Subclasses should override this
+    _moved_attributes = []
+
+
+class MovedAttribute(_LazyDescr):
+
+    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
+        super(MovedAttribute, self).__init__(name)
+        if PY3:
+            if new_mod is None:
+                new_mod = name
+            self.mod = new_mod
+            if new_attr is None:
+                if old_attr is None:
+                    new_attr = name
+                else:
+                    new_attr = old_attr
+            self.attr = new_attr
+        else:
+            self.mod = old_mod
+            if old_attr is None:
+                old_attr = name
+            self.attr = old_attr
+
+    def _resolve(self):
+        module = _import_module(self.mod)
+        return getattr(module, self.attr)
+
+
+class _SixMetaPathImporter(object):
+
+    """
+    A meta path importer to import six.moves and its submodules.
+
+    This class implements a PEP302 finder and loader. It should be compatible
+    with Python 2.5 and all existing versions of Python3
+    """
+
+    def __init__(self, six_module_name):
+        self.name = six_module_name
+        self.known_modules = {}
+
+    def _add_module(self, mod, *fullnames):
+        for fullname in fullnames:
+            self.known_modules[self.name + "." + fullname] = mod
+
+    def _get_module(self, fullname):
+        return self.known_modules[self.name + "." + fullname]
+
+    def find_module(self, fullname, path=None):
+        if fullname in self.known_modules:
+            return self
+        return None
+
+    def __get_module(self, fullname):
+        try:
+            return self.known_modules[fullname]
+        except KeyError:
+            raise ImportError("This loader does not know module " + fullname)
+
+    def load_module(self, fullname):
+        try:
+            # in case of a reload
+            return sys.modules[fullname]
+        except KeyError:
+            pass
+        mod = self.__get_module(fullname)
+        if isinstance(mod, MovedModule):
+            mod = mod._resolve()
+        else:
+            mod.__loader__ = self
+        sys.modules[fullname] = mod
+        return mod
+
+    def is_package(self, fullname):
+        """
+        Return true, if the named module is a package.
+
+        We need this method to get correct spec objects with
+        Python 3.4 (see PEP451)
+        """
+        return hasattr(self.__get_module(fullname), "__path__")
+
+    def get_code(self, fullname):
+        """Return None
+
+        Required, if is_package is implemented"""
+        self.__get_module(fullname)  # eventually raises ImportError
+        return None
+    get_source = get_code  # same as get_code
+
+_importer = _SixMetaPathImporter(__name__)
+
+
+class _MovedItems(_LazyModule):
+
+    """Lazy loading of moved objects"""
+    __path__ = []  # mark as package
+
+
+_moved_attributes = [
+    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
+    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
+    MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
+    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
+    MovedAttribute("intern", "__builtin__", "sys"),
+    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
+    MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
+    MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
+    MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
+    MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
+    MovedAttribute("reduce", "__builtin__", "functools"),
+    MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
+    MovedAttribute("StringIO", "StringIO", "io"),
+    MovedAttribute("UserDict", "UserDict", "collections"),
+    MovedAttribute("UserList", "UserList", "collections"),
+    MovedAttribute("UserString", "UserString", "collections"),
+    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
+    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
+    MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
+    MovedModule("builtins", "__builtin__"),
+    MovedModule("configparser", "ConfigParser"),
+    MovedModule("copyreg", "copy_reg"),
+    MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
+    MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
+    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
+    MovedModule("http_cookies", "Cookie", "http.cookies"),
+    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
+    MovedModule("html_parser", "HTMLParser", "html.parser"),
+    MovedModule("http_client", "httplib", "http.client"),
+    MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
+    MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
+    MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
+    MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
+    MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
+    MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
+    MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
+    MovedModule("cPickle", "cPickle", "pickle"),
+    MovedModule("queue", "Queue"),
+    MovedModule("reprlib", "repr"),
+    MovedModule("socketserver", "SocketServer"),
+    MovedModule("_thread", "thread", "_thread"),
+    MovedModule("tkinter", "Tkinter"),
+    MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
+    MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
+    MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
+    MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
+    MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
+    MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
+    MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
+    MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
+    MovedModule("tkinter_colorchooser", "tkColorChooser",
+                "tkinter.colorchooser"),
+    MovedModule("tkinter_commondialog", "tkCommonDialog",
+                "tkinter.commondialog"),
+    MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
+    MovedModule("tkinter_font", "tkFont", "tkinter.font"),
+    MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
+    MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
+                "tkinter.simpledialog"),
+    MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
+    MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
+    MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
+    MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
+    MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
+    MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
+]
+# Add windows specific modules.
+if sys.platform == "win32":
+    _moved_attributes += [
+        MovedModule("winreg", "_winreg"),
+    ]
+
+for attr in _moved_attributes:
+    setattr(_MovedItems, attr.name, attr)
+    if isinstance(attr, MovedModule):
+        _importer._add_module(attr, "moves." + attr.name)
+del attr
+
+_MovedItems._moved_attributes = _moved_attributes
+
+moves = _MovedItems(__name__ + ".moves")
+_importer._add_module(moves, "moves")
+
+
+class Module_six_moves_urllib_parse(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_parse"""
+
+
+_urllib_parse_moved_attributes = [
+    MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
+    MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
+    MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
+    MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
+    MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
+    MovedAttribute("urljoin", "urlparse", "urllib.parse"),
+    MovedAttribute("urlparse", "urlparse", "urllib.parse"),
+    MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
+    MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
+    MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
+    MovedAttribute("quote", "urllib", "urllib.parse"),
+    MovedAttribute("quote_plus", "urllib", "urllib.parse"),
+    MovedAttribute("unquote", "urllib", "urllib.parse"),
+    MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
+    MovedAttribute("urlencode", "urllib", "urllib.parse"),
+    MovedAttribute("splitquery", "urllib", "urllib.parse"),
+    MovedAttribute("splittag", "urllib", "urllib.parse"),
+    MovedAttribute("splituser", "urllib", "urllib.parse"),
+    MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_params", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_query", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
+]
+for attr in _urllib_parse_moved_attributes:
+    setattr(Module_six_moves_urllib_parse, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
+                      "moves.urllib_parse", "moves.urllib.parse")
+
+
+class Module_six_moves_urllib_error(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_error"""
+
+
+_urllib_error_moved_attributes = [
+    MovedAttribute("URLError", "urllib2", "urllib.error"),
+    MovedAttribute("HTTPError", "urllib2", "urllib.error"),
+    MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
+]
+for attr in _urllib_error_moved_attributes:
+    setattr(Module_six_moves_urllib_error, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
+                      "moves.urllib_error", "moves.urllib.error")
+
+
+class Module_six_moves_urllib_request(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_request"""
+
+
+_urllib_request_moved_attributes = [
+    MovedAttribute("urlopen", "urllib2", "urllib.request"),
+    MovedAttribute("install_opener", "urllib2", "urllib.request"),
+    MovedAttribute("build_opener", "urllib2", "urllib.request"),
+    MovedAttribute("pathname2url", "urllib", "urllib.request"),
+    MovedAttribute("url2pathname", "urllib", "urllib.request"),
+    MovedAttribute("getproxies", "urllib", "urllib.request"),
+    MovedAttribute("Request", "urllib2", "urllib.request"),
+    MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
+    MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
+    MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
+    MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
+    MovedAttribute("FileHandler", "urllib2", "urllib.request"),
+    MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
+    MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
+    MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
+    MovedAttribute("urlretrieve", "urllib", "urllib.request"),
+    MovedAttribute("urlcleanup", "urllib", "urllib.request"),
+    MovedAttribute("URLopener", "urllib", "urllib.request"),
+    MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
+    MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
+]
+for attr in _urllib_request_moved_attributes:
+    setattr(Module_six_moves_urllib_request, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
+                      "moves.urllib_request", "moves.urllib.request")
+
+
+class Module_six_moves_urllib_response(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_response"""
+
+
+_urllib_response_moved_attributes = [
+    MovedAttribute("addbase", "urllib", "urllib.response"),
+    MovedAttribute("addclosehook", "urllib", "urllib.response"),
+    MovedAttribute("addinfo", "urllib", "urllib.response"),
+    MovedAttribute("addinfourl", "urllib", "urllib.response"),
+]
+for attr in _urllib_response_moved_attributes:
+    setattr(Module_six_moves_urllib_response, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
+                      "moves.urllib_response", "moves.urllib.response")
+
+
+class Module_six_moves_urllib_robotparser(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_robotparser"""
+
+
+_urllib_robotparser_moved_attributes = [
+    MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
+]
+for attr in _urllib_robotparser_moved_attributes:
+    setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
+                      "moves.urllib_robotparser", "moves.urllib.robotparser")
+
+
+class Module_six_moves_urllib(types.ModuleType):
+
+    """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
+    __path__ = []  # mark as package
+    parse = _importer._get_module("moves.urllib_parse")
+    error = _importer._get_module("moves.urllib_error")
+    request = _importer._get_module("moves.urllib_request")
+    response = _importer._get_module("moves.urllib_response")
+    robotparser = _importer._get_module("moves.urllib_robotparser")
+
+    def __dir__(self):
+        return ['parse', 'error', 'request', 'response', 'robotparser']
+
+_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
+                      "moves.urllib")
+
+
+def add_move(move):
+    """Add an item to six.moves."""
+    setattr(_MovedItems, move.name, move)
+
+
+def remove_move(name):
+    """Remove item from six.moves."""
+    try:
+        delattr(_MovedItems, name)
+    except AttributeError:
+        try:
+            del moves.__dict__[name]
+        except KeyError:
+            raise AttributeError("no such move, %r" % (name,))
+
+
+if PY3:
+    _meth_func = "__func__"
+    _meth_self = "__self__"
+
+    _func_closure = "__closure__"
+    _func_code = "__code__"
+    _func_defaults = "__defaults__"
+    _func_globals = "__globals__"
+else:
+    _meth_func = "im_func"
+    _meth_self = "im_self"
+
+    _func_closure = "func_closure"
+    _func_code = "func_code"
+    _func_defaults = "func_defaults"
+    _func_globals = "func_globals"
+
+
+try:
+    advance_iterator = next
+except NameError:
+    def advance_iterator(it):
+        return it.next()
+next = advance_iterator
+
+
+try:
+    callable = callable
+except NameError:
+    def callable(obj):
+        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
+
+
+if PY3:
+    def get_unbound_function(unbound):
+        return unbound
+
+    create_bound_method = types.MethodType
+
+    def create_unbound_method(func, cls):
+        return func
+
+    Iterator = object
+else:
+    def get_unbound_function(unbound):
+        return unbound.im_func
+
+    def create_bound_method(func, obj):
+        return types.MethodType(func, obj, obj.__class__)
+
+    def create_unbound_method(func, cls):
+        return types.MethodType(func, None, cls)
+
+    class Iterator(object):
+
+        def next(self):
+            return type(self).__next__(self)
+
+    callable = callable
+_add_doc(get_unbound_function,
+         """Get the function out of a possibly unbound function""")
+
+
+get_method_function = operator.attrgetter(_meth_func)
+get_method_self = operator.attrgetter(_meth_self)
+get_function_closure = operator.attrgetter(_func_closure)
+get_function_code = operator.attrgetter(_func_code)
+get_function_defaults = operator.attrgetter(_func_defaults)
+get_function_globals = operator.attrgetter(_func_globals)
+
+
+if PY3:
+    def iterkeys(d, **kw):
+        return iter(d.keys(**kw))
+
+    def itervalues(d, **kw):
+        return iter(d.values(**kw))
+
+    def iteritems(d, **kw):
+        return iter(d.items(**kw))
+
+    def iterlists(d, **kw):
+        return iter(d.lists(**kw))
+
+    viewkeys = operator.methodcaller("keys")
+
+    viewvalues = operator.methodcaller("values")
+
+    viewitems = operator.methodcaller("items")
+else:
+    def iterkeys(d, **kw):
+        return d.iterkeys(**kw)
+
+    def itervalues(d, **kw):
+        return d.itervalues(**kw)
+
+    def iteritems(d, **kw):
+        return d.iteritems(**kw)
+
+    def iterlists(d, **kw):
+        return d.iterlists(**kw)
+
+    viewkeys = operator.methodcaller("viewkeys")
+
+    viewvalues = operator.methodcaller("viewvalues")
+
+    viewitems = operator.methodcaller("viewitems")
+
+_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
+_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
+_add_doc(iteritems,
+         "Return an iterator over the (key, value) pairs of a dictionary.")
+_add_doc(iterlists,
+         "Return an iterator over the (key, [values]) pairs of a dictionary.")
+
+
+if PY3:
+    def b(s):
+        return s.encode("latin-1")
+
+    def u(s):
+        return s
+    unichr = chr
+    import struct
+    int2byte = struct.Struct(">B").pack
+    del struct
+    byte2int = operator.itemgetter(0)
+    indexbytes = operator.getitem
+    iterbytes = iter
+    import io
+    StringIO = io.StringIO
+    BytesIO = io.BytesIO
+    _assertCountEqual = "assertCountEqual"
+    if sys.version_info[1] <= 1:
+        _assertRaisesRegex = "assertRaisesRegexp"
+        _assertRegex = "assertRegexpMatches"
+    else:
+        _assertRaisesRegex = "assertRaisesRegex"
+        _assertRegex = "assertRegex"
+else:
+    def b(s):
+        return s
+    # Workaround for standalone backslash
+
+    def u(s):
+        return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
+    unichr = unichr
+    int2byte = chr
+
+    def byte2int(bs):
+        return ord(bs[0])
+
+    def indexbytes(buf, i):
+        return ord(buf[i])
+    iterbytes = functools.partial(itertools.imap, ord)
+    import StringIO
+    StringIO = BytesIO = StringIO.StringIO
+    _assertCountEqual = "assertItemsEqual"
+    _assertRaisesRegex = "assertRaisesRegexp"
+    _assertRegex = "assertRegexpMatches"
+_add_doc(b, """Byte literal""")
+_add_doc(u, """Text literal""")
+
+
+def assertCountEqual(self, *args, **kwargs):
+    return getattr(self, _assertCountEqual)(*args, **kwargs)
+
+
+def assertRaisesRegex(self, *args, **kwargs):
+    return getattr(self, _assertRaisesRegex)(*args, **kwargs)
+
+
+def assertRegex(self, *args, **kwargs):
+    return getattr(self, _assertRegex)(*args, **kwargs)
+
+
+if PY3:
+    exec_ = getattr(moves.builtins, "exec")
+
+    def reraise(tp, value, tb=None):
+        if value is None:
+            value = tp()
+        if value.__traceback__ is not tb:
+            raise value.with_traceback(tb)
+        raise value
+
+else:
+    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 reraise(tp, value, tb=None):
+    raise tp, value, tb
+""")
+
+
+if sys.version_info[:2] == (3, 2):
+    exec_("""def raise_from(value, from_value):
+    if from_value is None:
+        raise value
+    raise value from from_value
+""")
+elif sys.version_info[:2] > (3, 2):
+    exec_("""def raise_from(value, from_value):
+    raise value from from_value
+""")
+else:
+    def raise_from(value, from_value):
+        raise value
+
+
+print_ = getattr(moves.builtins, "print", None)
+if print_ is None:
+    def print_(*args, **kwargs):
+        """The new-style print function for Python 2.4 and 2.5."""
+        fp = kwargs.pop("file", sys.stdout)
+        if fp is None:
+            return
+
+        def write(data):
+            if not isinstance(data, basestring):
+                data = str(data)
+            # If the file has an encoding, encode unicode with it.
+            if (isinstance(fp, file) and
+                    isinstance(data, unicode) and
+                    fp.encoding is not None):
+                errors = getattr(fp, "errors", None)
+                if errors is None:
+                    errors = "strict"
+                data = data.encode(fp.encoding, errors)
+            fp.write(data)
+        want_unicode = False
+        sep = kwargs.pop("sep", None)
+        if sep is not None:
+            if isinstance(sep, unicode):
+                want_unicode = True
+            elif not isinstance(sep, str):
+                raise TypeError("sep must be None or a string")
+        end = kwargs.pop("end", None)
+        if end is not None:
+            if isinstance(end, unicode):
+                want_unicode = True
+            elif not isinstance(end, str):
+                raise TypeError("end must be None or a string")
+        if kwargs:
+            raise TypeError("invalid keyword arguments to print()")
+        if not want_unicode:
+            for arg in args:
+                if isinstance(arg, unicode):
+                    want_unicode = True
+                    break
+        if want_unicode:
+            newline = unicode("\n")
+            space = unicode(" ")
+        else:
+            newline = "\n"
+            space = " "
+        if sep is None:
+            sep = space
+        if end is None:
+            end = newline
+        for i, arg in enumerate(args):
+            if i:
+                write(sep)
+            write(arg)
+        write(end)
+if sys.version_info[:2] < (3, 3):
+    _print = print_
+
+    def print_(*args, **kwargs):
+        fp = kwargs.get("file", sys.stdout)
+        flush = kwargs.pop("flush", False)
+        _print(*args, **kwargs)
+        if flush and fp is not None:
+            fp.flush()
+
+_add_doc(reraise, """Reraise an exception.""")
+
+if sys.version_info[0:2] < (3, 4):
+    def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
+              updated=functools.WRAPPER_UPDATES):
+        def wrapper(f):
+            f = functools.wraps(wrapped, assigned, updated)(f)
+            f.__wrapped__ = wrapped
+            return f
+        return wrapper
+else:
+    wraps = functools.wraps
+
+
+def with_metaclass(meta, *bases):
+    """Create a base class with a metaclass."""
+    # This requires a bit of explanation: the basic idea is to make a dummy
+    # metaclass for one level of class instantiation that replaces itself with
+    # the actual metaclass.
+    class metaclass(meta):
+
+        def __new__(cls, name, this_bases, d):
+            return meta(name, bases, d)
+    return type.__new__(metaclass, 'temporary_class', (), {})
+
+
+def add_metaclass(metaclass):
+    """Class decorator for creating a class with a metaclass."""
+    def wrapper(cls):
+        orig_vars = cls.__dict__.copy()
+        slots = orig_vars.get('__slots__')
+        if slots is not None:
+            if isinstance(slots, str):
+                slots = [slots]
+            for slots_var in slots:
+                orig_vars.pop(slots_var)
+        orig_vars.pop('__dict__', None)
+        orig_vars.pop('__weakref__', None)
+        return metaclass(cls.__name__, cls.__bases__, orig_vars)
+    return wrapper
+
+
+def python_2_unicode_compatible(klass):
+    """
+    A decorator that defines __unicode__ and __str__ methods under Python 2.
+    Under Python 3 it does nothing.
+
+    To support Python 2 and 3 with a single code base, define a __str__ method
+    returning text and apply this decorator to the class.
+    """
+    if PY2:
+        if '__str__' not in klass.__dict__:
+            raise ValueError("@python_2_unicode_compatible cannot be applied "
+                             "to %s because it doesn't define __str__()." %
+                             klass.__name__)
+        klass.__unicode__ = klass.__str__
+        klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
+    return klass
+
+
+# Complete the moves implementation.
+# This code is at the end of this module to speed up module loading.
+# Turn this module into a package.
+__path__ = []  # required for PEP 302 and PEP 451
+__package__ = __name__  # see PEP 366 @ReservedAssignment
+if globals().get("__spec__") is not None:
+    __spec__.submodule_search_locations = []  # PEP 451 @UndefinedVariable
+# Remove other six meta path importers, since they cause problems. This can
+# happen if six is removed from sys.modules and then reloaded. (Setuptools does
+# this for some reason.)
+if sys.meta_path:
+    for i, importer in enumerate(sys.meta_path):
+        # Here's some real nastiness: Another "instance" of the six module might
+        # be floating around. Therefore, we can't use isinstance() to check for
+        # the six meta path importer, since the other six instance will have
+        # inserted an importer with different class.
+        if (type(importer).__name__ == "_SixMetaPathImporter" and
+                importer.name == __name__):
+            del sys.meta_path[i]
+            break
+    del i, importer
+# Finally, add the importer to the meta path import hook.
+sys.meta_path.append(_importer)
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/extern/__init__.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/extern/__init__.py
new file mode 100644
index 00000000..b4156fec
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/extern/__init__.py
@@ -0,0 +1,73 @@
+import sys
+
+
+class VendorImporter:
+    """
+    A PEP 302 meta path importer for finding optionally-vendored
+    or otherwise naturally-installed packages from root_name.
+    """
+
+    def __init__(self, root_name, vendored_names=(), vendor_pkg=None):
+        self.root_name = root_name
+        self.vendored_names = set(vendored_names)
+        self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor')
+
+    @property
+    def search_path(self):
+        """
+        Search first the vendor package then as a natural package.
+        """
+        yield self.vendor_pkg + '.'
+        yield ''
+
+    def find_module(self, fullname, path=None):
+        """
+        Return self when fullname starts with root_name and the
+        target module is one vendored through this importer.
+        """
+        root, base, target = fullname.partition(self.root_name + '.')
+        if root:
+            return
+        if not any(map(target.startswith, self.vendored_names)):
+            return
+        return self
+
+    def load_module(self, fullname):
+        """
+        Iterate over the search path to locate and load fullname.
+        """
+        root, base, target = fullname.partition(self.root_name + '.')
+        for prefix in self.search_path:
+            try:
+                extant = prefix + target
+                __import__(extant)
+                mod = sys.modules[extant]
+                sys.modules[fullname] = mod
+                # mysterious hack:
+                # Remove the reference to the extant package/module
+                # on later Python versions to cause relative imports
+                # in the vendor package to resolve the same modules
+                # as those going through this importer.
+                if sys.version_info > (3, 3):
+                    del sys.modules[extant]
+                return mod
+            except ImportError:
+                pass
+        else:
+            raise ImportError(
+                "The '{target}' package is required; "
+                "normally this is bundled with this package so if you get "
+                "this warning, consult the packager of your "
+                "distribution.".format(**locals())
+            )
+
+    def install(self):
+        """
+        Install this importer into sys.meta_path if not already present.
+        """
+        if self not in sys.meta_path:
+            sys.meta_path.append(self)
+
+
+names = 'packaging', 'pyparsing', 'six', 'appdirs'
+VendorImporter(__name__, names).install()
diff --git a/vendor/setuptools-39.0.1/build/lib/pkg_resources/py31compat.py b/vendor/setuptools-39.0.1/build/lib/pkg_resources/py31compat.py
new file mode 100644
index 00000000..331a51bb
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/pkg_resources/py31compat.py
@@ -0,0 +1,22 @@
+import os
+import errno
+import sys
+
+
+def _makedirs_31(path, exist_ok=False):
+    try:
+        os.makedirs(path)
+    except OSError as exc:
+        if not exist_ok or exc.errno != errno.EEXIST:
+            raise
+
+
+# rely on compatibility behavior until mode considerations
+#  and exists_ok considerations are disentangled.
+# See https://github.com/pypa/setuptools/pull/1083#issuecomment-315168663
+needs_makedirs = (
+    sys.version_info < (3, 2, 5) or
+    (3, 3) <= sys.version_info < (3, 3, 6) or
+    (3, 4) <= sys.version_info < (3, 4, 1)
+)
+makedirs = _makedirs_31 if needs_makedirs else os.makedirs
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/__init__.py b/vendor/setuptools-39.0.1/build/lib/setuptools/__init__.py
new file mode 100644
index 00000000..7da47fbe
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/__init__.py
@@ -0,0 +1,180 @@
+"""Extensions to the 'distutils' for large or complex distributions"""
+
+import os
+import functools
+import distutils.core
+import distutils.filelist
+from distutils.util import convert_path
+from fnmatch import fnmatchcase
+
+from setuptools.extern.six.moves import filter, map
+
+import setuptools.version
+from setuptools.extension import Extension
+from setuptools.dist import Distribution, Feature
+from setuptools.depends import Require
+from . import monkey
+
+__all__ = [
+    'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require',
+    'find_packages',
+]
+
+__version__ = setuptools.version.__version__
+
+bootstrap_install_from = None
+
+# If we run 2to3 on .py files, should we also convert docstrings?
+# Default: yes; assume that we can detect doctests reliably
+run_2to3_on_doctests = True
+# Standard package names for fixer packages
+lib2to3_fixer_packages = ['lib2to3.fixes']
+
+
+class PackageFinder(object):
+    """
+    Generate a list of all Python packages found within a directory
+    """
+
+    @classmethod
+    def find(cls, where='.', exclude=(), include=('*',)):
+        """Return a list all Python packages found within directory 'where'
+
+        'where' is the root directory which will be searched for packages.  It
+        should be supplied as a "cross-platform" (i.e. URL-style) path; it will
+        be converted to the appropriate local path syntax.
+
+        'exclude' is a sequence of package names to exclude; '*' can be used
+        as a wildcard in the names, such that 'foo.*' will exclude all
+        subpackages of 'foo' (but not 'foo' itself).
+
+        'include' is a sequence of package names to include.  If it's
+        specified, only the named packages will be included.  If it's not
+        specified, all found packages will be included.  'include' can contain
+        shell style wildcard patterns just like 'exclude'.
+        """
+
+        return list(cls._find_packages_iter(
+            convert_path(where),
+            cls._build_filter('ez_setup', '*__pycache__', *exclude),
+            cls._build_filter(*include)))
+
+    @classmethod
+    def _find_packages_iter(cls, where, exclude, include):
+        """
+        All the packages found in 'where' that pass the 'include' filter, but
+        not the 'exclude' filter.
+        """
+        for root, dirs, files in os.walk(where, followlinks=True):
+            # Copy dirs to iterate over it, then empty dirs.
+            all_dirs = dirs[:]
+            dirs[:] = []
+
+            for dir in all_dirs:
+                full_path = os.path.join(root, dir)
+                rel_path = os.path.relpath(full_path, where)
+                package = rel_path.replace(os.path.sep, '.')
+
+                # Skip directory trees that are not valid packages
+                if ('.' in dir or not cls._looks_like_package(full_path)):
+                    continue
+
+                # Should this package be included?
+                if include(package) and not exclude(package):
+                    yield package
+
+                # Keep searching subdirectories, as there may be more packages
+                # down there, even if the parent was excluded.
+                dirs.append(dir)
+
+    @staticmethod
+    def _looks_like_package(path):
+        """Does a directory look like a package?"""
+        return os.path.isfile(os.path.join(path, '__init__.py'))
+
+    @staticmethod
+    def _build_filter(*patterns):
+        """
+        Given a list of patterns, return a callable that will be true only if
+        the input matches at least one of the patterns.
+        """
+        return lambda name: any(fnmatchcase(name, pat=pat) for pat in patterns)
+
+
+class PEP420PackageFinder(PackageFinder):
+    @staticmethod
+    def _looks_like_package(path):
+        return True
+
+
+find_packages = PackageFinder.find
+
+
+def _install_setup_requires(attrs):
+    # Note: do not use `setuptools.Distribution` directly, as
+    # our PEP 517 backend patch `distutils.core.Distribution`.
+    dist = distutils.core.Distribution(dict(
+        (k, v) for k, v in attrs.items()
+        if k in ('dependency_links', 'setup_requires')
+    ))
+    # Honor setup.cfg's options.
+    dist.parse_config_files(ignore_option_errors=True)
+    if dist.setup_requires:
+        dist.fetch_build_eggs(dist.setup_requires)
+
+
+def setup(**attrs):
+    # Make sure we have any requirements needed to interpret 'attrs'.
+    _install_setup_requires(attrs)
+    return distutils.core.setup(**attrs)
+
+setup.__doc__ = distutils.core.setup.__doc__
+
+
+_Command = monkey.get_unpatched(distutils.core.Command)
+
+
+class Command(_Command):
+    __doc__ = _Command.__doc__
+
+    command_consumes_arguments = False
+
+    def __init__(self, dist, **kw):
+        """
+        Construct the command for dist, updating
+        vars(self) with any keyword parameters.
+        """
+        _Command.__init__(self, dist)
+        vars(self).update(kw)
+
+    def reinitialize_command(self, command, reinit_subcommands=0, **kw):
+        cmd = _Command.reinitialize_command(self, command, reinit_subcommands)
+        vars(cmd).update(kw)
+        return cmd
+
+
+def _find_all_simple(path):
+    """
+    Find all files under 'path'
+    """
+    results = (
+        os.path.join(base, file)
+        for base, dirs, files in os.walk(path, followlinks=True)
+        for file in files
+    )
+    return filter(os.path.isfile, results)
+
+
+def findall(dir=os.curdir):
+    """
+    Find all files under 'dir' and return the list of full filenames.
+    Unless dir is '.', return full filenames with dir prepended.
+    """
+    files = _find_all_simple(dir)
+    if dir == os.curdir:
+        make_rel = functools.partial(os.path.relpath, start=dir)
+        files = map(make_rel, files)
+    return list(files)
+
+
+monkey.patch_all()
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/__init__.py b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/__about__.py b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/__about__.py
new file mode 100644
index 00000000..95d330ef
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/__about__.py
@@ -0,0 +1,21 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+__all__ = [
+    "__title__", "__summary__", "__uri__", "__version__", "__author__",
+    "__email__", "__license__", "__copyright__",
+]
+
+__title__ = "packaging"
+__summary__ = "Core utilities for Python packages"
+__uri__ = "https://github.com/pypa/packaging"
+
+__version__ = "16.8"
+
+__author__ = "Donald Stufft and individual contributors"
+__email__ = "donald@stufft.io"
+
+__license__ = "BSD or Apache License, Version 2.0"
+__copyright__ = "Copyright 2014-2016 %s" % __author__
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/__init__.py b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/__init__.py
new file mode 100644
index 00000000..5ee62202
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/__init__.py
@@ -0,0 +1,14 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+from .__about__ import (
+    __author__, __copyright__, __email__, __license__, __summary__, __title__,
+    __uri__, __version__
+)
+
+__all__ = [
+    "__title__", "__summary__", "__uri__", "__version__", "__author__",
+    "__email__", "__license__", "__copyright__",
+]
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/_compat.py b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/_compat.py
new file mode 100644
index 00000000..210bb80b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/_compat.py
@@ -0,0 +1,30 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import sys
+
+
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
+
+# flake8: noqa
+
+if PY3:
+    string_types = str,
+else:
+    string_types = basestring,
+
+
+def with_metaclass(meta, *bases):
+    """
+    Create a base class with a metaclass.
+    """
+    # This requires a bit of explanation: the basic idea is to make a dummy
+    # metaclass for one level of class instantiation that replaces itself with
+    # the actual metaclass.
+    class metaclass(meta):
+        def __new__(cls, name, this_bases, d):
+            return meta(name, bases, d)
+    return type.__new__(metaclass, 'temporary_class', (), {})
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/_structures.py b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/_structures.py
new file mode 100644
index 00000000..ccc27861
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/_structures.py
@@ -0,0 +1,68 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+
+class Infinity(object):
+
+    def __repr__(self):
+        return "Infinity"
+
+    def __hash__(self):
+        return hash(repr(self))
+
+    def __lt__(self, other):
+        return False
+
+    def __le__(self, other):
+        return False
+
+    def __eq__(self, other):
+        return isinstance(other, self.__class__)
+
+    def __ne__(self, other):
+        return not isinstance(other, self.__class__)
+
+    def __gt__(self, other):
+        return True
+
+    def __ge__(self, other):
+        return True
+
+    def __neg__(self):
+        return NegativeInfinity
+
+Infinity = Infinity()
+
+
+class NegativeInfinity(object):
+
+    def __repr__(self):
+        return "-Infinity"
+
+    def __hash__(self):
+        return hash(repr(self))
+
+    def __lt__(self, other):
+        return True
+
+    def __le__(self, other):
+        return True
+
+    def __eq__(self, other):
+        return isinstance(other, self.__class__)
+
+    def __ne__(self, other):
+        return not isinstance(other, self.__class__)
+
+    def __gt__(self, other):
+        return False
+
+    def __ge__(self, other):
+        return False
+
+    def __neg__(self):
+        return Infinity
+
+NegativeInfinity = NegativeInfinity()
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/markers.py b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/markers.py
new file mode 100644
index 00000000..031332a3
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/markers.py
@@ -0,0 +1,301 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import operator
+import os
+import platform
+import sys
+
+from setuptools.extern.pyparsing import ParseException, ParseResults, stringStart, stringEnd
+from setuptools.extern.pyparsing import ZeroOrMore, Group, Forward, QuotedString
+from setuptools.extern.pyparsing import Literal as L  # noqa
+
+from ._compat import string_types
+from .specifiers import Specifier, InvalidSpecifier
+
+
+__all__ = [
+    "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName",
+    "Marker", "default_environment",
+]
+
+
+class InvalidMarker(ValueError):
+    """
+    An invalid marker was found, users should refer to PEP 508.
+    """
+
+
+class UndefinedComparison(ValueError):
+    """
+    An invalid operation was attempted on a value that doesn't support it.
+    """
+
+
+class UndefinedEnvironmentName(ValueError):
+    """
+    A name was attempted to be used that does not exist inside of the
+    environment.
+    """
+
+
+class Node(object):
+
+    def __init__(self, value):
+        self.value = value
+
+    def __str__(self):
+        return str(self.value)
+
+    def __repr__(self):
+        return "<{0}({1!r})>".format(self.__class__.__name__, str(self))
+
+    def serialize(self):
+        raise NotImplementedError
+
+
+class Variable(Node):
+
+    def serialize(self):
+        return str(self)
+
+
+class Value(Node):
+
+    def serialize(self):
+        return '"{0}"'.format(self)
+
+
+class Op(Node):
+
+    def serialize(self):
+        return str(self)
+
+
+VARIABLE = (
+    L("implementation_version") |
+    L("platform_python_implementation") |
+    L("implementation_name") |
+    L("python_full_version") |
+    L("platform_release") |
+    L("platform_version") |
+    L("platform_machine") |
+    L("platform_system") |
+    L("python_version") |
+    L("sys_platform") |
+    L("os_name") |
+    L("os.name") |  # PEP-345
+    L("sys.platform") |  # PEP-345
+    L("platform.version") |  # PEP-345
+    L("platform.machine") |  # PEP-345
+    L("platform.python_implementation") |  # PEP-345
+    L("python_implementation") |  # undocumented setuptools legacy
+    L("extra")
+)
+ALIASES = {
+    'os.name': 'os_name',
+    'sys.platform': 'sys_platform',
+    'platform.version': 'platform_version',
+    'platform.machine': 'platform_machine',
+    'platform.python_implementation': 'platform_python_implementation',
+    'python_implementation': 'platform_python_implementation'
+}
+VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0])))
+
+VERSION_CMP = (
+    L("===") |
+    L("==") |
+    L(">=") |
+    L("<=") |
+    L("!=") |
+    L("~=") |
+    L(">") |
+    L("<")
+)
+
+MARKER_OP = VERSION_CMP | L("not in") | L("in")
+MARKER_OP.setParseAction(lambda s, l, t: Op(t[0]))
+
+MARKER_VALUE = QuotedString("'") | QuotedString('"')
+MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0]))
+
+BOOLOP = L("and") | L("or")
+
+MARKER_VAR = VARIABLE | MARKER_VALUE
+
+MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR)
+MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0]))
+
+LPAREN = L("(").suppress()
+RPAREN = L(")").suppress()
+
+MARKER_EXPR = Forward()
+MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN)
+MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR)
+
+MARKER = stringStart + MARKER_EXPR + stringEnd
+
+
+def _coerce_parse_result(results):
+    if isinstance(results, ParseResults):
+        return [_coerce_parse_result(i) for i in results]
+    else:
+        return results
+
+
+def _format_marker(marker, first=True):
+    assert isinstance(marker, (list, tuple, string_types))
+
+    # Sometimes we have a structure like [[...]] which is a single item list
+    # where the single item is itself it's own list. In that case we want skip
+    # the rest of this function so that we don't get extraneous () on the
+    # outside.
+    if (isinstance(marker, list) and len(marker) == 1 and
+            isinstance(marker[0], (list, tuple))):
+        return _format_marker(marker[0])
+
+    if isinstance(marker, list):
+        inner = (_format_marker(m, first=False) for m in marker)
+        if first:
+            return " ".join(inner)
+        else:
+            return "(" + " ".join(inner) + ")"
+    elif isinstance(marker, tuple):
+        return " ".join([m.serialize() for m in marker])
+    else:
+        return marker
+
+
+_operators = {
+    "in": lambda lhs, rhs: lhs in rhs,
+    "not in": lambda lhs, rhs: lhs not in rhs,
+    "<": operator.lt,
+    "<=": operator.le,
+    "==": operator.eq,
+    "!=": operator.ne,
+    ">=": operator.ge,
+    ">": operator.gt,
+}
+
+
+def _eval_op(lhs, op, rhs):
+    try:
+        spec = Specifier("".join([op.serialize(), rhs]))
+    except InvalidSpecifier:
+        pass
+    else:
+        return spec.contains(lhs)
+
+    oper = _operators.get(op.serialize())
+    if oper is None:
+        raise UndefinedComparison(
+            "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs)
+        )
+
+    return oper(lhs, rhs)
+
+
+_undefined = object()
+
+
+def _get_env(environment, name):
+    value = environment.get(name, _undefined)
+
+    if value is _undefined:
+        raise UndefinedEnvironmentName(
+            "{0!r} does not exist in evaluation environment.".format(name)
+        )
+
+    return value
+
+
+def _evaluate_markers(markers, environment):
+    groups = [[]]
+
+    for marker in markers:
+        assert isinstance(marker, (list, tuple, string_types))
+
+        if isinstance(marker, list):
+            groups[-1].append(_evaluate_markers(marker, environment))
+        elif isinstance(marker, tuple):
+            lhs, op, rhs = marker
+
+            if isinstance(lhs, Variable):
+                lhs_value = _get_env(environment, lhs.value)
+                rhs_value = rhs.value
+            else:
+                lhs_value = lhs.value
+                rhs_value = _get_env(environment, rhs.value)
+
+            groups[-1].append(_eval_op(lhs_value, op, rhs_value))
+        else:
+            assert marker in ["and", "or"]
+            if marker == "or":
+                groups.append([])
+
+    return any(all(item) for item in groups)
+
+
+def format_full_version(info):
+    version = '{0.major}.{0.minor}.{0.micro}'.format(info)
+    kind = info.releaselevel
+    if kind != 'final':
+        version += kind[0] + str(info.serial)
+    return version
+
+
+def default_environment():
+    if hasattr(sys, 'implementation'):
+        iver = format_full_version(sys.implementation.version)
+        implementation_name = sys.implementation.name
+    else:
+        iver = '0'
+        implementation_name = ''
+
+    return {
+        "implementation_name": implementation_name,
+        "implementation_version": iver,
+        "os_name": os.name,
+        "platform_machine": platform.machine(),
+        "platform_release": platform.release(),
+        "platform_system": platform.system(),
+        "platform_version": platform.version(),
+        "python_full_version": platform.python_version(),
+        "platform_python_implementation": platform.python_implementation(),
+        "python_version": platform.python_version()[:3],
+        "sys_platform": sys.platform,
+    }
+
+
+class Marker(object):
+
+    def __init__(self, marker):
+        try:
+            self._markers = _coerce_parse_result(MARKER.parseString(marker))
+        except ParseException as e:
+            err_str = "Invalid marker: {0!r}, parse error at {1!r}".format(
+                marker, marker[e.loc:e.loc + 8])
+            raise InvalidMarker(err_str)
+
+    def __str__(self):
+        return _format_marker(self._markers)
+
+    def __repr__(self):
+        return "<Marker({0!r})>".format(str(self))
+
+    def evaluate(self, environment=None):
+        """Evaluate a marker.
+
+        Return the boolean from evaluating the given marker against the
+        environment. environment is an optional argument to override all or
+        part of the determined environment.
+
+        The environment is determined from the current Python process.
+        """
+        current_environment = default_environment()
+        if environment is not None:
+            current_environment.update(environment)
+
+        return _evaluate_markers(self._markers, current_environment)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/requirements.py b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/requirements.py
new file mode 100644
index 00000000..5b493416
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/requirements.py
@@ -0,0 +1,127 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import string
+import re
+
+from setuptools.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException
+from setuptools.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine
+from setuptools.extern.pyparsing import Literal as L  # noqa
+from setuptools.extern.six.moves.urllib import parse as urlparse
+
+from .markers import MARKER_EXPR, Marker
+from .specifiers import LegacySpecifier, Specifier, SpecifierSet
+
+
+class InvalidRequirement(ValueError):
+    """
+    An invalid requirement was found, users should refer to PEP 508.
+    """
+
+
+ALPHANUM = Word(string.ascii_letters + string.digits)
+
+LBRACKET = L("[").suppress()
+RBRACKET = L("]").suppress()
+LPAREN = L("(").suppress()
+RPAREN = L(")").suppress()
+COMMA = L(",").suppress()
+SEMICOLON = L(";").suppress()
+AT = L("@").suppress()
+
+PUNCTUATION = Word("-_.")
+IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM)
+IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END))
+
+NAME = IDENTIFIER("name")
+EXTRA = IDENTIFIER
+
+URI = Regex(r'[^ ]+')("url")
+URL = (AT + URI)
+
+EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA)
+EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras")
+
+VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE)
+VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE)
+
+VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY
+VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE),
+                       joinString=",", adjacent=False)("_raw_spec")
+_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY))
+_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '')
+
+VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier")
+VERSION_SPEC.setParseAction(lambda s, l, t: t[1])
+
+MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker")
+MARKER_EXPR.setParseAction(
+    lambda s, l, t: Marker(s[t._original_start:t._original_end])
+)
+MARKER_SEPERATOR = SEMICOLON
+MARKER = MARKER_SEPERATOR + MARKER_EXPR
+
+VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER)
+URL_AND_MARKER = URL + Optional(MARKER)
+
+NAMED_REQUIREMENT = \
+    NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER)
+
+REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd
+
+
+class Requirement(object):
+    """Parse a requirement.
+
+    Parse a given requirement string into its parts, such as name, specifier,
+    URL, and extras. Raises InvalidRequirement on a badly-formed requirement
+    string.
+    """
+
+    # TODO: Can we test whether something is contained within a requirement?
+    #       If so how do we do that? Do we need to test against the _name_ of
+    #       the thing as well as the version? What about the markers?
+    # TODO: Can we normalize the name and extra name?
+
+    def __init__(self, requirement_string):
+        try:
+            req = REQUIREMENT.parseString(requirement_string)
+        except ParseException as e:
+            raise InvalidRequirement(
+                "Invalid requirement, parse error at \"{0!r}\"".format(
+                    requirement_string[e.loc:e.loc + 8]))
+
+        self.name = req.name
+        if req.url:
+            parsed_url = urlparse.urlparse(req.url)
+            if not (parsed_url.scheme and parsed_url.netloc) or (
+                    not parsed_url.scheme and not parsed_url.netloc):
+                raise InvalidRequirement("Invalid URL given")
+            self.url = req.url
+        else:
+            self.url = None
+        self.extras = set(req.extras.asList() if req.extras else [])
+        self.specifier = SpecifierSet(req.specifier)
+        self.marker = req.marker if req.marker else None
+
+    def __str__(self):
+        parts = [self.name]
+
+        if self.extras:
+            parts.append("[{0}]".format(",".join(sorted(self.extras))))
+
+        if self.specifier:
+            parts.append(str(self.specifier))
+
+        if self.url:
+            parts.append("@ {0}".format(self.url))
+
+        if self.marker:
+            parts.append("; {0}".format(self.marker))
+
+        return "".join(parts)
+
+    def __repr__(self):
+        return "<Requirement({0!r})>".format(str(self))
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/specifiers.py b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/specifiers.py
new file mode 100644
index 00000000..7f5a76cf
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/specifiers.py
@@ -0,0 +1,774 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import abc
+import functools
+import itertools
+import re
+
+from ._compat import string_types, with_metaclass
+from .version import Version, LegacyVersion, parse
+
+
+class InvalidSpecifier(ValueError):
+    """
+    An invalid specifier was found, users should refer to PEP 440.
+    """
+
+
+class BaseSpecifier(with_metaclass(abc.ABCMeta, object)):
+
+    @abc.abstractmethod
+    def __str__(self):
+        """
+        Returns the str representation of this Specifier like object. This
+        should be representative of the Specifier itself.
+        """
+
+    @abc.abstractmethod
+    def __hash__(self):
+        """
+        Returns a hash value for this Specifier like object.
+        """
+
+    @abc.abstractmethod
+    def __eq__(self, other):
+        """
+        Returns a boolean representing whether or not the two Specifier like
+        objects are equal.
+        """
+
+    @abc.abstractmethod
+    def __ne__(self, other):
+        """
+        Returns a boolean representing whether or not the two Specifier like
+        objects are not equal.
+        """
+
+    @abc.abstractproperty
+    def prereleases(self):
+        """
+        Returns whether or not pre-releases as a whole are allowed by this
+        specifier.
+        """
+
+    @prereleases.setter
+    def prereleases(self, value):
+        """
+        Sets whether or not pre-releases as a whole are allowed by this
+        specifier.
+        """
+
+    @abc.abstractmethod
+    def contains(self, item, prereleases=None):
+        """
+        Determines if the given item is contained within this specifier.
+        """
+
+    @abc.abstractmethod
+    def filter(self, iterable, prereleases=None):
+        """
+        Takes an iterable of items and filters them so that only items which
+        are contained within this specifier are allowed in it.
+        """
+
+
+class _IndividualSpecifier(BaseSpecifier):
+
+    _operators = {}
+
+    def __init__(self, spec="", prereleases=None):
+        match = self._regex.search(spec)
+        if not match:
+            raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec))
+
+        self._spec = (
+            match.group("operator").strip(),
+            match.group("version").strip(),
+        )
+
+        # Store whether or not this Specifier should accept prereleases
+        self._prereleases = prereleases
+
+    def __repr__(self):
+        pre = (
+            ", prereleases={0!r}".format(self.prereleases)
+            if self._prereleases is not None
+            else ""
+        )
+
+        return "<{0}({1!r}{2})>".format(
+            self.__class__.__name__,
+            str(self),
+            pre,
+        )
+
+    def __str__(self):
+        return "{0}{1}".format(*self._spec)
+
+    def __hash__(self):
+        return hash(self._spec)
+
+    def __eq__(self, other):
+        if isinstance(other, string_types):
+            try:
+                other = self.__class__(other)
+            except InvalidSpecifier:
+                return NotImplemented
+        elif not isinstance(other, self.__class__):
+            return NotImplemented
+
+        return self._spec == other._spec
+
+    def __ne__(self, other):
+        if isinstance(other, string_types):
+            try:
+                other = self.__class__(other)
+            except InvalidSpecifier:
+                return NotImplemented
+        elif not isinstance(other, self.__class__):
+            return NotImplemented
+
+        return self._spec != other._spec
+
+    def _get_operator(self, op):
+        return getattr(self, "_compare_{0}".format(self._operators[op]))
+
+    def _coerce_version(self, version):
+        if not isinstance(version, (LegacyVersion, Version)):
+            version = parse(version)
+        return version
+
+    @property
+    def operator(self):
+        return self._spec[0]
+
+    @property
+    def version(self):
+        return self._spec[1]
+
+    @property
+    def prereleases(self):
+        return self._prereleases
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+    def __contains__(self, item):
+        return self.contains(item)
+
+    def contains(self, item, prereleases=None):
+        # Determine if prereleases are to be allowed or not.
+        if prereleases is None:
+            prereleases = self.prereleases
+
+        # Normalize item to a Version or LegacyVersion, this allows us to have
+        # a shortcut for ``"2.0" in Specifier(">=2")
+        item = self._coerce_version(item)
+
+        # Determine if we should be supporting prereleases in this specifier
+        # or not, if we do not support prereleases than we can short circuit
+        # logic if this version is a prereleases.
+        if item.is_prerelease and not prereleases:
+            return False
+
+        # Actually do the comparison to determine if this item is contained
+        # within this Specifier or not.
+        return self._get_operator(self.operator)(item, self.version)
+
+    def filter(self, iterable, prereleases=None):
+        yielded = False
+        found_prereleases = []
+
+        kw = {"prereleases": prereleases if prereleases is not None else True}
+
+        # Attempt to iterate over all the values in the iterable and if any of
+        # them match, yield them.
+        for version in iterable:
+            parsed_version = self._coerce_version(version)
+
+            if self.contains(parsed_version, **kw):
+                # If our version is a prerelease, and we were not set to allow
+                # prereleases, then we'll store it for later incase nothing
+                # else matches this specifier.
+                if (parsed_version.is_prerelease and not
+                        (prereleases or self.prereleases)):
+                    found_prereleases.append(version)
+                # Either this is not a prerelease, or we should have been
+                # accepting prereleases from the begining.
+                else:
+                    yielded = True
+                    yield version
+
+        # Now that we've iterated over everything, determine if we've yielded
+        # any values, and if we have not and we have any prereleases stored up
+        # then we will go ahead and yield the prereleases.
+        if not yielded and found_prereleases:
+            for version in found_prereleases:
+                yield version
+
+
+class LegacySpecifier(_IndividualSpecifier):
+
+    _regex_str = (
+        r"""
+        (?P<operator>(==|!=|<=|>=|<|>))
+        \s*
+        (?P<version>
+            [^,;\s)]* # Since this is a "legacy" specifier, and the version
+                      # string can be just about anything, we match everything
+                      # except for whitespace, a semi-colon for marker support,
+                      # a closing paren since versions can be enclosed in
+                      # them, and a comma since it's a version separator.
+        )
+        """
+    )
+
+    _regex = re.compile(
+        r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
+
+    _operators = {
+        "==": "equal",
+        "!=": "not_equal",
+        "<=": "less_than_equal",
+        ">=": "greater_than_equal",
+        "<": "less_than",
+        ">": "greater_than",
+    }
+
+    def _coerce_version(self, version):
+        if not isinstance(version, LegacyVersion):
+            version = LegacyVersion(str(version))
+        return version
+
+    def _compare_equal(self, prospective, spec):
+        return prospective == self._coerce_version(spec)
+
+    def _compare_not_equal(self, prospective, spec):
+        return prospective != self._coerce_version(spec)
+
+    def _compare_less_than_equal(self, prospective, spec):
+        return prospective <= self._coerce_version(spec)
+
+    def _compare_greater_than_equal(self, prospective, spec):
+        return prospective >= self._coerce_version(spec)
+
+    def _compare_less_than(self, prospective, spec):
+        return prospective < self._coerce_version(spec)
+
+    def _compare_greater_than(self, prospective, spec):
+        return prospective > self._coerce_version(spec)
+
+
+def _require_version_compare(fn):
+    @functools.wraps(fn)
+    def wrapped(self, prospective, spec):
+        if not isinstance(prospective, Version):
+            return False
+        return fn(self, prospective, spec)
+    return wrapped
+
+
+class Specifier(_IndividualSpecifier):
+
+    _regex_str = (
+        r"""
+        (?P<operator>(~=|==|!=|<=|>=|<|>|===))
+        (?P<version>
+            (?:
+                # The identity operators allow for an escape hatch that will
+                # do an exact string match of the version you wish to install.
+                # This will not be parsed by PEP 440 and we cannot determine
+                # any semantic meaning from it. This operator is discouraged
+                # but included entirely as an escape hatch.
+                (?<====)  # Only match for the identity operator
+                \s*
+                [^\s]*    # We just match everything, except for whitespace
+                          # since we are only testing for strict identity.
+            )
+            |
+            (?:
+                # The (non)equality operators allow for wild card and local
+                # versions to be specified so we have to define these two
+                # operators separately to enable that.
+                (?<===|!=)            # Only match for equals and not equals
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)*   # release
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+
+                # You cannot use a wild card and a dev or local version
+                # together so group them with a | and make them optional.
+                (?:
+                    (?:[-_\.]?dev[-_\.]?[0-9]*)?         # dev release
+                    (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local
+                    |
+                    \.\*  # Wild card syntax of .*
+                )?
+            )
+            |
+            (?:
+                # The compatible operator requires at least two digits in the
+                # release segment.
+                (?<=~=)               # Only match for the compatible operator
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)+   # release  (We have a + instead of a *)
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
+            )
+            |
+            (?:
+                # All other operators only allow a sub set of what the
+                # (non)equality operators do. Specifically they do not allow
+                # local versions to be specified nor do they allow the prefix
+                # matching wild cards.
+                (?<!==|!=|~=)         # We have special cases for these
+                                      # operators so we want to make sure they
+                                      # don't match here.
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)*   # release
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
+            )
+        )
+        """
+    )
+
+    _regex = re.compile(
+        r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
+
+    _operators = {
+        "~=": "compatible",
+        "==": "equal",
+        "!=": "not_equal",
+        "<=": "less_than_equal",
+        ">=": "greater_than_equal",
+        "<": "less_than",
+        ">": "greater_than",
+        "===": "arbitrary",
+    }
+
+    @_require_version_compare
+    def _compare_compatible(self, prospective, spec):
+        # Compatible releases have an equivalent combination of >= and ==. That
+        # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to
+        # implement this in terms of the other specifiers instead of
+        # implementing it ourselves. The only thing we need to do is construct
+        # the other specifiers.
+
+        # We want everything but the last item in the version, but we want to
+        # ignore post and dev releases and we want to treat the pre-release as
+        # it's own separate segment.
+        prefix = ".".join(
+            list(
+                itertools.takewhile(
+                    lambda x: (not x.startswith("post") and not
+                               x.startswith("dev")),
+                    _version_split(spec),
+                )
+            )[:-1]
+        )
+
+        # Add the prefix notation to the end of our string
+        prefix += ".*"
+
+        return (self._get_operator(">=")(prospective, spec) and
+                self._get_operator("==")(prospective, prefix))
+
+    @_require_version_compare
+    def _compare_equal(self, prospective, spec):
+        # We need special logic to handle prefix matching
+        if spec.endswith(".*"):
+            # In the case of prefix matching we want to ignore local segment.
+            prospective = Version(prospective.public)
+            # Split the spec out by dots, and pretend that there is an implicit
+            # dot in between a release segment and a pre-release segment.
+            spec = _version_split(spec[:-2])  # Remove the trailing .*
+
+            # Split the prospective version out by dots, and pretend that there
+            # is an implicit dot in between a release segment and a pre-release
+            # segment.
+            prospective = _version_split(str(prospective))
+
+            # Shorten the prospective version to be the same length as the spec
+            # so that we can determine if the specifier is a prefix of the
+            # prospective version or not.
+            prospective = prospective[:len(spec)]
+
+            # Pad out our two sides with zeros so that they both equal the same
+            # length.
+            spec, prospective = _pad_version(spec, prospective)
+        else:
+            # Convert our spec string into a Version
+            spec = Version(spec)
+
+            # If the specifier does not have a local segment, then we want to
+            # act as if the prospective version also does not have a local
+            # segment.
+            if not spec.local:
+                prospective = Version(prospective.public)
+
+        return prospective == spec
+
+    @_require_version_compare
+    def _compare_not_equal(self, prospective, spec):
+        return not self._compare_equal(prospective, spec)
+
+    @_require_version_compare
+    def _compare_less_than_equal(self, prospective, spec):
+        return prospective <= Version(spec)
+
+    @_require_version_compare
+    def _compare_greater_than_equal(self, prospective, spec):
+        return prospective >= Version(spec)
+
+    @_require_version_compare
+    def _compare_less_than(self, prospective, spec):
+        # Convert our spec to a Version instance, since we'll want to work with
+        # it as a version.
+        spec = Version(spec)
+
+        # Check to see if the prospective version is less than the spec
+        # version. If it's not we can short circuit and just return False now
+        # instead of doing extra unneeded work.
+        if not prospective < spec:
+            return False
+
+        # This special case is here so that, unless the specifier itself
+        # includes is a pre-release version, that we do not accept pre-release
+        # versions for the version mentioned in the specifier (e.g. <3.1 should
+        # not match 3.1.dev0, but should match 3.0.dev0).
+        if not spec.is_prerelease and prospective.is_prerelease:
+            if Version(prospective.base_version) == Version(spec.base_version):
+                return False
+
+        # If we've gotten to here, it means that prospective version is both
+        # less than the spec version *and* it's not a pre-release of the same
+        # version in the spec.
+        return True
+
+    @_require_version_compare
+    def _compare_greater_than(self, prospective, spec):
+        # Convert our spec to a Version instance, since we'll want to work with
+        # it as a version.
+        spec = Version(spec)
+
+        # Check to see if the prospective version is greater than the spec
+        # version. If it's not we can short circuit and just return False now
+        # instead of doing extra unneeded work.
+        if not prospective > spec:
+            return False
+
+        # This special case is here so that, unless the specifier itself
+        # includes is a post-release version, that we do not accept
+        # post-release versions for the version mentioned in the specifier
+        # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0).
+        if not spec.is_postrelease and prospective.is_postrelease:
+            if Version(prospective.base_version) == Version(spec.base_version):
+                return False
+
+        # Ensure that we do not allow a local version of the version mentioned
+        # in the specifier, which is techincally greater than, to match.
+        if prospective.local is not None:
+            if Version(prospective.base_version) == Version(spec.base_version):
+                return False
+
+        # If we've gotten to here, it means that prospective version is both
+        # greater than the spec version *and* it's not a pre-release of the
+        # same version in the spec.
+        return True
+
+    def _compare_arbitrary(self, prospective, spec):
+        return str(prospective).lower() == str(spec).lower()
+
+    @property
+    def prereleases(self):
+        # If there is an explicit prereleases set for this, then we'll just
+        # blindly use that.
+        if self._prereleases is not None:
+            return self._prereleases
+
+        # Look at all of our specifiers and determine if they are inclusive
+        # operators, and if they are if they are including an explicit
+        # prerelease.
+        operator, version = self._spec
+        if operator in ["==", ">=", "<=", "~=", "==="]:
+            # The == specifier can include a trailing .*, if it does we
+            # want to remove before parsing.
+            if operator == "==" and version.endswith(".*"):
+                version = version[:-2]
+
+            # Parse the version, and if it is a pre-release than this
+            # specifier allows pre-releases.
+            if parse(version).is_prerelease:
+                return True
+
+        return False
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+
+_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$")
+
+
+def _version_split(version):
+    result = []
+    for item in version.split("."):
+        match = _prefix_regex.search(item)
+        if match:
+            result.extend(match.groups())
+        else:
+            result.append(item)
+    return result
+
+
+def _pad_version(left, right):
+    left_split, right_split = [], []
+
+    # Get the release segment of our versions
+    left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left)))
+    right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right)))
+
+    # Get the rest of our versions
+    left_split.append(left[len(left_split[0]):])
+    right_split.append(right[len(right_split[0]):])
+
+    # Insert our padding
+    left_split.insert(
+        1,
+        ["0"] * max(0, len(right_split[0]) - len(left_split[0])),
+    )
+    right_split.insert(
+        1,
+        ["0"] * max(0, len(left_split[0]) - len(right_split[0])),
+    )
+
+    return (
+        list(itertools.chain(*left_split)),
+        list(itertools.chain(*right_split)),
+    )
+
+
+class SpecifierSet(BaseSpecifier):
+
+    def __init__(self, specifiers="", prereleases=None):
+        # Split on , to break each indidivual specifier into it's own item, and
+        # strip each item to remove leading/trailing whitespace.
+        specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
+
+        # Parsed each individual specifier, attempting first to make it a
+        # Specifier and falling back to a LegacySpecifier.
+        parsed = set()
+        for specifier in specifiers:
+            try:
+                parsed.add(Specifier(specifier))
+            except InvalidSpecifier:
+                parsed.add(LegacySpecifier(specifier))
+
+        # Turn our parsed specifiers into a frozen set and save them for later.
+        self._specs = frozenset(parsed)
+
+        # Store our prereleases value so we can use it later to determine if
+        # we accept prereleases or not.
+        self._prereleases = prereleases
+
+    def __repr__(self):
+        pre = (
+            ", prereleases={0!r}".format(self.prereleases)
+            if self._prereleases is not None
+            else ""
+        )
+
+        return "<SpecifierSet({0!r}{1})>".format(str(self), pre)
+
+    def __str__(self):
+        return ",".join(sorted(str(s) for s in self._specs))
+
+    def __hash__(self):
+        return hash(self._specs)
+
+    def __and__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        specifier = SpecifierSet()
+        specifier._specs = frozenset(self._specs | other._specs)
+
+        if self._prereleases is None and other._prereleases is not None:
+            specifier._prereleases = other._prereleases
+        elif self._prereleases is not None and other._prereleases is None:
+            specifier._prereleases = self._prereleases
+        elif self._prereleases == other._prereleases:
+            specifier._prereleases = self._prereleases
+        else:
+            raise ValueError(
+                "Cannot combine SpecifierSets with True and False prerelease "
+                "overrides."
+            )
+
+        return specifier
+
+    def __eq__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif isinstance(other, _IndividualSpecifier):
+            other = SpecifierSet(str(other))
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        return self._specs == other._specs
+
+    def __ne__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif isinstance(other, _IndividualSpecifier):
+            other = SpecifierSet(str(other))
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        return self._specs != other._specs
+
+    def __len__(self):
+        return len(self._specs)
+
+    def __iter__(self):
+        return iter(self._specs)
+
+    @property
+    def prereleases(self):
+        # If we have been given an explicit prerelease modifier, then we'll
+        # pass that through here.
+        if self._prereleases is not None:
+            return self._prereleases
+
+        # If we don't have any specifiers, and we don't have a forced value,
+        # then we'll just return None since we don't know if this should have
+        # pre-releases or not.
+        if not self._specs:
+            return None
+
+        # Otherwise we'll see if any of the given specifiers accept
+        # prereleases, if any of them do we'll return True, otherwise False.
+        return any(s.prereleases for s in self._specs)
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+    def __contains__(self, item):
+        return self.contains(item)
+
+    def contains(self, item, prereleases=None):
+        # Ensure that our item is a Version or LegacyVersion instance.
+        if not isinstance(item, (LegacyVersion, Version)):
+            item = parse(item)
+
+        # Determine if we're forcing a prerelease or not, if we're not forcing
+        # one for this particular filter call, then we'll use whatever the
+        # SpecifierSet thinks for whether or not we should support prereleases.
+        if prereleases is None:
+            prereleases = self.prereleases
+
+        # We can determine if we're going to allow pre-releases by looking to
+        # see if any of the underlying items supports them. If none of them do
+        # and this item is a pre-release then we do not allow it and we can
+        # short circuit that here.
+        # Note: This means that 1.0.dev1 would not be contained in something
+        #       like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0
+        if not prereleases and item.is_prerelease:
+            return False
+
+        # We simply dispatch to the underlying specs here to make sure that the
+        # given version is contained within all of them.
+        # Note: This use of all() here means that an empty set of specifiers
+        #       will always return True, this is an explicit design decision.
+        return all(
+            s.contains(item, prereleases=prereleases)
+            for s in self._specs
+        )
+
+    def filter(self, iterable, prereleases=None):
+        # Determine if we're forcing a prerelease or not, if we're not forcing
+        # one for this particular filter call, then we'll use whatever the
+        # SpecifierSet thinks for whether or not we should support prereleases.
+        if prereleases is None:
+            prereleases = self.prereleases
+
+        # If we have any specifiers, then we want to wrap our iterable in the
+        # filter method for each one, this will act as a logical AND amongst
+        # each specifier.
+        if self._specs:
+            for spec in self._specs:
+                iterable = spec.filter(iterable, prereleases=bool(prereleases))
+            return iterable
+        # If we do not have any specifiers, then we need to have a rough filter
+        # which will filter out any pre-releases, unless there are no final
+        # releases, and which will filter out LegacyVersion in general.
+        else:
+            filtered = []
+            found_prereleases = []
+
+            for item in iterable:
+                # Ensure that we some kind of Version class for this item.
+                if not isinstance(item, (LegacyVersion, Version)):
+                    parsed_version = parse(item)
+                else:
+                    parsed_version = item
+
+                # Filter out any item which is parsed as a LegacyVersion
+                if isinstance(parsed_version, LegacyVersion):
+                    continue
+
+                # Store any item which is a pre-release for later unless we've
+                # already found a final version or we are accepting prereleases
+                if parsed_version.is_prerelease and not prereleases:
+                    if not filtered:
+                        found_prereleases.append(item)
+                else:
+                    filtered.append(item)
+
+            # If we've found no items except for pre-releases, then we'll go
+            # ahead and use the pre-releases
+            if not filtered and found_prereleases and prereleases is None:
+                return found_prereleases
+
+            return filtered
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/utils.py b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/utils.py
new file mode 100644
index 00000000..942387ce
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/utils.py
@@ -0,0 +1,14 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import re
+
+
+_canonicalize_regex = re.compile(r"[-_.]+")
+
+
+def canonicalize_name(name):
+    # This is taken from PEP 503.
+    return _canonicalize_regex.sub("-", name).lower()
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/version.py b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/version.py
new file mode 100644
index 00000000..83b5ee8c
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/packaging/version.py
@@ -0,0 +1,393 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import collections
+import itertools
+import re
+
+from ._structures import Infinity
+
+
+__all__ = [
+    "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"
+]
+
+
+_Version = collections.namedtuple(
+    "_Version",
+    ["epoch", "release", "dev", "pre", "post", "local"],
+)
+
+
+def parse(version):
+    """
+    Parse the given version string and return either a :class:`Version` object
+    or a :class:`LegacyVersion` object depending on if the given version is
+    a valid PEP 440 version or a legacy version.
+    """
+    try:
+        return Version(version)
+    except InvalidVersion:
+        return LegacyVersion(version)
+
+
+class InvalidVersion(ValueError):
+    """
+    An invalid version was found, users should refer to PEP 440.
+    """
+
+
+class _BaseVersion(object):
+
+    def __hash__(self):
+        return hash(self._key)
+
+    def __lt__(self, other):
+        return self._compare(other, lambda s, o: s < o)
+
+    def __le__(self, other):
+        return self._compare(other, lambda s, o: s <= o)
+
+    def __eq__(self, other):
+        return self._compare(other, lambda s, o: s == o)
+
+    def __ge__(self, other):
+        return self._compare(other, lambda s, o: s >= o)
+
+    def __gt__(self, other):
+        return self._compare(other, lambda s, o: s > o)
+
+    def __ne__(self, other):
+        return self._compare(other, lambda s, o: s != o)
+
+    def _compare(self, other, method):
+        if not isinstance(other, _BaseVersion):
+            return NotImplemented
+
+        return method(self._key, other._key)
+
+
+class LegacyVersion(_BaseVersion):
+
+    def __init__(self, version):
+        self._version = str(version)
+        self._key = _legacy_cmpkey(self._version)
+
+    def __str__(self):
+        return self._version
+
+    def __repr__(self):
+        return "<LegacyVersion({0})>".format(repr(str(self)))
+
+    @property
+    def public(self):
+        return self._version
+
+    @property
+    def base_version(self):
+        return self._version
+
+    @property
+    def local(self):
+        return None
+
+    @property
+    def is_prerelease(self):
+        return False
+
+    @property
+    def is_postrelease(self):
+        return False
+
+
+_legacy_version_component_re = re.compile(
+    r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE,
+)
+
+_legacy_version_replacement_map = {
+    "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@",
+}
+
+
+def _parse_version_parts(s):
+    for part in _legacy_version_component_re.split(s):
+        part = _legacy_version_replacement_map.get(part, part)
+
+        if not part or part == ".":
+            continue
+
+        if part[:1] in "0123456789":
+            # pad for numeric comparison
+            yield part.zfill(8)
+        else:
+            yield "*" + part
+
+    # ensure that alpha/beta/candidate are before final
+    yield "*final"
+
+
+def _legacy_cmpkey(version):
+    # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch
+    # greater than or equal to 0. This will effectively put the LegacyVersion,
+    # which uses the defacto standard originally implemented by setuptools,
+    # as before all PEP 440 versions.
+    epoch = -1
+
+    # This scheme is taken from pkg_resources.parse_version setuptools prior to
+    # it's adoption of the packaging library.
+    parts = []
+    for part in _parse_version_parts(version.lower()):
+        if part.startswith("*"):
+            # remove "-" before a prerelease tag
+            if part < "*final":
+                while parts and parts[-1] == "*final-":
+                    parts.pop()
+
+            # remove trailing zeros from each series of numeric parts
+            while parts and parts[-1] == "00000000":
+                parts.pop()
+
+        parts.append(part)
+    parts = tuple(parts)
+
+    return epoch, parts
+
+# Deliberately not anchored to the start and end of the string, to make it
+# easier for 3rd party code to reuse
+VERSION_PATTERN = r"""
+    v?
+    (?:
+        (?:(?P<epoch>[0-9]+)!)?                           # epoch
+        (?P<release>[0-9]+(?:\.[0-9]+)*)                  # release segment
+        (?P<pre>                                          # pre-release
+            [-_\.]?
+            (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview))
+            [-_\.]?
+            (?P<pre_n>[0-9]+)?
+        )?
+        (?P<post>                                         # post release
+            (?:-(?P<post_n1>[0-9]+))
+            |
+            (?:
+                [-_\.]?
+                (?P<post_l>post|rev|r)
+                [-_\.]?
+                (?P<post_n2>[0-9]+)?
+            )
+        )?
+        (?P<dev>                                          # dev release
+            [-_\.]?
+            (?P<dev_l>dev)
+            [-_\.]?
+            (?P<dev_n>[0-9]+)?
+        )?
+    )
+    (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))?       # local version
+"""
+
+
+class Version(_BaseVersion):
+
+    _regex = re.compile(
+        r"^\s*" + VERSION_PATTERN + r"\s*$",
+        re.VERBOSE | re.IGNORECASE,
+    )
+
+    def __init__(self, version):
+        # Validate the version and parse it into pieces
+        match = self._regex.search(version)
+        if not match:
+            raise InvalidVersion("Invalid version: '{0}'".format(version))
+
+        # Store the parsed out pieces of the version
+        self._version = _Version(
+            epoch=int(match.group("epoch")) if match.group("epoch") else 0,
+            release=tuple(int(i) for i in match.group("release").split(".")),
+            pre=_parse_letter_version(
+                match.group("pre_l"),
+                match.group("pre_n"),
+            ),
+            post=_parse_letter_version(
+                match.group("post_l"),
+                match.group("post_n1") or match.group("post_n2"),
+            ),
+            dev=_parse_letter_version(
+                match.group("dev_l"),
+                match.group("dev_n"),
+            ),
+            local=_parse_local_version(match.group("local")),
+        )
+
+        # Generate a key which will be used for sorting
+        self._key = _cmpkey(
+            self._version.epoch,
+            self._version.release,
+            self._version.pre,
+            self._version.post,
+            self._version.dev,
+            self._version.local,
+        )
+
+    def __repr__(self):
+        return "<Version({0})>".format(repr(str(self)))
+
+    def __str__(self):
+        parts = []
+
+        # Epoch
+        if self._version.epoch != 0:
+            parts.append("{0}!".format(self._version.epoch))
+
+        # Release segment
+        parts.append(".".join(str(x) for x in self._version.release))
+
+        # Pre-release
+        if self._version.pre is not None:
+            parts.append("".join(str(x) for x in self._version.pre))
+
+        # Post-release
+        if self._version.post is not None:
+            parts.append(".post{0}".format(self._version.post[1]))
+
+        # Development release
+        if self._version.dev is not None:
+            parts.append(".dev{0}".format(self._version.dev[1]))
+
+        # Local version segment
+        if self._version.local is not None:
+            parts.append(
+                "+{0}".format(".".join(str(x) for x in self._version.local))
+            )
+
+        return "".join(parts)
+
+    @property
+    def public(self):
+        return str(self).split("+", 1)[0]
+
+    @property
+    def base_version(self):
+        parts = []
+
+        # Epoch
+        if self._version.epoch != 0:
+            parts.append("{0}!".format(self._version.epoch))
+
+        # Release segment
+        parts.append(".".join(str(x) for x in self._version.release))
+
+        return "".join(parts)
+
+    @property
+    def local(self):
+        version_string = str(self)
+        if "+" in version_string:
+            return version_string.split("+", 1)[1]
+
+    @property
+    def is_prerelease(self):
+        return bool(self._version.dev or self._version.pre)
+
+    @property
+    def is_postrelease(self):
+        return bool(self._version.post)
+
+
+def _parse_letter_version(letter, number):
+    if letter:
+        # We consider there to be an implicit 0 in a pre-release if there is
+        # not a numeral associated with it.
+        if number is None:
+            number = 0
+
+        # We normalize any letters to their lower case form
+        letter = letter.lower()
+
+        # We consider some words to be alternate spellings of other words and
+        # in those cases we want to normalize the spellings to our preferred
+        # spelling.
+        if letter == "alpha":
+            letter = "a"
+        elif letter == "beta":
+            letter = "b"
+        elif letter in ["c", "pre", "preview"]:
+            letter = "rc"
+        elif letter in ["rev", "r"]:
+            letter = "post"
+
+        return letter, int(number)
+    if not letter and number:
+        # We assume if we are given a number, but we are not given a letter
+        # then this is using the implicit post release syntax (e.g. 1.0-1)
+        letter = "post"
+
+        return letter, int(number)
+
+
+_local_version_seperators = re.compile(r"[\._-]")
+
+
+def _parse_local_version(local):
+    """
+    Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve").
+    """
+    if local is not None:
+        return tuple(
+            part.lower() if not part.isdigit() else int(part)
+            for part in _local_version_seperators.split(local)
+        )
+
+
+def _cmpkey(epoch, release, pre, post, dev, local):
+    # When we compare a release version, we want to compare it with all of the
+    # trailing zeros removed. So we'll use a reverse the list, drop all the now
+    # leading zeros until we come to something non zero, then take the rest
+    # re-reverse it back into the correct order and make it a tuple and use
+    # that for our sorting key.
+    release = tuple(
+        reversed(list(
+            itertools.dropwhile(
+                lambda x: x == 0,
+                reversed(release),
+            )
+        ))
+    )
+
+    # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
+    # We'll do this by abusing the pre segment, but we _only_ want to do this
+    # if there is not a pre or a post segment. If we have one of those then
+    # the normal sorting rules will handle this case correctly.
+    if pre is None and post is None and dev is not None:
+        pre = -Infinity
+    # Versions without a pre-release (except as noted above) should sort after
+    # those with one.
+    elif pre is None:
+        pre = Infinity
+
+    # Versions without a post segment should sort before those with one.
+    if post is None:
+        post = -Infinity
+
+    # Versions without a development segment should sort after those with one.
+    if dev is None:
+        dev = Infinity
+
+    if local is None:
+        # Versions without a local segment should sort before those with one.
+        local = -Infinity
+    else:
+        # Versions with a local segment need that segment parsed to implement
+        # the sorting rules in PEP440.
+        # - Alpha numeric segments sort before numeric segments
+        # - Alpha numeric segments sort lexicographically
+        # - Numeric segments sort numerically
+        # - Shorter versions sort before longer versions when the prefixes
+        #   match exactly
+        local = tuple(
+            (i, "") if isinstance(i, int) else (-Infinity, i)
+            for i in local
+        )
+
+    return epoch, release, pre, post, dev, local
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/pyparsing.py b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/pyparsing.py
new file mode 100644
index 00000000..a2122435
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/pyparsing.py
@@ -0,0 +1,5696 @@
+# module pyparsing.py
+#
+# Copyright (c) 2003-2016  Paul T. McGuire
+#
+# 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.
+#
+
+__doc__ = \
+"""
+pyparsing module - Classes and methods to define and execute parsing grammars
+
+The pyparsing module is an alternative approach to creating and executing simple grammars,
+vs. the traditional lex/yacc approach, or the use of regular expressions.  With pyparsing, you
+don't need to learn a new syntax for defining grammars or matching expressions - the parsing module
+provides a library of classes that you use to construct the grammar directly in Python.
+
+Here is a program to parse "Hello, World!" (or any greeting of the form 
+C{"<salutation>, <addressee>!"}), built up using L{Word}, L{Literal}, and L{And} elements 
+(L{'+'<ParserElement.__add__>} operator gives L{And} expressions, strings are auto-converted to
+L{Literal} expressions)::
+
+    from pyparsing import Word, alphas
+
+    # define grammar of a greeting
+    greet = Word(alphas) + "," + Word(alphas) + "!"
+
+    hello = "Hello, World!"
+    print (hello, "->", greet.parseString(hello))
+
+The program outputs the following::
+
+    Hello, World! -> ['Hello', ',', 'World', '!']
+
+The Python representation of the grammar is quite readable, owing to the self-explanatory
+class names, and the use of '+', '|' and '^' operators.
+
+The L{ParseResults} object returned from L{ParserElement.parseString<ParserElement.parseString>} can be accessed as a nested list, a dictionary, or an
+object with named attributes.
+
+The pyparsing module handles some of the problems that are typically vexing when writing text parsers:
+ - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello  ,  World  !", etc.)
+ - quoted strings
+ - embedded comments
+"""
+
+__version__ = "2.1.10"
+__versionTime__ = "07 Oct 2016 01:31 UTC"
+__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
+
+import string
+from weakref import ref as wkref
+import copy
+import sys
+import warnings
+import re
+import sre_constants
+import collections
+import pprint
+import traceback
+import types
+from datetime import datetime
+
+try:
+    from _thread import RLock
+except ImportError:
+    from threading import RLock
+
+try:
+    from collections import OrderedDict as _OrderedDict
+except ImportError:
+    try:
+        from ordereddict import OrderedDict as _OrderedDict
+    except ImportError:
+        _OrderedDict = None
+
+#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) )
+
+__all__ = [
+'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty',
+'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal',
+'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or',
+'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException',
+'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException',
+'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', 
+'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore',
+'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col',
+'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString',
+'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums',
+'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno',
+'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral',
+'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables',
+'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', 
+'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd',
+'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute',
+'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass',
+'CloseMatch', 'tokenMap', 'pyparsing_common',
+]
+
+system_version = tuple(sys.version_info)[:3]
+PY_3 = system_version[0] == 3
+if PY_3:
+    _MAX_INT = sys.maxsize
+    basestring = str
+    unichr = chr
+    _ustr = str
+
+    # build list of single arg builtins, that can be used as parse actions
+    singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max]
+
+else:
+    _MAX_INT = sys.maxint
+    range = xrange
+
+    def _ustr(obj):
+        """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries
+           str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It
+           then < returns the unicode object | encodes it with the default encoding | ... >.
+        """
+        if isinstance(obj,unicode):
+            return obj
+
+        try:
+            # If this works, then _ustr(obj) has the same behaviour as str(obj), so
+            # it won't break any existing code.
+            return str(obj)
+
+        except UnicodeEncodeError:
+            # Else encode it
+            ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace')
+            xmlcharref = Regex('&#\d+;')
+            xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:])
+            return xmlcharref.transformString(ret)
+
+    # build list of single arg builtins, tolerant of Python version, that can be used as parse actions
+    singleArgBuiltins = []
+    import __builtin__
+    for fname in "sum len sorted reversed list tuple set any all min max".split():
+        try:
+            singleArgBuiltins.append(getattr(__builtin__,fname))
+        except AttributeError:
+            continue
+            
+_generatorType = type((y for y in range(1)))
+ 
+def _xml_escape(data):
+    """Escape &, <, >, ", ', etc. in a string of data."""
+
+    # ampersand must be replaced first
+    from_symbols = '&><"\''
+    to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split())
+    for from_,to_ in zip(from_symbols, to_symbols):
+        data = data.replace(from_, to_)
+    return data
+
+class _Constants(object):
+    pass
+
+alphas     = string.ascii_uppercase + string.ascii_lowercase
+nums       = "0123456789"
+hexnums    = nums + "ABCDEFabcdef"
+alphanums  = alphas + nums
+_bslash    = chr(92)
+printables = "".join(c for c in string.printable if c not in string.whitespace)
+
+class ParseBaseException(Exception):
+    """base exception class for all parsing runtime exceptions"""
+    # Performance tuning: we construct a *lot* of these, so keep this
+    # constructor as small and fast as possible
+    def __init__( self, pstr, loc=0, msg=None, elem=None ):
+        self.loc = loc
+        if msg is None:
+            self.msg = pstr
+            self.pstr = ""
+        else:
+            self.msg = msg
+            self.pstr = pstr
+        self.parserElement = elem
+        self.args = (pstr, loc, msg)
+
+    @classmethod
+    def _from_exception(cls, pe):
+        """
+        internal factory method to simplify creating one type of ParseException 
+        from another - avoids having __init__ signature conflicts among subclasses
+        """
+        return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement)
+
+    def __getattr__( self, aname ):
+        """supported attributes by name are:
+            - lineno - returns the line number of the exception text
+            - col - returns the column number of the exception text
+            - line - returns the line containing the exception text
+        """
+        if( aname == "lineno" ):
+            return lineno( self.loc, self.pstr )
+        elif( aname in ("col", "column") ):
+            return col( self.loc, self.pstr )
+        elif( aname == "line" ):
+            return line( self.loc, self.pstr )
+        else:
+            raise AttributeError(aname)
+
+    def __str__( self ):
+        return "%s (at char %d), (line:%d, col:%d)" % \
+                ( self.msg, self.loc, self.lineno, self.column )
+    def __repr__( self ):
+        return _ustr(self)
+    def markInputline( self, markerString = ">!<" ):
+        """Extracts the exception line from the input string, and marks
+           the location of the exception with a special symbol.
+        """
+        line_str = self.line
+        line_column = self.column - 1
+        if markerString:
+            line_str = "".join((line_str[:line_column],
+                                markerString, line_str[line_column:]))
+        return line_str.strip()
+    def __dir__(self):
+        return "lineno col line".split() + dir(type(self))
+
+class ParseException(ParseBaseException):
+    """
+    Exception thrown when parse expressions don't match class;
+    supported attributes by name are:
+     - lineno - returns the line number of the exception text
+     - col - returns the column number of the exception text
+     - line - returns the line containing the exception text
+        
+    Example::
+        try:
+            Word(nums).setName("integer").parseString("ABC")
+        except ParseException as pe:
+            print(pe)
+            print("column: {}".format(pe.col))
+            
+    prints::
+       Expected integer (at char 0), (line:1, col:1)
+        column: 1
+    """
+    pass
+
+class ParseFatalException(ParseBaseException):
+    """user-throwable exception thrown when inconsistent parse content
+       is found; stops all parsing immediately"""
+    pass
+
+class ParseSyntaxException(ParseFatalException):
+    """just like L{ParseFatalException}, but thrown internally when an
+       L{ErrorStop<And._ErrorStop>} ('-' operator) indicates that parsing is to stop 
+       immediately because an unbacktrackable syntax error has been found"""
+    pass
+
+#~ class ReparseException(ParseBaseException):
+    #~ """Experimental class - parse actions can raise this exception to cause
+       #~ pyparsing to reparse the input string:
+        #~ - with a modified input string, and/or
+        #~ - with a modified start location
+       #~ Set the values of the ReparseException in the constructor, and raise the
+       #~ exception in a parse action to cause pyparsing to use the new string/location.
+       #~ Setting the values as None causes no change to be made.
+       #~ """
+    #~ def __init_( self, newstring, restartLoc ):
+        #~ self.newParseText = newstring
+        #~ self.reparseLoc = restartLoc
+
+class RecursiveGrammarException(Exception):
+    """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive"""
+    def __init__( self, parseElementList ):
+        self.parseElementTrace = parseElementList
+
+    def __str__( self ):
+        return "RecursiveGrammarException: %s" % self.parseElementTrace
+
+class _ParseResultsWithOffset(object):
+    def __init__(self,p1,p2):
+        self.tup = (p1,p2)
+    def __getitem__(self,i):
+        return self.tup[i]
+    def __repr__(self):
+        return repr(self.tup[0])
+    def setOffset(self,i):
+        self.tup = (self.tup[0],i)
+
+class ParseResults(object):
+    """
+    Structured parse results, to provide multiple means of access to the parsed data:
+       - as a list (C{len(results)})
+       - by list index (C{results[0], results[1]}, etc.)
+       - by attribute (C{results.<resultsName>} - see L{ParserElement.setResultsName})
+
+    Example::
+        integer = Word(nums)
+        date_str = (integer.setResultsName("year") + '/' 
+                        + integer.setResultsName("month") + '/' 
+                        + integer.setResultsName("day"))
+        # equivalent form:
+        # date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+
+        # parseString returns a ParseResults object
+        result = date_str.parseString("1999/12/31")
+
+        def test(s, fn=repr):
+            print("%s -> %s" % (s, fn(eval(s))))
+        test("list(result)")
+        test("result[0]")
+        test("result['month']")
+        test("result.day")
+        test("'month' in result")
+        test("'minutes' in result")
+        test("result.dump()", str)
+    prints::
+        list(result) -> ['1999', '/', '12', '/', '31']
+        result[0] -> '1999'
+        result['month'] -> '12'
+        result.day -> '31'
+        'month' in result -> True
+        'minutes' in result -> False
+        result.dump() -> ['1999', '/', '12', '/', '31']
+        - day: 31
+        - month: 12
+        - year: 1999
+    """
+    def __new__(cls, toklist=None, name=None, asList=True, modal=True ):
+        if isinstance(toklist, cls):
+            return toklist
+        retobj = object.__new__(cls)
+        retobj.__doinit = True
+        return retobj
+
+    # Performance tuning: we construct a *lot* of these, so keep this
+    # constructor as small and fast as possible
+    def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ):
+        if self.__doinit:
+            self.__doinit = False
+            self.__name = None
+            self.__parent = None
+            self.__accumNames = {}
+            self.__asList = asList
+            self.__modal = modal
+            if toklist is None:
+                toklist = []
+            if isinstance(toklist, list):
+                self.__toklist = toklist[:]
+            elif isinstance(toklist, _generatorType):
+                self.__toklist = list(toklist)
+            else:
+                self.__toklist = [toklist]
+            self.__tokdict = dict()
+
+        if name is not None and name:
+            if not modal:
+                self.__accumNames[name] = 0
+            if isinstance(name,int):
+                name = _ustr(name) # will always return a str, but use _ustr for consistency
+            self.__name = name
+            if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])):
+                if isinstance(toklist,basestring):
+                    toklist = [ toklist ]
+                if asList:
+                    if isinstance(toklist,ParseResults):
+                        self[name] = _ParseResultsWithOffset(toklist.copy(),0)
+                    else:
+                        self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0)
+                    self[name].__name = name
+                else:
+                    try:
+                        self[name] = toklist[0]
+                    except (KeyError,TypeError,IndexError):
+                        self[name] = toklist
+
+    def __getitem__( self, i ):
+        if isinstance( i, (int,slice) ):
+            return self.__toklist[i]
+        else:
+            if i not in self.__accumNames:
+                return self.__tokdict[i][-1][0]
+            else:
+                return ParseResults([ v[0] for v in self.__tokdict[i] ])
+
+    def __setitem__( self, k, v, isinstance=isinstance ):
+        if isinstance(v,_ParseResultsWithOffset):
+            self.__tokdict[k] = self.__tokdict.get(k,list()) + [v]
+            sub = v[0]
+        elif isinstance(k,(int,slice)):
+            self.__toklist[k] = v
+            sub = v
+        else:
+            self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)]
+            sub = v
+        if isinstance(sub,ParseResults):
+            sub.__parent = wkref(self)
+
+    def __delitem__( self, i ):
+        if isinstance(i,(int,slice)):
+            mylen = len( self.__toklist )
+            del self.__toklist[i]
+
+            # convert int to slice
+            if isinstance(i, int):
+                if i < 0:
+                    i += mylen
+                i = slice(i, i+1)
+            # get removed indices
+            removed = list(range(*i.indices(mylen)))
+            removed.reverse()
+            # fixup indices in token dictionary
+            for name,occurrences in self.__tokdict.items():
+                for j in removed:
+                    for k, (value, position) in enumerate(occurrences):
+                        occurrences[k] = _ParseResultsWithOffset(value, position - (position > j))
+        else:
+            del self.__tokdict[i]
+
+    def __contains__( self, k ):
+        return k in self.__tokdict
+
+    def __len__( self ): return len( self.__toklist )
+    def __bool__(self): return ( not not self.__toklist )
+    __nonzero__ = __bool__
+    def __iter__( self ): return iter( self.__toklist )
+    def __reversed__( self ): return iter( self.__toklist[::-1] )
+    def _iterkeys( self ):
+        if hasattr(self.__tokdict, "iterkeys"):
+            return self.__tokdict.iterkeys()
+        else:
+            return iter(self.__tokdict)
+
+    def _itervalues( self ):
+        return (self[k] for k in self._iterkeys())
+            
+    def _iteritems( self ):
+        return ((k, self[k]) for k in self._iterkeys())
+
+    if PY_3:
+        keys = _iterkeys       
+        """Returns an iterator of all named result keys (Python 3.x only)."""
+
+        values = _itervalues
+        """Returns an iterator of all named result values (Python 3.x only)."""
+
+        items = _iteritems
+        """Returns an iterator of all named result key-value tuples (Python 3.x only)."""
+
+    else:
+        iterkeys = _iterkeys
+        """Returns an iterator of all named result keys (Python 2.x only)."""
+
+        itervalues = _itervalues
+        """Returns an iterator of all named result values (Python 2.x only)."""
+
+        iteritems = _iteritems
+        """Returns an iterator of all named result key-value tuples (Python 2.x only)."""
+
+        def keys( self ):
+            """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x)."""
+            return list(self.iterkeys())
+
+        def values( self ):
+            """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x)."""
+            return list(self.itervalues())
+                
+        def items( self ):
+            """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x)."""
+            return list(self.iteritems())
+
+    def haskeys( self ):
+        """Since keys() returns an iterator, this method is helpful in bypassing
+           code that looks for the existence of any defined results names."""
+        return bool(self.__tokdict)
+        
+    def pop( self, *args, **kwargs):
+        """
+        Removes and returns item at specified index (default=C{last}).
+        Supports both C{list} and C{dict} semantics for C{pop()}. If passed no
+        argument or an integer argument, it will use C{list} semantics
+        and pop tokens from the list of parsed tokens. If passed a 
+        non-integer argument (most likely a string), it will use C{dict}
+        semantics and pop the corresponding value from any defined 
+        results names. A second default return value argument is 
+        supported, just as in C{dict.pop()}.
+
+        Example::
+            def remove_first(tokens):
+                tokens.pop(0)
+            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
+            print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321']
+
+            label = Word(alphas)
+            patt = label("LABEL") + OneOrMore(Word(nums))
+            print(patt.parseString("AAB 123 321").dump())
+
+            # Use pop() in a parse action to remove named result (note that corresponding value is not
+            # removed from list form of results)
+            def remove_LABEL(tokens):
+                tokens.pop("LABEL")
+                return tokens
+            patt.addParseAction(remove_LABEL)
+            print(patt.parseString("AAB 123 321").dump())
+        prints::
+            ['AAB', '123', '321']
+            - LABEL: AAB
+
+            ['AAB', '123', '321']
+        """
+        if not args:
+            args = [-1]
+        for k,v in kwargs.items():
+            if k == 'default':
+                args = (args[0], v)
+            else:
+                raise TypeError("pop() got an unexpected keyword argument '%s'" % k)
+        if (isinstance(args[0], int) or 
+                        len(args) == 1 or 
+                        args[0] in self):
+            index = args[0]
+            ret = self[index]
+            del self[index]
+            return ret
+        else:
+            defaultvalue = args[1]
+            return defaultvalue
+
+    def get(self, key, defaultValue=None):
+        """
+        Returns named result matching the given key, or if there is no
+        such name, then returns the given C{defaultValue} or C{None} if no
+        C{defaultValue} is specified.
+
+        Similar to C{dict.get()}.
+        
+        Example::
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
+
+            result = date_str.parseString("1999/12/31")
+            print(result.get("year")) # -> '1999'
+            print(result.get("hour", "not specified")) # -> 'not specified'
+            print(result.get("hour")) # -> None
+        """
+        if key in self:
+            return self[key]
+        else:
+            return defaultValue
+
+    def insert( self, index, insStr ):
+        """
+        Inserts new element at location index in the list of parsed tokens.
+        
+        Similar to C{list.insert()}.
+
+        Example::
+            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
+
+            # use a parse action to insert the parse location in the front of the parsed results
+            def insert_locn(locn, tokens):
+                tokens.insert(0, locn)
+            print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321']
+        """
+        self.__toklist.insert(index, insStr)
+        # fixup indices in token dictionary
+        for name,occurrences in self.__tokdict.items():
+            for k, (value, position) in enumerate(occurrences):
+                occurrences[k] = _ParseResultsWithOffset(value, position + (position > index))
+
+    def append( self, item ):
+        """
+        Add single element to end of ParseResults list of elements.
+
+        Example::
+            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
+            
+            # use a parse action to compute the sum of the parsed integers, and add it to the end
+            def append_sum(tokens):
+                tokens.append(sum(map(int, tokens)))
+            print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444]
+        """
+        self.__toklist.append(item)
+
+    def extend( self, itemseq ):
+        """
+        Add sequence of elements to end of ParseResults list of elements.
+
+        Example::
+            patt = OneOrMore(Word(alphas))
+            
+            # use a parse action to append the reverse of the matched strings, to make a palindrome
+            def make_palindrome(tokens):
+                tokens.extend(reversed([t[::-1] for t in tokens]))
+                return ''.join(tokens)
+            print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl'
+        """
+        if isinstance(itemseq, ParseResults):
+            self += itemseq
+        else:
+            self.__toklist.extend(itemseq)
+
+    def clear( self ):
+        """
+        Clear all elements and results names.
+        """
+        del self.__toklist[:]
+        self.__tokdict.clear()
+
+    def __getattr__( self, name ):
+        try:
+            return self[name]
+        except KeyError:
+            return ""
+            
+        if name in self.__tokdict:
+            if name not in self.__accumNames:
+                return self.__tokdict[name][-1][0]
+            else:
+                return ParseResults([ v[0] for v in self.__tokdict[name] ])
+        else:
+            return ""
+
+    def __add__( self, other ):
+        ret = self.copy()
+        ret += other
+        return ret
+
+    def __iadd__( self, other ):
+        if other.__tokdict:
+            offset = len(self.__toklist)
+            addoffset = lambda a: offset if a<0 else a+offset
+            otheritems = other.__tokdict.items()
+            otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) )
+                                for (k,vlist) in otheritems for v in vlist]
+            for k,v in otherdictitems:
+                self[k] = v
+                if isinstance(v[0],ParseResults):
+                    v[0].__parent = wkref(self)
+            
+        self.__toklist += other.__toklist
+        self.__accumNames.update( other.__accumNames )
+        return self
+
+    def __radd__(self, other):
+        if isinstance(other,int) and other == 0:
+            # useful for merging many ParseResults using sum() builtin
+            return self.copy()
+        else:
+            # this may raise a TypeError - so be it
+            return other + self
+        
+    def __repr__( self ):
+        return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) )
+
+    def __str__( self ):
+        return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']'
+
+    def _asStringList( self, sep='' ):
+        out = []
+        for item in self.__toklist:
+            if out and sep:
+                out.append(sep)
+            if isinstance( item, ParseResults ):
+                out += item._asStringList()
+            else:
+                out.append( _ustr(item) )
+        return out
+
+    def asList( self ):
+        """
+        Returns the parse results as a nested list of matching tokens, all converted to strings.
+
+        Example::
+            patt = OneOrMore(Word(alphas))
+            result = patt.parseString("sldkj lsdkj sldkj")
+            # even though the result prints in string-like form, it is actually a pyparsing ParseResults
+            print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj']
+            
+            # Use asList() to create an actual list
+            result_list = result.asList()
+            print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj']
+        """
+        return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist]
+
+    def asDict( self ):
+        """
+        Returns the named parse results as a nested dictionary.
+
+        Example::
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+            
+            result = date_str.parseString('12/31/1999')
+            print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]})
+            
+            result_dict = result.asDict()
+            print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'}
+
+            # even though a ParseResults supports dict-like access, sometime you just need to have a dict
+            import json
+            print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable
+            print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"}
+        """
+        if PY_3:
+            item_fn = self.items
+        else:
+            item_fn = self.iteritems
+            
+        def toItem(obj):
+            if isinstance(obj, ParseResults):
+                if obj.haskeys():
+                    return obj.asDict()
+                else:
+                    return [toItem(v) for v in obj]
+            else:
+                return obj
+                
+        return dict((k,toItem(v)) for k,v in item_fn())
+
+    def copy( self ):
+        """
+        Returns a new copy of a C{ParseResults} object.
+        """
+        ret = ParseResults( self.__toklist )
+        ret.__tokdict = self.__tokdict.copy()
+        ret.__parent = self.__parent
+        ret.__accumNames.update( self.__accumNames )
+        ret.__name = self.__name
+        return ret
+
+    def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ):
+        """
+        (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names.
+        """
+        nl = "\n"
+        out = []
+        namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items()
+                                                            for v in vlist)
+        nextLevelIndent = indent + "  "
+
+        # collapse out indents if formatting is not desired
+        if not formatted:
+            indent = ""
+            nextLevelIndent = ""
+            nl = ""
+
+        selfTag = None
+        if doctag is not None:
+            selfTag = doctag
+        else:
+            if self.__name:
+                selfTag = self.__name
+
+        if not selfTag:
+            if namedItemsOnly:
+                return ""
+            else:
+                selfTag = "ITEM"
+
+        out += [ nl, indent, "<", selfTag, ">" ]
+
+        for i,res in enumerate(self.__toklist):
+            if isinstance(res,ParseResults):
+                if i in namedItems:
+                    out += [ res.asXML(namedItems[i],
+                                        namedItemsOnly and doctag is None,
+                                        nextLevelIndent,
+                                        formatted)]
+                else:
+                    out += [ res.asXML(None,
+                                        namedItemsOnly and doctag is None,
+                                        nextLevelIndent,
+                                        formatted)]
+            else:
+                # individual token, see if there is a name for it
+                resTag = None
+                if i in namedItems:
+                    resTag = namedItems[i]
+                if not resTag:
+                    if namedItemsOnly:
+                        continue
+                    else:
+                        resTag = "ITEM"
+                xmlBodyText = _xml_escape(_ustr(res))
+                out += [ nl, nextLevelIndent, "<", resTag, ">",
+                                                xmlBodyText,
+                                                "</", resTag, ">" ]
+
+        out += [ nl, indent, "</", selfTag, ">" ]
+        return "".join(out)
+
+    def __lookup(self,sub):
+        for k,vlist in self.__tokdict.items():
+            for v,loc in vlist:
+                if sub is v:
+                    return k
+        return None
+
+    def getName(self):
+        """
+        Returns the results name for this token expression. Useful when several 
+        different expressions might match at a particular location.
+
+        Example::
+            integer = Word(nums)
+            ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d")
+            house_number_expr = Suppress('#') + Word(nums, alphanums)
+            user_data = (Group(house_number_expr)("house_number") 
+                        | Group(ssn_expr)("ssn")
+                        | Group(integer)("age"))
+            user_info = OneOrMore(user_data)
+            
+            result = user_info.parseString("22 111-22-3333 #221B")
+            for item in result:
+                print(item.getName(), ':', item[0])
+        prints::
+            age : 22
+            ssn : 111-22-3333
+            house_number : 221B
+        """
+        if self.__name:
+            return self.__name
+        elif self.__parent:
+            par = self.__parent()
+            if par:
+                return par.__lookup(self)
+            else:
+                return None
+        elif (len(self) == 1 and
+               len(self.__tokdict) == 1 and
+               next(iter(self.__tokdict.values()))[0][1] in (0,-1)):
+            return next(iter(self.__tokdict.keys()))
+        else:
+            return None
+
+    def dump(self, indent='', depth=0, full=True):
+        """
+        Diagnostic method for listing out the contents of a C{ParseResults}.
+        Accepts an optional C{indent} argument so that this string can be embedded
+        in a nested display of other data.
+
+        Example::
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+            
+            result = date_str.parseString('12/31/1999')
+            print(result.dump())
+        prints::
+            ['12', '/', '31', '/', '1999']
+            - day: 1999
+            - month: 31
+            - year: 12
+        """
+        out = []
+        NL = '\n'
+        out.append( indent+_ustr(self.asList()) )
+        if full:
+            if self.haskeys():
+                items = sorted((str(k), v) for k,v in self.items())
+                for k,v in items:
+                    if out:
+                        out.append(NL)
+                    out.append( "%s%s- %s: " % (indent,('  '*depth), k) )
+                    if isinstance(v,ParseResults):
+                        if v:
+                            out.append( v.dump(indent,depth+1) )
+                        else:
+                            out.append(_ustr(v))
+                    else:
+                        out.append(repr(v))
+            elif any(isinstance(vv,ParseResults) for vv in self):
+                v = self
+                for i,vv in enumerate(v):
+                    if isinstance(vv,ParseResults):
+                        out.append("\n%s%s[%d]:\n%s%s%s" % (indent,('  '*(depth)),i,indent,('  '*(depth+1)),vv.dump(indent,depth+1) ))
+                    else:
+                        out.append("\n%s%s[%d]:\n%s%s%s" % (indent,('  '*(depth)),i,indent,('  '*(depth+1)),_ustr(vv)))
+            
+        return "".join(out)
+
+    def pprint(self, *args, **kwargs):
+        """
+        Pretty-printer for parsed results as a list, using the C{pprint} module.
+        Accepts additional positional or keyword args as defined for the 
+        C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint})
+
+        Example::
+            ident = Word(alphas, alphanums)
+            num = Word(nums)
+            func = Forward()
+            term = ident | num | Group('(' + func + ')')
+            func <<= ident + Group(Optional(delimitedList(term)))
+            result = func.parseString("fna a,b,(fnb c,d,200),100")
+            result.pprint(width=40)
+        prints::
+            ['fna',
+             ['a',
+              'b',
+              ['(', 'fnb', ['c', 'd', '200'], ')'],
+              '100']]
+        """
+        pprint.pprint(self.asList(), *args, **kwargs)
+
+    # add support for pickle protocol
+    def __getstate__(self):
+        return ( self.__toklist,
+                 ( self.__tokdict.copy(),
+                   self.__parent is not None and self.__parent() or None,
+                   self.__accumNames,
+                   self.__name ) )
+
+    def __setstate__(self,state):
+        self.__toklist = state[0]
+        (self.__tokdict,
+         par,
+         inAccumNames,
+         self.__name) = state[1]
+        self.__accumNames = {}
+        self.__accumNames.update(inAccumNames)
+        if par is not None:
+            self.__parent = wkref(par)
+        else:
+            self.__parent = None
+
+    def __getnewargs__(self):
+        return self.__toklist, self.__name, self.__asList, self.__modal
+
+    def __dir__(self):
+        return (dir(type(self)) + list(self.keys()))
+
+collections.MutableMapping.register(ParseResults)
+
+def col (loc,strg):
+    """Returns current column within a string, counting newlines as line separators.
+   The first column is number 1.
+
+   Note: the default parsing behavior is to expand tabs in the input string
+   before starting the parsing process.  See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information
+   on parsing strings containing C{<TAB>}s, and suggested methods to maintain a
+   consistent view of the parsed string, the parse location, and line and column
+   positions within the parsed string.
+   """
+    s = strg
+    return 1 if 0<loc<len(s) and s[loc-1] == '\n' else loc - s.rfind("\n", 0, loc)
+
+def lineno(loc,strg):
+    """Returns current line number within a string, counting newlines as line separators.
+   The first line is number 1.
+
+   Note: the default parsing behavior is to expand tabs in the input string
+   before starting the parsing process.  See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information
+   on parsing strings containing C{<TAB>}s, and suggested methods to maintain a
+   consistent view of the parsed string, the parse location, and line and column
+   positions within the parsed string.
+   """
+    return strg.count("\n",0,loc) + 1
+
+def line( loc, strg ):
+    """Returns the line of text containing loc within a string, counting newlines as line separators.
+       """
+    lastCR = strg.rfind("\n", 0, loc)
+    nextCR = strg.find("\n", loc)
+    if nextCR >= 0:
+        return strg[lastCR+1:nextCR]
+    else:
+        return strg[lastCR+1:]
+
+def _defaultStartDebugAction( instring, loc, expr ):
+    print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )))
+
+def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ):
+    print ("Matched " + _ustr(expr) + " -> " + str(toks.asList()))
+
+def _defaultExceptionDebugAction( instring, loc, expr, exc ):
+    print ("Exception raised:" + _ustr(exc))
+
+def nullDebugAction(*args):
+    """'Do-nothing' debug action, to suppress debugging output during parsing."""
+    pass
+
+# Only works on Python 3.x - nonlocal is toxic to Python 2 installs
+#~ 'decorator to trim function calls to match the arity of the target'
+#~ def _trim_arity(func, maxargs=3):
+    #~ if func in singleArgBuiltins:
+        #~ return lambda s,l,t: func(t)
+    #~ limit = 0
+    #~ foundArity = False
+    #~ def wrapper(*args):
+        #~ nonlocal limit,foundArity
+        #~ while 1:
+            #~ try:
+                #~ ret = func(*args[limit:])
+                #~ foundArity = True
+                #~ return ret
+            #~ except TypeError:
+                #~ if limit == maxargs or foundArity:
+                    #~ raise
+                #~ limit += 1
+                #~ continue
+    #~ return wrapper
+
+# this version is Python 2.x-3.x cross-compatible
+'decorator to trim function calls to match the arity of the target'
+def _trim_arity(func, maxargs=2):
+    if func in singleArgBuiltins:
+        return lambda s,l,t: func(t)
+    limit = [0]
+    foundArity = [False]
+    
+    # traceback return data structure changed in Py3.5 - normalize back to plain tuples
+    if system_version[:2] >= (3,5):
+        def extract_stack(limit=0):
+            # special handling for Python 3.5.0 - extra deep call stack by 1
+            offset = -3 if system_version == (3,5,0) else -2
+            frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset]
+            return [(frame_summary.filename, frame_summary.lineno)]
+        def extract_tb(tb, limit=0):
+            frames = traceback.extract_tb(tb, limit=limit)
+            frame_summary = frames[-1]
+            return [(frame_summary.filename, frame_summary.lineno)]
+    else:
+        extract_stack = traceback.extract_stack
+        extract_tb = traceback.extract_tb
+    
+    # synthesize what would be returned by traceback.extract_stack at the call to 
+    # user's parse action 'func', so that we don't incur call penalty at parse time
+    
+    LINE_DIFF = 6
+    # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND 
+    # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!!
+    this_line = extract_stack(limit=2)[-1]
+    pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF)
+
+    def wrapper(*args):
+        while 1:
+            try:
+                ret = func(*args[limit[0]:])
+                foundArity[0] = True
+                return ret
+            except TypeError:
+                # re-raise TypeErrors if they did not come from our arity testing
+                if foundArity[0]:
+                    raise
+                else:
+                    try:
+                        tb = sys.exc_info()[-1]
+                        if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth:
+                            raise
+                    finally:
+                        del tb
+
+                if limit[0] <= maxargs:
+                    limit[0] += 1
+                    continue
+                raise
+
+    # copy func name to wrapper for sensible debug output
+    func_name = "<parse action>"
+    try:
+        func_name = getattr(func, '__name__', 
+                            getattr(func, '__class__').__name__)
+    except Exception:
+        func_name = str(func)
+    wrapper.__name__ = func_name
+
+    return wrapper
+
+class ParserElement(object):
+    """Abstract base level parser element class."""
+    DEFAULT_WHITE_CHARS = " \n\t\r"
+    verbose_stacktrace = False
+
+    @staticmethod
+    def setDefaultWhitespaceChars( chars ):
+        r"""
+        Overrides the default whitespace chars
+
+        Example::
+            # default whitespace chars are space, <TAB> and newline
+            OneOrMore(Word(alphas)).parseString("abc def\nghi jkl")  # -> ['abc', 'def', 'ghi', 'jkl']
+            
+            # change to just treat newline as significant
+            ParserElement.setDefaultWhitespaceChars(" \t")
+            OneOrMore(Word(alphas)).parseString("abc def\nghi jkl")  # -> ['abc', 'def']
+        """
+        ParserElement.DEFAULT_WHITE_CHARS = chars
+
+    @staticmethod
+    def inlineLiteralsUsing(cls):
+        """
+        Set class to be used for inclusion of string literals into a parser.
+        
+        Example::
+            # default literal class used is Literal
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
+
+            date_str.parseString("1999/12/31")  # -> ['1999', '/', '12', '/', '31']
+
+
+            # change to Suppress
+            ParserElement.inlineLiteralsUsing(Suppress)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
+
+            date_str.parseString("1999/12/31")  # -> ['1999', '12', '31']
+        """
+        ParserElement._literalStringClass = cls
+
+    def __init__( self, savelist=False ):
+        self.parseAction = list()
+        self.failAction = None
+        #~ self.name = "<unknown>"  # don't define self.name, let subclasses try/except upcall
+        self.strRepr = None
+        self.resultsName = None
+        self.saveAsList = savelist
+        self.skipWhitespace = True
+        self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
+        self.copyDefaultWhiteChars = True
+        self.mayReturnEmpty = False # used when checking for left-recursion
+        self.keepTabs = False
+        self.ignoreExprs = list()
+        self.debug = False
+        self.streamlined = False
+        self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index
+        self.errmsg = ""
+        self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all)
+        self.debugActions = ( None, None, None ) #custom debug actions
+        self.re = None
+        self.callPreparse = True # used to avoid redundant calls to preParse
+        self.callDuringTry = False
+
+    def copy( self ):
+        """
+        Make a copy of this C{ParserElement}.  Useful for defining different parse actions
+        for the same parsing pattern, using copies of the original parse element.
+        
+        Example::
+            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
+            integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K")
+            integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
+            
+            print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M"))
+        prints::
+            [5120, 100, 655360, 268435456]
+        Equivalent form of C{expr.copy()} is just C{expr()}::
+            integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
+        """
+        cpy = copy.copy( self )
+        cpy.parseAction = self.parseAction[:]
+        cpy.ignoreExprs = self.ignoreExprs[:]
+        if self.copyDefaultWhiteChars:
+            cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
+        return cpy
+
+    def setName( self, name ):
+        """
+        Define name for this expression, makes debugging and exception messages clearer.
+        
+        Example::
+            Word(nums).parseString("ABC")  # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1)
+            Word(nums).setName("integer").parseString("ABC")  # -> Exception: Expected integer (at char 0), (line:1, col:1)
+        """
+        self.name = name
+        self.errmsg = "Expected " + self.name
+        if hasattr(self,"exception"):
+            self.exception.msg = self.errmsg
+        return self
+
+    def setResultsName( self, name, listAllMatches=False ):
+        """
+        Define name for referencing matching tokens as a nested attribute
+        of the returned parse results.
+        NOTE: this returns a *copy* of the original C{ParserElement} object;
+        this is so that the client can define a basic element, such as an
+        integer, and reference it in multiple places with different names.
+
+        You can also set results names using the abbreviated syntax,
+        C{expr("name")} in place of C{expr.setResultsName("name")} - 
+        see L{I{__call__}<__call__>}.
+
+        Example::
+            date_str = (integer.setResultsName("year") + '/' 
+                        + integer.setResultsName("month") + '/' 
+                        + integer.setResultsName("day"))
+
+            # equivalent form:
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+        """
+        newself = self.copy()
+        if name.endswith("*"):
+            name = name[:-1]
+            listAllMatches=True
+        newself.resultsName = name
+        newself.modalResults = not listAllMatches
+        return newself
+
+    def setBreak(self,breakFlag = True):
+        """Method to invoke the Python pdb debugger when this element is
+           about to be parsed. Set C{breakFlag} to True to enable, False to
+           disable.
+        """
+        if breakFlag:
+            _parseMethod = self._parse
+            def breaker(instring, loc, doActions=True, callPreParse=True):
+                import pdb
+                pdb.set_trace()
+                return _parseMethod( instring, loc, doActions, callPreParse )
+            breaker._originalParseMethod = _parseMethod
+            self._parse = breaker
+        else:
+            if hasattr(self._parse,"_originalParseMethod"):
+                self._parse = self._parse._originalParseMethod
+        return self
+
+    def setParseAction( self, *fns, **kwargs ):
+        """
+        Define action to perform when successfully matching parse element definition.
+        Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)},
+        C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where:
+         - s   = the original string being parsed (see note below)
+         - loc = the location of the matching substring
+         - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object
+        If the functions in fns modify the tokens, they can return them as the return
+        value from fn, and the modified list of tokens will replace the original.
+        Otherwise, fn does not need to return any value.
+
+        Optional keyword arguments:
+         - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing
+
+        Note: the default parsing behavior is to expand tabs in the input string
+        before starting the parsing process.  See L{I{parseString}<parseString>} for more information
+        on parsing strings containing C{<TAB>}s, and suggested methods to maintain a
+        consistent view of the parsed string, the parse location, and line and column
+        positions within the parsed string.
+        
+        Example::
+            integer = Word(nums)
+            date_str = integer + '/' + integer + '/' + integer
+
+            date_str.parseString("1999/12/31")  # -> ['1999', '/', '12', '/', '31']
+
+            # use parse action to convert to ints at parse time
+            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
+            date_str = integer + '/' + integer + '/' + integer
+
+            # note that integer fields are now ints, not strings
+            date_str.parseString("1999/12/31")  # -> [1999, '/', 12, '/', 31]
+        """
+        self.parseAction = list(map(_trim_arity, list(fns)))
+        self.callDuringTry = kwargs.get("callDuringTry", False)
+        return self
+
+    def addParseAction( self, *fns, **kwargs ):
+        """
+        Add parse action to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}.
+        
+        See examples in L{I{copy}<copy>}.
+        """
+        self.parseAction += list(map(_trim_arity, list(fns)))
+        self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False)
+        return self
+
+    def addCondition(self, *fns, **kwargs):
+        """Add a boolean predicate function to expression's list of parse actions. See 
+        L{I{setParseAction}<setParseAction>} for function call signatures. Unlike C{setParseAction}, 
+        functions passed to C{addCondition} need to return boolean success/fail of the condition.
+
+        Optional keyword arguments:
+         - message = define a custom message to be used in the raised exception
+         - fatal   = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException
+         
+        Example::
+            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
+            year_int = integer.copy()
+            year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later")
+            date_str = year_int + '/' + integer + '/' + integer
+
+            result = date_str.parseString("1999/12/31")  # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1)
+        """
+        msg = kwargs.get("message", "failed user-defined condition")
+        exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException
+        for fn in fns:
+            def pa(s,l,t):
+                if not bool(_trim_arity(fn)(s,l,t)):
+                    raise exc_type(s,l,msg)
+            self.parseAction.append(pa)
+        self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False)
+        return self
+
+    def setFailAction( self, fn ):
+        """Define action to perform if parsing fails at this expression.
+           Fail acton fn is a callable function that takes the arguments
+           C{fn(s,loc,expr,err)} where:
+            - s = string being parsed
+            - loc = location where expression match was attempted and failed
+            - expr = the parse expression that failed
+            - err = the exception thrown
+           The function returns no value.  It may throw C{L{ParseFatalException}}
+           if it is desired to stop parsing immediately."""
+        self.failAction = fn
+        return self
+
+    def _skipIgnorables( self, instring, loc ):
+        exprsFound = True
+        while exprsFound:
+            exprsFound = False
+            for e in self.ignoreExprs:
+                try:
+                    while 1:
+                        loc,dummy = e._parse( instring, loc )
+                        exprsFound = True
+                except ParseException:
+                    pass
+        return loc
+
+    def preParse( self, instring, loc ):
+        if self.ignoreExprs:
+            loc = self._skipIgnorables( instring, loc )
+
+        if self.skipWhitespace:
+            wt = self.whiteChars
+            instrlen = len(instring)
+            while loc < instrlen and instring[loc] in wt:
+                loc += 1
+
+        return loc
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        return loc, []
+
+    def postParse( self, instring, loc, tokenlist ):
+        return tokenlist
+
+    #~ @profile
+    def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ):
+        debugging = ( self.debug ) #and doActions )
+
+        if debugging or self.failAction:
+            #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))
+            if (self.debugActions[0] ):
+                self.debugActions[0]( instring, loc, self )
+            if callPreParse and self.callPreparse:
+                preloc = self.preParse( instring, loc )
+            else:
+                preloc = loc
+            tokensStart = preloc
+            try:
+                try:
+                    loc,tokens = self.parseImpl( instring, preloc, doActions )
+                except IndexError:
+                    raise ParseException( instring, len(instring), self.errmsg, self )
+            except ParseBaseException as err:
+                #~ print ("Exception raised:", err)
+                if self.debugActions[2]:
+                    self.debugActions[2]( instring, tokensStart, self, err )
+                if self.failAction:
+                    self.failAction( instring, tokensStart, self, err )
+                raise
+        else:
+            if callPreParse and self.callPreparse:
+                preloc = self.preParse( instring, loc )
+            else:
+                preloc = loc
+            tokensStart = preloc
+            if self.mayIndexError or loc >= len(instring):
+                try:
+                    loc,tokens = self.parseImpl( instring, preloc, doActions )
+                except IndexError:
+                    raise ParseException( instring, len(instring), self.errmsg, self )
+            else:
+                loc,tokens = self.parseImpl( instring, preloc, doActions )
+
+        tokens = self.postParse( instring, loc, tokens )
+
+        retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults )
+        if self.parseAction and (doActions or self.callDuringTry):
+            if debugging:
+                try:
+                    for fn in self.parseAction:
+                        tokens = fn( instring, tokensStart, retTokens )
+                        if tokens is not None:
+                            retTokens = ParseResults( tokens,
+                                                      self.resultsName,
+                                                      asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
+                                                      modal=self.modalResults )
+                except ParseBaseException as err:
+                    #~ print "Exception raised in user parse action:", err
+                    if (self.debugActions[2] ):
+                        self.debugActions[2]( instring, tokensStart, self, err )
+                    raise
+            else:
+                for fn in self.parseAction:
+                    tokens = fn( instring, tokensStart, retTokens )
+                    if tokens is not None:
+                        retTokens = ParseResults( tokens,
+                                                  self.resultsName,
+                                                  asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
+                                                  modal=self.modalResults )
+
+        if debugging:
+            #~ print ("Matched",self,"->",retTokens.asList())
+            if (self.debugActions[1] ):
+                self.debugActions[1]( instring, tokensStart, loc, self, retTokens )
+
+        return loc, retTokens
+
+    def tryParse( self, instring, loc ):
+        try:
+            return self._parse( instring, loc, doActions=False )[0]
+        except ParseFatalException:
+            raise ParseException( instring, loc, self.errmsg, self)
+    
+    def canParseNext(self, instring, loc):
+        try:
+            self.tryParse(instring, loc)
+        except (ParseException, IndexError):
+            return False
+        else:
+            return True
+
+    class _UnboundedCache(object):
+        def __init__(self):
+            cache = {}
+            self.not_in_cache = not_in_cache = object()
+
+            def get(self, key):
+                return cache.get(key, not_in_cache)
+
+            def set(self, key, value):
+                cache[key] = value
+
+            def clear(self):
+                cache.clear()
+
+            self.get = types.MethodType(get, self)
+            self.set = types.MethodType(set, self)
+            self.clear = types.MethodType(clear, self)
+
+    if _OrderedDict is not None:
+        class _FifoCache(object):
+            def __init__(self, size):
+                self.not_in_cache = not_in_cache = object()
+
+                cache = _OrderedDict()
+
+                def get(self, key):
+                    return cache.get(key, not_in_cache)
+
+                def set(self, key, value):
+                    cache[key] = value
+                    if len(cache) > size:
+                        cache.popitem(False)
+
+                def clear(self):
+                    cache.clear()
+
+                self.get = types.MethodType(get, self)
+                self.set = types.MethodType(set, self)
+                self.clear = types.MethodType(clear, self)
+
+    else:
+        class _FifoCache(object):
+            def __init__(self, size):
+                self.not_in_cache = not_in_cache = object()
+
+                cache = {}
+                key_fifo = collections.deque([], size)
+
+                def get(self, key):
+                    return cache.get(key, not_in_cache)
+
+                def set(self, key, value):
+                    cache[key] = value
+                    if len(cache) > size:
+                        cache.pop(key_fifo.popleft(), None)
+                    key_fifo.append(key)
+
+                def clear(self):
+                    cache.clear()
+                    key_fifo.clear()
+
+                self.get = types.MethodType(get, self)
+                self.set = types.MethodType(set, self)
+                self.clear = types.MethodType(clear, self)
+
+    # argument cache for optimizing repeated calls when backtracking through recursive expressions
+    packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail
+    packrat_cache_lock = RLock()
+    packrat_cache_stats = [0, 0]
+
+    # this method gets repeatedly called during backtracking with the same arguments -
+    # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression
+    def _parseCache( self, instring, loc, doActions=True, callPreParse=True ):
+        HIT, MISS = 0, 1
+        lookup = (self, instring, loc, callPreParse, doActions)
+        with ParserElement.packrat_cache_lock:
+            cache = ParserElement.packrat_cache
+            value = cache.get(lookup)
+            if value is cache.not_in_cache:
+                ParserElement.packrat_cache_stats[MISS] += 1
+                try:
+                    value = self._parseNoCache(instring, loc, doActions, callPreParse)
+                except ParseBaseException as pe:
+                    # cache a copy of the exception, without the traceback
+                    cache.set(lookup, pe.__class__(*pe.args))
+                    raise
+                else:
+                    cache.set(lookup, (value[0], value[1].copy()))
+                    return value
+            else:
+                ParserElement.packrat_cache_stats[HIT] += 1
+                if isinstance(value, Exception):
+                    raise value
+                return (value[0], value[1].copy())
+
+    _parse = _parseNoCache
+
+    @staticmethod
+    def resetCache():
+        ParserElement.packrat_cache.clear()
+        ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats)
+
+    _packratEnabled = False
+    @staticmethod
+    def enablePackrat(cache_size_limit=128):
+        """Enables "packrat" parsing, which adds memoizing to the parsing logic.
+           Repeated parse attempts at the same string location (which happens
+           often in many complex grammars) can immediately return a cached value,
+           instead of re-executing parsing/validating code.  Memoizing is done of
+           both valid results and parsing exceptions.
+           
+           Parameters:
+            - cache_size_limit - (default=C{128}) - if an integer value is provided
+              will limit the size of the packrat cache; if None is passed, then
+              the cache size will be unbounded; if 0 is passed, the cache will
+              be effectively disabled.
+            
+           This speedup may break existing programs that use parse actions that
+           have side-effects.  For this reason, packrat parsing is disabled when
+           you first import pyparsing.  To activate the packrat feature, your
+           program must call the class method C{ParserElement.enablePackrat()}.  If
+           your program uses C{psyco} to "compile as you go", you must call
+           C{enablePackrat} before calling C{psyco.full()}.  If you do not do this,
+           Python will crash.  For best results, call C{enablePackrat()} immediately
+           after importing pyparsing.
+           
+           Example::
+               import pyparsing
+               pyparsing.ParserElement.enablePackrat()
+        """
+        if not ParserElement._packratEnabled:
+            ParserElement._packratEnabled = True
+            if cache_size_limit is None:
+                ParserElement.packrat_cache = ParserElement._UnboundedCache()
+            else:
+                ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit)
+            ParserElement._parse = ParserElement._parseCache
+
+    def parseString( self, instring, parseAll=False ):
+        """
+        Execute the parse expression with the given string.
+        This is the main interface to the client code, once the complete
+        expression has been built.
+
+        If you want the grammar to require that the entire input string be
+        successfully parsed, then set C{parseAll} to True (equivalent to ending
+        the grammar with C{L{StringEnd()}}).
+
+        Note: C{parseString} implicitly calls C{expandtabs()} on the input string,
+        in order to report proper column numbers in parse actions.
+        If the input string contains tabs and
+        the grammar uses parse actions that use the C{loc} argument to index into the
+        string being parsed, you can ensure you have a consistent view of the input
+        string by:
+         - calling C{parseWithTabs} on your grammar before calling C{parseString}
+           (see L{I{parseWithTabs}<parseWithTabs>})
+         - define your parse action using the full C{(s,loc,toks)} signature, and
+           reference the input string using the parse action's C{s} argument
+         - explictly expand the tabs in your input string before calling
+           C{parseString}
+        
+        Example::
+            Word('a').parseString('aaaaabaaa')  # -> ['aaaaa']
+            Word('a').parseString('aaaaabaaa', parseAll=True)  # -> Exception: Expected end of text
+        """
+        ParserElement.resetCache()
+        if not self.streamlined:
+            self.streamline()
+            #~ self.saveAsList = True
+        for e in self.ignoreExprs:
+            e.streamline()
+        if not self.keepTabs:
+            instring = instring.expandtabs()
+        try:
+            loc, tokens = self._parse( instring, 0 )
+            if parseAll:
+                loc = self.preParse( instring, loc )
+                se = Empty() + StringEnd()
+                se._parse( instring, loc )
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+        else:
+            return tokens
+
+    def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ):
+        """
+        Scan the input string for expression matches.  Each match will return the
+        matching tokens, start location, and end location.  May be called with optional
+        C{maxMatches} argument, to clip scanning after 'n' matches are found.  If
+        C{overlap} is specified, then overlapping matches will be reported.
+
+        Note that the start and end locations are reported relative to the string
+        being parsed.  See L{I{parseString}<parseString>} for more information on parsing
+        strings with embedded tabs.
+
+        Example::
+            source = "sldjf123lsdjjkf345sldkjf879lkjsfd987"
+            print(source)
+            for tokens,start,end in Word(alphas).scanString(source):
+                print(' '*start + '^'*(end-start))
+                print(' '*start + tokens[0])
+        
+        prints::
+        
+            sldjf123lsdjjkf345sldkjf879lkjsfd987
+            ^^^^^
+            sldjf
+                    ^^^^^^^
+                    lsdjjkf
+                              ^^^^^^
+                              sldkjf
+                                       ^^^^^^
+                                       lkjsfd
+        """
+        if not self.streamlined:
+            self.streamline()
+        for e in self.ignoreExprs:
+            e.streamline()
+
+        if not self.keepTabs:
+            instring = _ustr(instring).expandtabs()
+        instrlen = len(instring)
+        loc = 0
+        preparseFn = self.preParse
+        parseFn = self._parse
+        ParserElement.resetCache()
+        matches = 0
+        try:
+            while loc <= instrlen and matches < maxMatches:
+                try:
+                    preloc = preparseFn( instring, loc )
+                    nextLoc,tokens = parseFn( instring, preloc, callPreParse=False )
+                except ParseException:
+                    loc = preloc+1
+                else:
+                    if nextLoc > loc:
+                        matches += 1
+                        yield tokens, preloc, nextLoc
+                        if overlap:
+                            nextloc = preparseFn( instring, loc )
+                            if nextloc > loc:
+                                loc = nextLoc
+                            else:
+                                loc += 1
+                        else:
+                            loc = nextLoc
+                    else:
+                        loc = preloc+1
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def transformString( self, instring ):
+        """
+        Extension to C{L{scanString}}, to modify matching text with modified tokens that may
+        be returned from a parse action.  To use C{transformString}, define a grammar and
+        attach a parse action to it that modifies the returned token list.
+        Invoking C{transformString()} on a target string will then scan for matches,
+        and replace the matched text patterns according to the logic in the parse
+        action.  C{transformString()} returns the resulting transformed string.
+        
+        Example::
+            wd = Word(alphas)
+            wd.setParseAction(lambda toks: toks[0].title())
+            
+            print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york."))
+        Prints::
+            Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York.
+        """
+        out = []
+        lastE = 0
+        # force preservation of <TAB>s, to minimize unwanted transformation of string, and to
+        # keep string locs straight between transformString and scanString
+        self.keepTabs = True
+        try:
+            for t,s,e in self.scanString( instring ):
+                out.append( instring[lastE:s] )
+                if t:
+                    if isinstance(t,ParseResults):
+                        out += t.asList()
+                    elif isinstance(t,list):
+                        out += t
+                    else:
+                        out.append(t)
+                lastE = e
+            out.append(instring[lastE:])
+            out = [o for o in out if o]
+            return "".join(map(_ustr,_flatten(out)))
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def searchString( self, instring, maxMatches=_MAX_INT ):
+        """
+        Another extension to C{L{scanString}}, simplifying the access to the tokens found
+        to match the given parse expression.  May be called with optional
+        C{maxMatches} argument, to clip searching after 'n' matches are found.
+        
+        Example::
+            # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters
+            cap_word = Word(alphas.upper(), alphas.lower())
+            
+            print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))
+        prints::
+            ['More', 'Iron', 'Lead', 'Gold', 'I']
+        """
+        try:
+            return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ])
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False):
+        """
+        Generator method to split a string using the given expression as a separator.
+        May be called with optional C{maxsplit} argument, to limit the number of splits;
+        and the optional C{includeSeparators} argument (default=C{False}), if the separating
+        matching text should be included in the split results.
+        
+        Example::        
+            punc = oneOf(list(".,;:/-!?"))
+            print(list(punc.split("This, this?, this sentence, is badly punctuated!")))
+        prints::
+            ['This', ' this', '', ' this sentence', ' is badly punctuated', '']
+        """
+        splits = 0
+        last = 0
+        for t,s,e in self.scanString(instring, maxMatches=maxsplit):
+            yield instring[last:s]
+            if includeSeparators:
+                yield t[0]
+            last = e
+        yield instring[last:]
+
+    def __add__(self, other ):
+        """
+        Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement
+        converts them to L{Literal}s by default.
+        
+        Example::
+            greet = Word(alphas) + "," + Word(alphas) + "!"
+            hello = "Hello, World!"
+            print (hello, "->", greet.parseString(hello))
+        Prints::
+            Hello, World! -> ['Hello', ',', 'World', '!']
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return And( [ self, other ] )
+
+    def __radd__(self, other ):
+        """
+        Implementation of + operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other + self
+
+    def __sub__(self, other):
+        """
+        Implementation of - operator, returns C{L{And}} with error stop
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return And( [ self, And._ErrorStop(), other ] )
+
+    def __rsub__(self, other ):
+        """
+        Implementation of - operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other - self
+
+    def __mul__(self,other):
+        """
+        Implementation of * operator, allows use of C{expr * 3} in place of
+        C{expr + expr + expr}.  Expressions may also me multiplied by a 2-integer
+        tuple, similar to C{{min,max}} multipliers in regular expressions.  Tuples
+        may also include C{None} as in:
+         - C{expr*(n,None)} or C{expr*(n,)} is equivalent
+              to C{expr*n + L{ZeroOrMore}(expr)}
+              (read as "at least n instances of C{expr}")
+         - C{expr*(None,n)} is equivalent to C{expr*(0,n)}
+              (read as "0 to n instances of C{expr}")
+         - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)}
+         - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)}
+
+        Note that C{expr*(None,n)} does not raise an exception if
+        more than n exprs exist in the input stream; that is,
+        C{expr*(None,n)} does not enforce a maximum number of expr
+        occurrences.  If this behavior is desired, then write
+        C{expr*(None,n) + ~expr}
+        """
+        if isinstance(other,int):
+            minElements, optElements = other,0
+        elif isinstance(other,tuple):
+            other = (other + (None, None))[:2]
+            if other[0] is None:
+                other = (0, other[1])
+            if isinstance(other[0],int) and other[1] is None:
+                if other[0] == 0:
+                    return ZeroOrMore(self)
+                if other[0] == 1:
+                    return OneOrMore(self)
+                else:
+                    return self*other[0] + ZeroOrMore(self)
+            elif isinstance(other[0],int) and isinstance(other[1],int):
+                minElements, optElements = other
+                optElements -= minElements
+            else:
+                raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1]))
+        else:
+            raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other))
+
+        if minElements < 0:
+            raise ValueError("cannot multiply ParserElement by negative value")
+        if optElements < 0:
+            raise ValueError("second tuple value must be greater or equal to first tuple value")
+        if minElements == optElements == 0:
+            raise ValueError("cannot multiply ParserElement by 0 or (0,0)")
+
+        if (optElements):
+            def makeOptionalList(n):
+                if n>1:
+                    return Optional(self + makeOptionalList(n-1))
+                else:
+                    return Optional(self)
+            if minElements:
+                if minElements == 1:
+                    ret = self + makeOptionalList(optElements)
+                else:
+                    ret = And([self]*minElements) + makeOptionalList(optElements)
+            else:
+                ret = makeOptionalList(optElements)
+        else:
+            if minElements == 1:
+                ret = self
+            else:
+                ret = And([self]*minElements)
+        return ret
+
+    def __rmul__(self, other):
+        return self.__mul__(other)
+
+    def __or__(self, other ):
+        """
+        Implementation of | operator - returns C{L{MatchFirst}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return MatchFirst( [ self, other ] )
+
+    def __ror__(self, other ):
+        """
+        Implementation of | operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other | self
+
+    def __xor__(self, other ):
+        """
+        Implementation of ^ operator - returns C{L{Or}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return Or( [ self, other ] )
+
+    def __rxor__(self, other ):
+        """
+        Implementation of ^ operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other ^ self
+
+    def __and__(self, other ):
+        """
+        Implementation of & operator - returns C{L{Each}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return Each( [ self, other ] )
+
+    def __rand__(self, other ):
+        """
+        Implementation of & operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other & self
+
+    def __invert__( self ):
+        """
+        Implementation of ~ operator - returns C{L{NotAny}}
+        """
+        return NotAny( self )
+
+    def __call__(self, name=None):
+        """
+        Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}.
+        
+        If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be
+        passed as C{True}.
+           
+        If C{name} is omitted, same as calling C{L{copy}}.
+
+        Example::
+            # these are equivalent
+            userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno")
+            userdata = Word(alphas)("name") + Word(nums+"-")("socsecno")             
+        """
+        if name is not None:
+            return self.setResultsName(name)
+        else:
+            return self.copy()
+
+    def suppress( self ):
+        """
+        Suppresses the output of this C{ParserElement}; useful to keep punctuation from
+        cluttering up returned output.
+        """
+        return Suppress( self )
+
+    def leaveWhitespace( self ):
+        """
+        Disables the skipping of whitespace before matching the characters in the
+        C{ParserElement}'s defined pattern.  This is normally only used internally by
+        the pyparsing module, but may be needed in some whitespace-sensitive grammars.
+        """
+        self.skipWhitespace = False
+        return self
+
+    def setWhitespaceChars( self, chars ):
+        """
+        Overrides the default whitespace chars
+        """
+        self.skipWhitespace = True
+        self.whiteChars = chars
+        self.copyDefaultWhiteChars = False
+        return self
+
+    def parseWithTabs( self ):
+        """
+        Overrides default behavior to expand C{<TAB>}s to spaces before parsing the input string.
+        Must be called before C{parseString} when the input grammar contains elements that
+        match C{<TAB>} characters.
+        """
+        self.keepTabs = True
+        return self
+
+    def ignore( self, other ):
+        """
+        Define expression to be ignored (e.g., comments) while doing pattern
+        matching; may be called repeatedly, to define multiple comment or other
+        ignorable patterns.
+        
+        Example::
+            patt = OneOrMore(Word(alphas))
+            patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj']
+            
+            patt.ignore(cStyleComment)
+            patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd']
+        """
+        if isinstance(other, basestring):
+            other = Suppress(other)
+
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                self.ignoreExprs.append(other)
+        else:
+            self.ignoreExprs.append( Suppress( other.copy() ) )
+        return self
+
+    def setDebugActions( self, startAction, successAction, exceptionAction ):
+        """
+        Enable display of debugging messages while doing pattern matching.
+        """
+        self.debugActions = (startAction or _defaultStartDebugAction,
+                             successAction or _defaultSuccessDebugAction,
+                             exceptionAction or _defaultExceptionDebugAction)
+        self.debug = True
+        return self
+
+    def setDebug( self, flag=True ):
+        """
+        Enable display of debugging messages while doing pattern matching.
+        Set C{flag} to True to enable, False to disable.
+
+        Example::
+            wd = Word(alphas).setName("alphaword")
+            integer = Word(nums).setName("numword")
+            term = wd | integer
+            
+            # turn on debugging for wd
+            wd.setDebug()
+
+            OneOrMore(term).parseString("abc 123 xyz 890")
+        
+        prints::
+            Match alphaword at loc 0(1,1)
+            Matched alphaword -> ['abc']
+            Match alphaword at loc 3(1,4)
+            Exception raised:Expected alphaword (at char 4), (line:1, col:5)
+            Match alphaword at loc 7(1,8)
+            Matched alphaword -> ['xyz']
+            Match alphaword at loc 11(1,12)
+            Exception raised:Expected alphaword (at char 12), (line:1, col:13)
+            Match alphaword at loc 15(1,16)
+            Exception raised:Expected alphaword (at char 15), (line:1, col:16)
+
+        The output shown is that produced by the default debug actions - custom debug actions can be
+        specified using L{setDebugActions}. Prior to attempting
+        to match the C{wd} expression, the debugging message C{"Match <exprname> at loc <n>(<line>,<col>)"}
+        is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"}
+        message is shown. Also note the use of L{setName} to assign a human-readable name to the expression,
+        which makes debugging and exception messages easier to understand - for instance, the default
+        name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}.
+        """
+        if flag:
+            self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction )
+        else:
+            self.debug = False
+        return self
+
+    def __str__( self ):
+        return self.name
+
+    def __repr__( self ):
+        return _ustr(self)
+
+    def streamline( self ):
+        self.streamlined = True
+        self.strRepr = None
+        return self
+
+    def checkRecursion( self, parseElementList ):
+        pass
+
+    def validate( self, validateTrace=[] ):
+        """
+        Check defined expressions for valid structure, check for infinite recursive definitions.
+        """
+        self.checkRecursion( [] )
+
+    def parseFile( self, file_or_filename, parseAll=False ):
+        """
+        Execute the parse expression on the given file or filename.
+        If a filename is specified (instead of a file object),
+        the entire file is opened, read, and closed before parsing.
+        """
+        try:
+            file_contents = file_or_filename.read()
+        except AttributeError:
+            with open(file_or_filename, "r") as f:
+                file_contents = f.read()
+        try:
+            return self.parseString(file_contents, parseAll)
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def __eq__(self,other):
+        if isinstance(other, ParserElement):
+            return self is other or vars(self) == vars(other)
+        elif isinstance(other, basestring):
+            return self.matches(other)
+        else:
+            return super(ParserElement,self)==other
+
+    def __ne__(self,other):
+        return not (self == other)
+
+    def __hash__(self):
+        return hash(id(self))
+
+    def __req__(self,other):
+        return self == other
+
+    def __rne__(self,other):
+        return not (self == other)
+
+    def matches(self, testString, parseAll=True):
+        """
+        Method for quick testing of a parser against a test string. Good for simple 
+        inline microtests of sub expressions while building up larger parser.
+           
+        Parameters:
+         - testString - to test against this expression for a match
+         - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests
+            
+        Example::
+            expr = Word(nums)
+            assert expr.matches("100")
+        """
+        try:
+            self.parseString(_ustr(testString), parseAll=parseAll)
+            return True
+        except ParseBaseException:
+            return False
+                
+    def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False):
+        """
+        Execute the parse expression on a series of test strings, showing each
+        test, the parsed results or where the parse failed. Quick and easy way to
+        run a parse expression against a list of sample strings.
+           
+        Parameters:
+         - tests - a list of separate test strings, or a multiline string of test strings
+         - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests           
+         - comment - (default=C{'#'}) - expression for indicating embedded comments in the test 
+              string; pass None to disable comment filtering
+         - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline;
+              if False, only dump nested list
+         - printResults - (default=C{True}) prints test output to stdout
+         - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing
+
+        Returns: a (success, results) tuple, where success indicates that all tests succeeded
+        (or failed if C{failureTests} is True), and the results contain a list of lines of each 
+        test's output
+        
+        Example::
+            number_expr = pyparsing_common.number.copy()
+
+            result = number_expr.runTests('''
+                # unsigned integer
+                100
+                # negative integer
+                -100
+                # float with scientific notation
+                6.02e23
+                # integer with scientific notation
+                1e-12
+                ''')
+            print("Success" if result[0] else "Failed!")
+
+            result = number_expr.runTests('''
+                # stray character
+                100Z
+                # missing leading digit before '.'
+                -.100
+                # too many '.'
+                3.14.159
+                ''', failureTests=True)
+            print("Success" if result[0] else "Failed!")
+        prints::
+            # unsigned integer
+            100
+            [100]
+
+            # negative integer
+            -100
+            [-100]
+
+            # float with scientific notation
+            6.02e23
+            [6.02e+23]
+
+            # integer with scientific notation
+            1e-12
+            [1e-12]
+
+            Success
+            
+            # stray character
+            100Z
+               ^
+            FAIL: Expected end of text (at char 3), (line:1, col:4)
+
+            # missing leading digit before '.'
+            -.100
+            ^
+            FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1)
+
+            # too many '.'
+            3.14.159
+                ^
+            FAIL: Expected end of text (at char 4), (line:1, col:5)
+
+            Success
+
+        Each test string must be on a single line. If you want to test a string that spans multiple
+        lines, create a test like this::
+
+            expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines")
+        
+        (Note that this is a raw string literal, you must include the leading 'r'.)
+        """
+        if isinstance(tests, basestring):
+            tests = list(map(str.strip, tests.rstrip().splitlines()))
+        if isinstance(comment, basestring):
+            comment = Literal(comment)
+        allResults = []
+        comments = []
+        success = True
+        for t in tests:
+            if comment is not None and comment.matches(t, False) or comments and not t:
+                comments.append(t)
+                continue
+            if not t:
+                continue
+            out = ['\n'.join(comments), t]
+            comments = []
+            try:
+                t = t.replace(r'\n','\n')
+                result = self.parseString(t, parseAll=parseAll)
+                out.append(result.dump(full=fullDump))
+                success = success and not failureTests
+            except ParseBaseException as pe:
+                fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else ""
+                if '\n' in t:
+                    out.append(line(pe.loc, t))
+                    out.append(' '*(col(pe.loc,t)-1) + '^' + fatal)
+                else:
+                    out.append(' '*pe.loc + '^' + fatal)
+                out.append("FAIL: " + str(pe))
+                success = success and failureTests
+                result = pe
+            except Exception as exc:
+                out.append("FAIL-EXCEPTION: " + str(exc))
+                success = success and failureTests
+                result = exc
+
+            if printResults:
+                if fullDump:
+                    out.append('')
+                print('\n'.join(out))
+
+            allResults.append((t, result))
+        
+        return success, allResults
+
+        
+class Token(ParserElement):
+    """
+    Abstract C{ParserElement} subclass, for defining atomic matching patterns.
+    """
+    def __init__( self ):
+        super(Token,self).__init__( savelist=False )
+
+
+class Empty(Token):
+    """
+    An empty token, will always match.
+    """
+    def __init__( self ):
+        super(Empty,self).__init__()
+        self.name = "Empty"
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+
+
+class NoMatch(Token):
+    """
+    A token that will never match.
+    """
+    def __init__( self ):
+        super(NoMatch,self).__init__()
+        self.name = "NoMatch"
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+        self.errmsg = "Unmatchable token"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        raise ParseException(instring, loc, self.errmsg, self)
+
+
+class Literal(Token):
+    """
+    Token to exactly match a specified string.
+    
+    Example::
+        Literal('blah').parseString('blah')  # -> ['blah']
+        Literal('blah').parseString('blahfooblah')  # -> ['blah']
+        Literal('blah').parseString('bla')  # -> Exception: Expected "blah"
+    
+    For case-insensitive matching, use L{CaselessLiteral}.
+    
+    For keyword matching (force word break before and after the matched string),
+    use L{Keyword} or L{CaselessKeyword}.
+    """
+    def __init__( self, matchString ):
+        super(Literal,self).__init__()
+        self.match = matchString
+        self.matchLen = len(matchString)
+        try:
+            self.firstMatchChar = matchString[0]
+        except IndexError:
+            warnings.warn("null string passed to Literal; use Empty() instead",
+                            SyntaxWarning, stacklevel=2)
+            self.__class__ = Empty
+        self.name = '"%s"' % _ustr(self.match)
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = False
+        self.mayIndexError = False
+
+    # Performance tuning: this routine gets called a *lot*
+    # if this is a single character match string  and the first character matches,
+    # short-circuit as quickly as possible, and avoid calling startswith
+    #~ @profile
+    def parseImpl( self, instring, loc, doActions=True ):
+        if (instring[loc] == self.firstMatchChar and
+            (self.matchLen==1 or instring.startswith(self.match,loc)) ):
+            return loc+self.matchLen, self.match
+        raise ParseException(instring, loc, self.errmsg, self)
+_L = Literal
+ParserElement._literalStringClass = Literal
+
+class Keyword(Token):
+    """
+    Token to exactly match a specified string as a keyword, that is, it must be
+    immediately followed by a non-keyword character.  Compare with C{L{Literal}}:
+     - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}.
+     - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'}
+    Accepts two optional constructor arguments in addition to the keyword string:
+     - C{identChars} is a string of characters that would be valid identifier characters,
+          defaulting to all alphanumerics + "_" and "$"
+     - C{caseless} allows case-insensitive matching, default is C{False}.
+       
+    Example::
+        Keyword("start").parseString("start")  # -> ['start']
+        Keyword("start").parseString("starting")  # -> Exception
+
+    For case-insensitive matching, use L{CaselessKeyword}.
+    """
+    DEFAULT_KEYWORD_CHARS = alphanums+"_$"
+
+    def __init__( self, matchString, identChars=None, caseless=False ):
+        super(Keyword,self).__init__()
+        if identChars is None:
+            identChars = Keyword.DEFAULT_KEYWORD_CHARS
+        self.match = matchString
+        self.matchLen = len(matchString)
+        try:
+            self.firstMatchChar = matchString[0]
+        except IndexError:
+            warnings.warn("null string passed to Keyword; use Empty() instead",
+                            SyntaxWarning, stacklevel=2)
+        self.name = '"%s"' % self.match
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = False
+        self.mayIndexError = False
+        self.caseless = caseless
+        if caseless:
+            self.caselessmatch = matchString.upper()
+            identChars = identChars.upper()
+        self.identChars = set(identChars)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.caseless:
+            if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
+                 (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and
+                 (loc == 0 or instring[loc-1].upper() not in self.identChars) ):
+                return loc+self.matchLen, self.match
+        else:
+            if (instring[loc] == self.firstMatchChar and
+                (self.matchLen==1 or instring.startswith(self.match,loc)) and
+                (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and
+                (loc == 0 or instring[loc-1] not in self.identChars) ):
+                return loc+self.matchLen, self.match
+        raise ParseException(instring, loc, self.errmsg, self)
+
+    def copy(self):
+        c = super(Keyword,self).copy()
+        c.identChars = Keyword.DEFAULT_KEYWORD_CHARS
+        return c
+
+    @staticmethod
+    def setDefaultKeywordChars( chars ):
+        """Overrides the default Keyword chars
+        """
+        Keyword.DEFAULT_KEYWORD_CHARS = chars
+
+class CaselessLiteral(Literal):
+    """
+    Token to match a specified string, ignoring case of letters.
+    Note: the matched results will always be in the case of the given
+    match string, NOT the case of the input text.
+
+    Example::
+        OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD']
+        
+    (Contrast with example for L{CaselessKeyword}.)
+    """
+    def __init__( self, matchString ):
+        super(CaselessLiteral,self).__init__( matchString.upper() )
+        # Preserve the defining literal.
+        self.returnString = matchString
+        self.name = "'%s'" % self.returnString
+        self.errmsg = "Expected " + self.name
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if instring[ loc:loc+self.matchLen ].upper() == self.match:
+            return loc+self.matchLen, self.returnString
+        raise ParseException(instring, loc, self.errmsg, self)
+
+class CaselessKeyword(Keyword):
+    """
+    Caseless version of L{Keyword}.
+
+    Example::
+        OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD']
+        
+    (Contrast with example for L{CaselessLiteral}.)
+    """
+    def __init__( self, matchString, identChars=None ):
+        super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True )
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
+             (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ):
+            return loc+self.matchLen, self.match
+        raise ParseException(instring, loc, self.errmsg, self)
+
+class CloseMatch(Token):
+    """
+    A variation on L{Literal} which matches "close" matches, that is, 
+    strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters:
+     - C{match_string} - string to be matched
+     - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match
+    
+    The results from a successful parse will contain the matched text from the input string and the following named results:
+     - C{mismatches} - a list of the positions within the match_string where mismatches were found
+     - C{original} - the original match_string used to compare against the input string
+    
+    If C{mismatches} is an empty list, then the match was an exact match.
+    
+    Example::
+        patt = CloseMatch("ATCATCGAATGGA")
+        patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']})
+        patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1)
+
+        # exact match
+        patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']})
+
+        # close match allowing up to 2 mismatches
+        patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2)
+        patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']})
+    """
+    def __init__(self, match_string, maxMismatches=1):
+        super(CloseMatch,self).__init__()
+        self.name = match_string
+        self.match_string = match_string
+        self.maxMismatches = maxMismatches
+        self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches)
+        self.mayIndexError = False
+        self.mayReturnEmpty = False
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        start = loc
+        instrlen = len(instring)
+        maxloc = start + len(self.match_string)
+
+        if maxloc <= instrlen:
+            match_string = self.match_string
+            match_stringloc = 0
+            mismatches = []
+            maxMismatches = self.maxMismatches
+
+            for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)):
+                src,mat = s_m
+                if src != mat:
+                    mismatches.append(match_stringloc)
+                    if len(mismatches) > maxMismatches:
+                        break
+            else:
+                loc = match_stringloc + 1
+                results = ParseResults([instring[start:loc]])
+                results['original'] = self.match_string
+                results['mismatches'] = mismatches
+                return loc, results
+
+        raise ParseException(instring, loc, self.errmsg, self)
+
+
+class Word(Token):
+    """
+    Token for matching words composed of allowed character sets.
+    Defined with string containing all allowed initial characters,
+    an optional string containing allowed body characters (if omitted,
+    defaults to the initial character set), and an optional minimum,
+    maximum, and/or exact length.  The default value for C{min} is 1 (a
+    minimum value < 1 is not valid); the default values for C{max} and C{exact}
+    are 0, meaning no maximum or exact length restriction. An optional
+    C{excludeChars} parameter can list characters that might be found in 
+    the input C{bodyChars} string; useful to define a word of all printables
+    except for one or two characters, for instance.
+    
+    L{srange} is useful for defining custom character set strings for defining 
+    C{Word} expressions, using range notation from regular expression character sets.
+    
+    A common mistake is to use C{Word} to match a specific literal string, as in 
+    C{Word("Address")}. Remember that C{Word} uses the string argument to define
+    I{sets} of matchable characters. This expression would match "Add", "AAA",
+    "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'.
+    To match an exact literal string, use L{Literal} or L{Keyword}.
+
+    pyparsing includes helper strings for building Words:
+     - L{alphas}
+     - L{nums}
+     - L{alphanums}
+     - L{hexnums}
+     - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.)
+     - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.)
+     - L{printables} (any non-whitespace character)
+
+    Example::
+        # a word composed of digits
+        integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9"))
+        
+        # a word with a leading capital, and zero or more lowercase
+        capital_word = Word(alphas.upper(), alphas.lower())
+
+        # hostnames are alphanumeric, with leading alpha, and '-'
+        hostname = Word(alphas, alphanums+'-')
+        
+        # roman numeral (not a strict parser, accepts invalid mix of characters)
+        roman = Word("IVXLCDM")
+        
+        # any string of non-whitespace characters, except for ','
+        csv_value = Word(printables, excludeChars=",")
+    """
+    def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ):
+        super(Word,self).__init__()
+        if excludeChars:
+            initChars = ''.join(c for c in initChars if c not in excludeChars)
+            if bodyChars:
+                bodyChars = ''.join(c for c in bodyChars if c not in excludeChars)
+        self.initCharsOrig = initChars
+        self.initChars = set(initChars)
+        if bodyChars :
+            self.bodyCharsOrig = bodyChars
+            self.bodyChars = set(bodyChars)
+        else:
+            self.bodyCharsOrig = initChars
+            self.bodyChars = set(initChars)
+
+        self.maxSpecified = max > 0
+
+        if min < 1:
+            raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted")
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayIndexError = False
+        self.asKeyword = asKeyword
+
+        if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0):
+            if self.bodyCharsOrig == self.initCharsOrig:
+                self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig)
+            elif len(self.initCharsOrig) == 1:
+                self.reString = "%s[%s]*" % \
+                                      (re.escape(self.initCharsOrig),
+                                      _escapeRegexRangeChars(self.bodyCharsOrig),)
+            else:
+                self.reString = "[%s][%s]*" % \
+                                      (_escapeRegexRangeChars(self.initCharsOrig),
+                                      _escapeRegexRangeChars(self.bodyCharsOrig),)
+            if self.asKeyword:
+                self.reString = r"\b"+self.reString+r"\b"
+            try:
+                self.re = re.compile( self.reString )
+            except Exception:
+                self.re = None
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.re:
+            result = self.re.match(instring,loc)
+            if not result:
+                raise ParseException(instring, loc, self.errmsg, self)
+
+            loc = result.end()
+            return loc, result.group()
+
+        if not(instring[ loc ] in self.initChars):
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        start = loc
+        loc += 1
+        instrlen = len(instring)
+        bodychars = self.bodyChars
+        maxloc = start + self.maxLen
+        maxloc = min( maxloc, instrlen )
+        while loc < maxloc and instring[loc] in bodychars:
+            loc += 1
+
+        throwException = False
+        if loc - start < self.minLen:
+            throwException = True
+        if self.maxSpecified and loc < instrlen and instring[loc] in bodychars:
+            throwException = True
+        if self.asKeyword:
+            if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars):
+                throwException = True
+
+        if throwException:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        return loc, instring[start:loc]
+
+    def __str__( self ):
+        try:
+            return super(Word,self).__str__()
+        except Exception:
+            pass
+
+
+        if self.strRepr is None:
+
+            def charsAsStr(s):
+                if len(s)>4:
+                    return s[:4]+"..."
+                else:
+                    return s
+
+            if ( self.initCharsOrig != self.bodyCharsOrig ):
+                self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) )
+            else:
+                self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig)
+
+        return self.strRepr
+
+
+class Regex(Token):
+    """
+    Token for matching strings that match a given regular expression.
+    Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module.
+    If the given regex contains named groups (defined using C{(?P<name>...)}), these will be preserved as 
+    named parse results.
+
+    Example::
+        realnum = Regex(r"[+-]?\d+\.\d*")
+        date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)')
+        # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression
+        roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})")
+    """
+    compiledREtype = type(re.compile("[A-Z]"))
+    def __init__( self, pattern, flags=0):
+        """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags."""
+        super(Regex,self).__init__()
+
+        if isinstance(pattern, basestring):
+            if not pattern:
+                warnings.warn("null string passed to Regex; use Empty() instead",
+                        SyntaxWarning, stacklevel=2)
+
+            self.pattern = pattern
+            self.flags = flags
+
+            try:
+                self.re = re.compile(self.pattern, self.flags)
+                self.reString = self.pattern
+            except sre_constants.error:
+                warnings.warn("invalid pattern (%s) passed to Regex" % pattern,
+                    SyntaxWarning, stacklevel=2)
+                raise
+
+        elif isinstance(pattern, Regex.compiledREtype):
+            self.re = pattern
+            self.pattern = \
+            self.reString = str(pattern)
+            self.flags = flags
+            
+        else:
+            raise ValueError("Regex may only be constructed with a string or a compiled RE object")
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayIndexError = False
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        result = self.re.match(instring,loc)
+        if not result:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        loc = result.end()
+        d = result.groupdict()
+        ret = ParseResults(result.group())
+        if d:
+            for k in d:
+                ret[k] = d[k]
+        return loc,ret
+
+    def __str__( self ):
+        try:
+            return super(Regex,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "Re:(%s)" % repr(self.pattern)
+
+        return self.strRepr
+
+
+class QuotedString(Token):
+    r"""
+    Token for matching strings that are delimited by quoting characters.
+    
+    Defined with the following parameters:
+        - quoteChar - string of one or more characters defining the quote delimiting string
+        - escChar - character to escape quotes, typically backslash (default=C{None})
+        - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None})
+        - multiline - boolean indicating whether quotes can span multiple lines (default=C{False})
+        - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True})
+        - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar)
+        - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True})
+
+    Example::
+        qs = QuotedString('"')
+        print(qs.searchString('lsjdf "This is the quote" sldjf'))
+        complex_qs = QuotedString('{{', endQuoteChar='}}')
+        print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf'))
+        sql_qs = QuotedString('"', escQuote='""')
+        print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf'))
+    prints::
+        [['This is the quote']]
+        [['This is the "quote"']]
+        [['This is the quote with "embedded" quotes']]
+    """
+    def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True):
+        super(QuotedString,self).__init__()
+
+        # remove white space from quote chars - wont work anyway
+        quoteChar = quoteChar.strip()
+        if not quoteChar:
+            warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
+            raise SyntaxError()
+
+        if endQuoteChar is None:
+            endQuoteChar = quoteChar
+        else:
+            endQuoteChar = endQuoteChar.strip()
+            if not endQuoteChar:
+                warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
+                raise SyntaxError()
+
+        self.quoteChar = quoteChar
+        self.quoteCharLen = len(quoteChar)
+        self.firstQuoteChar = quoteChar[0]
+        self.endQuoteChar = endQuoteChar
+        self.endQuoteCharLen = len(endQuoteChar)
+        self.escChar = escChar
+        self.escQuote = escQuote
+        self.unquoteResults = unquoteResults
+        self.convertWhitespaceEscapes = convertWhitespaceEscapes
+
+        if multiline:
+            self.flags = re.MULTILINE | re.DOTALL
+            self.pattern = r'%s(?:[^%s%s]' % \
+                ( re.escape(self.quoteChar),
+                  _escapeRegexRangeChars(self.endQuoteChar[0]),
+                  (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
+        else:
+            self.flags = 0
+            self.pattern = r'%s(?:[^%s\n\r%s]' % \
+                ( re.escape(self.quoteChar),
+                  _escapeRegexRangeChars(self.endQuoteChar[0]),
+                  (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
+        if len(self.endQuoteChar) > 1:
+            self.pattern += (
+                '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]),
+                                               _escapeRegexRangeChars(self.endQuoteChar[i]))
+                                    for i in range(len(self.endQuoteChar)-1,0,-1)) + ')'
+                )
+        if escQuote:
+            self.pattern += (r'|(?:%s)' % re.escape(escQuote))
+        if escChar:
+            self.pattern += (r'|(?:%s.)' % re.escape(escChar))
+            self.escCharReplacePattern = re.escape(self.escChar)+"(.)"
+        self.pattern += (r')*%s' % re.escape(self.endQuoteChar))
+
+        try:
+            self.re = re.compile(self.pattern, self.flags)
+            self.reString = self.pattern
+        except sre_constants.error:
+            warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern,
+                SyntaxWarning, stacklevel=2)
+            raise
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayIndexError = False
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None
+        if not result:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        loc = result.end()
+        ret = result.group()
+
+        if self.unquoteResults:
+
+            # strip off quotes
+            ret = ret[self.quoteCharLen:-self.endQuoteCharLen]
+
+            if isinstance(ret,basestring):
+                # replace escaped whitespace
+                if '\\' in ret and self.convertWhitespaceEscapes:
+                    ws_map = {
+                        r'\t' : '\t',
+                        r'\n' : '\n',
+                        r'\f' : '\f',
+                        r'\r' : '\r',
+                    }
+                    for wslit,wschar in ws_map.items():
+                        ret = ret.replace(wslit, wschar)
+
+                # replace escaped characters
+                if self.escChar:
+                    ret = re.sub(self.escCharReplacePattern,"\g<1>",ret)
+
+                # replace escaped quotes
+                if self.escQuote:
+                    ret = ret.replace(self.escQuote, self.endQuoteChar)
+
+        return loc, ret
+
+    def __str__( self ):
+        try:
+            return super(QuotedString,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar)
+
+        return self.strRepr
+
+
+class CharsNotIn(Token):
+    """
+    Token for matching words composed of characters I{not} in a given set (will
+    include whitespace in matched characters if not listed in the provided exclusion set - see example).
+    Defined with string containing all disallowed characters, and an optional
+    minimum, maximum, and/or exact length.  The default value for C{min} is 1 (a
+    minimum value < 1 is not valid); the default values for C{max} and C{exact}
+    are 0, meaning no maximum or exact length restriction.
+
+    Example::
+        # define a comma-separated-value as anything that is not a ','
+        csv_value = CharsNotIn(',')
+        print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213"))
+    prints::
+        ['dkls', 'lsdkjf', 's12 34', '@!#', '213']
+    """
+    def __init__( self, notChars, min=1, max=0, exact=0 ):
+        super(CharsNotIn,self).__init__()
+        self.skipWhitespace = False
+        self.notChars = notChars
+
+        if min < 1:
+            raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted")
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = ( self.minLen == 0 )
+        self.mayIndexError = False
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if instring[loc] in self.notChars:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        start = loc
+        loc += 1
+        notchars = self.notChars
+        maxlen = min( start+self.maxLen, len(instring) )
+        while loc < maxlen and \
+              (instring[loc] not in notchars):
+            loc += 1
+
+        if loc - start < self.minLen:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        return loc, instring[start:loc]
+
+    def __str__( self ):
+        try:
+            return super(CharsNotIn, self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            if len(self.notChars) > 4:
+                self.strRepr = "!W:(%s...)" % self.notChars[:4]
+            else:
+                self.strRepr = "!W:(%s)" % self.notChars
+
+        return self.strRepr
+
+class White(Token):
+    """
+    Special matching class for matching whitespace.  Normally, whitespace is ignored
+    by pyparsing grammars.  This class is included when some whitespace structures
+    are significant.  Define with a string containing the whitespace characters to be
+    matched; default is C{" \\t\\r\\n"}.  Also takes optional C{min}, C{max}, and C{exact} arguments,
+    as defined for the C{L{Word}} class.
+    """
+    whiteStrs = {
+        " " : "<SPC>",
+        "\t": "<TAB>",
+        "\n": "<LF>",
+        "\r": "<CR>",
+        "\f": "<FF>",
+        }
+    def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0):
+        super(White,self).__init__()
+        self.matchWhite = ws
+        self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) )
+        #~ self.leaveWhitespace()
+        self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite))
+        self.mayReturnEmpty = True
+        self.errmsg = "Expected " + self.name
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if not(instring[ loc ] in self.matchWhite):
+            raise ParseException(instring, loc, self.errmsg, self)
+        start = loc
+        loc += 1
+        maxloc = start + self.maxLen
+        maxloc = min( maxloc, len(instring) )
+        while loc < maxloc and instring[loc] in self.matchWhite:
+            loc += 1
+
+        if loc - start < self.minLen:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        return loc, instring[start:loc]
+
+
+class _PositionToken(Token):
+    def __init__( self ):
+        super(_PositionToken,self).__init__()
+        self.name=self.__class__.__name__
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+
+class GoToColumn(_PositionToken):
+    """
+    Token to advance to a specific column of input text; useful for tabular report scraping.
+    """
+    def __init__( self, colno ):
+        super(GoToColumn,self).__init__()
+        self.col = colno
+
+    def preParse( self, instring, loc ):
+        if col(loc,instring) != self.col:
+            instrlen = len(instring)
+            if self.ignoreExprs:
+                loc = self._skipIgnorables( instring, loc )
+            while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col :
+                loc += 1
+        return loc
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        thiscol = col( loc, instring )
+        if thiscol > self.col:
+            raise ParseException( instring, loc, "Text not in expected column", self )
+        newloc = loc + self.col - thiscol
+        ret = instring[ loc: newloc ]
+        return newloc, ret
+
+
+class LineStart(_PositionToken):
+    """
+    Matches if current position is at the beginning of a line within the parse string
+    
+    Example::
+    
+        test = '''\
+        AAA this line
+        AAA and this line
+          AAA but not this one
+        B AAA and definitely not this one
+        '''
+
+        for t in (LineStart() + 'AAA' + restOfLine).searchString(test):
+            print(t)
+    
+    Prints::
+        ['AAA', ' this line']
+        ['AAA', ' and this line']    
+
+    """
+    def __init__( self ):
+        super(LineStart,self).__init__()
+        self.errmsg = "Expected start of line"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if col(loc, instring) == 1:
+            return loc, []
+        raise ParseException(instring, loc, self.errmsg, self)
+
+class LineEnd(_PositionToken):
+    """
+    Matches if current position is at the end of a line within the parse string
+    """
+    def __init__( self ):
+        super(LineEnd,self).__init__()
+        self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") )
+        self.errmsg = "Expected end of line"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc<len(instring):
+            if instring[loc] == "\n":
+                return loc+1, "\n"
+            else:
+                raise ParseException(instring, loc, self.errmsg, self)
+        elif loc == len(instring):
+            return loc+1, []
+        else:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+class StringStart(_PositionToken):
+    """
+    Matches if current position is at the beginning of the parse string
+    """
+    def __init__( self ):
+        super(StringStart,self).__init__()
+        self.errmsg = "Expected start of text"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc != 0:
+            # see if entire string up to here is just whitespace and ignoreables
+            if loc != self.preParse( instring, 0 ):
+                raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+class StringEnd(_PositionToken):
+    """
+    Matches if current position is at the end of the parse string
+    """
+    def __init__( self ):
+        super(StringEnd,self).__init__()
+        self.errmsg = "Expected end of text"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc < len(instring):
+            raise ParseException(instring, loc, self.errmsg, self)
+        elif loc == len(instring):
+            return loc+1, []
+        elif loc > len(instring):
+            return loc, []
+        else:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+class WordStart(_PositionToken):
+    """
+    Matches if the current position is at the beginning of a Word, and
+    is not preceded by any character in a given set of C{wordChars}
+    (default=C{printables}). To emulate the C{\b} behavior of regular expressions,
+    use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of
+    the string being parsed, or at the beginning of a line.
+    """
+    def __init__(self, wordChars = printables):
+        super(WordStart,self).__init__()
+        self.wordChars = set(wordChars)
+        self.errmsg = "Not at the start of a word"
+
+    def parseImpl(self, instring, loc, doActions=True ):
+        if loc != 0:
+            if (instring[loc-1] in self.wordChars or
+                instring[loc] not in self.wordChars):
+                raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+class WordEnd(_PositionToken):
+    """
+    Matches if the current position is at the end of a Word, and
+    is not followed by any character in a given set of C{wordChars}
+    (default=C{printables}). To emulate the C{\b} behavior of regular expressions,
+    use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of
+    the string being parsed, or at the end of a line.
+    """
+    def __init__(self, wordChars = printables):
+        super(WordEnd,self).__init__()
+        self.wordChars = set(wordChars)
+        self.skipWhitespace = False
+        self.errmsg = "Not at the end of a word"
+
+    def parseImpl(self, instring, loc, doActions=True ):
+        instrlen = len(instring)
+        if instrlen>0 and loc<instrlen:
+            if (instring[loc] in self.wordChars or
+                instring[loc-1] not in self.wordChars):
+                raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+
+class ParseExpression(ParserElement):
+    """
+    Abstract subclass of ParserElement, for combining and post-processing parsed tokens.
+    """
+    def __init__( self, exprs, savelist = False ):
+        super(ParseExpression,self).__init__(savelist)
+        if isinstance( exprs, _generatorType ):
+            exprs = list(exprs)
+
+        if isinstance( exprs, basestring ):
+            self.exprs = [ ParserElement._literalStringClass( exprs ) ]
+        elif isinstance( exprs, collections.Iterable ):
+            exprs = list(exprs)
+            # if sequence of strings provided, wrap with Literal
+            if all(isinstance(expr, basestring) for expr in exprs):
+                exprs = map(ParserElement._literalStringClass, exprs)
+            self.exprs = list(exprs)
+        else:
+            try:
+                self.exprs = list( exprs )
+            except TypeError:
+                self.exprs = [ exprs ]
+        self.callPreparse = False
+
+    def __getitem__( self, i ):
+        return self.exprs[i]
+
+    def append( self, other ):
+        self.exprs.append( other )
+        self.strRepr = None
+        return self
+
+    def leaveWhitespace( self ):
+        """Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on
+           all contained expressions."""
+        self.skipWhitespace = False
+        self.exprs = [ e.copy() for e in self.exprs ]
+        for e in self.exprs:
+            e.leaveWhitespace()
+        return self
+
+    def ignore( self, other ):
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                super( ParseExpression, self).ignore( other )
+                for e in self.exprs:
+                    e.ignore( self.ignoreExprs[-1] )
+        else:
+            super( ParseExpression, self).ignore( other )
+            for e in self.exprs:
+                e.ignore( self.ignoreExprs[-1] )
+        return self
+
+    def __str__( self ):
+        try:
+            return super(ParseExpression,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) )
+        return self.strRepr
+
+    def streamline( self ):
+        super(ParseExpression,self).streamline()
+
+        for e in self.exprs:
+            e.streamline()
+
+        # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d )
+        # but only if there are no parse actions or resultsNames on the nested And's
+        # (likewise for Or's and MatchFirst's)
+        if ( len(self.exprs) == 2 ):
+            other = self.exprs[0]
+            if ( isinstance( other, self.__class__ ) and
+                  not(other.parseAction) and
+                  other.resultsName is None and
+                  not other.debug ):
+                self.exprs = other.exprs[:] + [ self.exprs[1] ]
+                self.strRepr = None
+                self.mayReturnEmpty |= other.mayReturnEmpty
+                self.mayIndexError  |= other.mayIndexError
+
+            other = self.exprs[-1]
+            if ( isinstance( other, self.__class__ ) and
+                  not(other.parseAction) and
+                  other.resultsName is None and
+                  not other.debug ):
+                self.exprs = self.exprs[:-1] + other.exprs[:]
+                self.strRepr = None
+                self.mayReturnEmpty |= other.mayReturnEmpty
+                self.mayIndexError  |= other.mayIndexError
+
+        self.errmsg = "Expected " + _ustr(self)
+        
+        return self
+
+    def setResultsName( self, name, listAllMatches=False ):
+        ret = super(ParseExpression,self).setResultsName(name,listAllMatches)
+        return ret
+
+    def validate( self, validateTrace=[] ):
+        tmp = validateTrace[:]+[self]
+        for e in self.exprs:
+            e.validate(tmp)
+        self.checkRecursion( [] )
+        
+    def copy(self):
+        ret = super(ParseExpression,self).copy()
+        ret.exprs = [e.copy() for e in self.exprs]
+        return ret
+
+class And(ParseExpression):
+    """
+    Requires all given C{ParseExpression}s to be found in the given order.
+    Expressions may be separated by whitespace.
+    May be constructed using the C{'+'} operator.
+    May also be constructed using the C{'-'} operator, which will suppress backtracking.
+
+    Example::
+        integer = Word(nums)
+        name_expr = OneOrMore(Word(alphas))
+
+        expr = And([integer("id"),name_expr("name"),integer("age")])
+        # more easily written as:
+        expr = integer("id") + name_expr("name") + integer("age")
+    """
+
+    class _ErrorStop(Empty):
+        def __init__(self, *args, **kwargs):
+            super(And._ErrorStop,self).__init__(*args, **kwargs)
+            self.name = '-'
+            self.leaveWhitespace()
+
+    def __init__( self, exprs, savelist = True ):
+        super(And,self).__init__(exprs, savelist)
+        self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
+        self.setWhitespaceChars( self.exprs[0].whiteChars )
+        self.skipWhitespace = self.exprs[0].skipWhitespace
+        self.callPreparse = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        # pass False as last arg to _parse for first element, since we already
+        # pre-parsed the string as part of our And pre-parsing
+        loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False )
+        errorStop = False
+        for e in self.exprs[1:]:
+            if isinstance(e, And._ErrorStop):
+                errorStop = True
+                continue
+            if errorStop:
+                try:
+                    loc, exprtokens = e._parse( instring, loc, doActions )
+                except ParseSyntaxException:
+                    raise
+                except ParseBaseException as pe:
+                    pe.__traceback__ = None
+                    raise ParseSyntaxException._from_exception(pe)
+                except IndexError:
+                    raise ParseSyntaxException(instring, len(instring), self.errmsg, self)
+            else:
+                loc, exprtokens = e._parse( instring, loc, doActions )
+            if exprtokens or exprtokens.haskeys():
+                resultlist += exprtokens
+        return loc, resultlist
+
+    def __iadd__(self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        return self.append( other ) #And( [ self, other ] )
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+            if not e.mayReturnEmpty:
+                break
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+
+class Or(ParseExpression):
+    """
+    Requires that at least one C{ParseExpression} is found.
+    If two expressions match, the expression that matches the longest string will be used.
+    May be constructed using the C{'^'} operator.
+
+    Example::
+        # construct Or using '^' operator
+        
+        number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums))
+        print(number.searchString("123 3.1416 789"))
+    prints::
+        [['123'], ['3.1416'], ['789']]
+    """
+    def __init__( self, exprs, savelist = False ):
+        super(Or,self).__init__(exprs, savelist)
+        if self.exprs:
+            self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs)
+        else:
+            self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        maxExcLoc = -1
+        maxException = None
+        matches = []
+        for e in self.exprs:
+            try:
+                loc2 = e.tryParse( instring, loc )
+            except ParseException as err:
+                err.__traceback__ = None
+                if err.loc > maxExcLoc:
+                    maxException = err
+                    maxExcLoc = err.loc
+            except IndexError:
+                if len(instring) > maxExcLoc:
+                    maxException = ParseException(instring,len(instring),e.errmsg,self)
+                    maxExcLoc = len(instring)
+            else:
+                # save match among all matches, to retry longest to shortest
+                matches.append((loc2, e))
+
+        if matches:
+            matches.sort(key=lambda x: -x[0])
+            for _,e in matches:
+                try:
+                    return e._parse( instring, loc, doActions )
+                except ParseException as err:
+                    err.__traceback__ = None
+                    if err.loc > maxExcLoc:
+                        maxException = err
+                        maxExcLoc = err.loc
+
+        if maxException is not None:
+            maxException.msg = self.errmsg
+            raise maxException
+        else:
+            raise ParseException(instring, loc, "no defined alternatives to match", self)
+
+
+    def __ixor__(self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        return self.append( other ) #Or( [ self, other ] )
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class MatchFirst(ParseExpression):
+    """
+    Requires that at least one C{ParseExpression} is found.
+    If two expressions match, the first one listed is the one that will match.
+    May be constructed using the C{'|'} operator.
+
+    Example::
+        # construct MatchFirst using '|' operator
+        
+        # watch the order of expressions to match
+        number = Word(nums) | Combine(Word(nums) + '.' + Word(nums))
+        print(number.searchString("123 3.1416 789")) #  Fail! -> [['123'], ['3'], ['1416'], ['789']]
+
+        # put more selective expression first
+        number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums)
+        print(number.searchString("123 3.1416 789")) #  Better -> [['123'], ['3.1416'], ['789']]
+    """
+    def __init__( self, exprs, savelist = False ):
+        super(MatchFirst,self).__init__(exprs, savelist)
+        if self.exprs:
+            self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs)
+        else:
+            self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        maxExcLoc = -1
+        maxException = None
+        for e in self.exprs:
+            try:
+                ret = e._parse( instring, loc, doActions )
+                return ret
+            except ParseException as err:
+                if err.loc > maxExcLoc:
+                    maxException = err
+                    maxExcLoc = err.loc
+            except IndexError:
+                if len(instring) > maxExcLoc:
+                    maxException = ParseException(instring,len(instring),e.errmsg,self)
+                    maxExcLoc = len(instring)
+
+        # only got here if no expression matched, raise exception for match that made it the furthest
+        else:
+            if maxException is not None:
+                maxException.msg = self.errmsg
+                raise maxException
+            else:
+                raise ParseException(instring, loc, "no defined alternatives to match", self)
+
+    def __ior__(self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        return self.append( other ) #MatchFirst( [ self, other ] )
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class Each(ParseExpression):
+    """
+    Requires all given C{ParseExpression}s to be found, but in any order.
+    Expressions may be separated by whitespace.
+    May be constructed using the C{'&'} operator.
+
+    Example::
+        color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN")
+        shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON")
+        integer = Word(nums)
+        shape_attr = "shape:" + shape_type("shape")
+        posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn")
+        color_attr = "color:" + color("color")
+        size_attr = "size:" + integer("size")
+
+        # use Each (using operator '&') to accept attributes in any order 
+        # (shape and posn are required, color and size are optional)
+        shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr)
+
+        shape_spec.runTests('''
+            shape: SQUARE color: BLACK posn: 100, 120
+            shape: CIRCLE size: 50 color: BLUE posn: 50,80
+            color:GREEN size:20 shape:TRIANGLE posn:20,40
+            '''
+            )
+    prints::
+        shape: SQUARE color: BLACK posn: 100, 120
+        ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']]
+        - color: BLACK
+        - posn: ['100', ',', '120']
+          - x: 100
+          - y: 120
+        - shape: SQUARE
+
+
+        shape: CIRCLE size: 50 color: BLUE posn: 50,80
+        ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']]
+        - color: BLUE
+        - posn: ['50', ',', '80']
+          - x: 50
+          - y: 80
+        - shape: CIRCLE
+        - size: 50
+
+
+        color: GREEN size: 20 shape: TRIANGLE posn: 20,40
+        ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']]
+        - color: GREEN
+        - posn: ['20', ',', '40']
+          - x: 20
+          - y: 40
+        - shape: TRIANGLE
+        - size: 20
+    """
+    def __init__( self, exprs, savelist = True ):
+        super(Each,self).__init__(exprs, savelist)
+        self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
+        self.skipWhitespace = True
+        self.initExprGroups = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.initExprGroups:
+            self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional))
+            opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ]
+            opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)]
+            self.optionals = opt1 + opt2
+            self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ]
+            self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ]
+            self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ]
+            self.required += self.multirequired
+            self.initExprGroups = False
+        tmpLoc = loc
+        tmpReqd = self.required[:]
+        tmpOpt  = self.optionals[:]
+        matchOrder = []
+
+        keepMatching = True
+        while keepMatching:
+            tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired
+            failed = []
+            for e in tmpExprs:
+                try:
+                    tmpLoc = e.tryParse( instring, tmpLoc )
+                except ParseException:
+                    failed.append(e)
+                else:
+                    matchOrder.append(self.opt1map.get(id(e),e))
+                    if e in tmpReqd:
+                        tmpReqd.remove(e)
+                    elif e in tmpOpt:
+                        tmpOpt.remove(e)
+            if len(failed) == len(tmpExprs):
+                keepMatching = False
+
+        if tmpReqd:
+            missing = ", ".join(_ustr(e) for e in tmpReqd)
+            raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing )
+
+        # add any unmatched Optionals, in case they have default values defined
+        matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt]
+
+        resultlist = []
+        for e in matchOrder:
+            loc,results = e._parse(instring,loc,doActions)
+            resultlist.append(results)
+
+        finalResults = sum(resultlist, ParseResults([]))
+        return loc, finalResults
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class ParseElementEnhance(ParserElement):
+    """
+    Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens.
+    """
+    def __init__( self, expr, savelist=False ):
+        super(ParseElementEnhance,self).__init__(savelist)
+        if isinstance( expr, basestring ):
+            if issubclass(ParserElement._literalStringClass, Token):
+                expr = ParserElement._literalStringClass(expr)
+            else:
+                expr = ParserElement._literalStringClass(Literal(expr))
+        self.expr = expr
+        self.strRepr = None
+        if expr is not None:
+            self.mayIndexError = expr.mayIndexError
+            self.mayReturnEmpty = expr.mayReturnEmpty
+            self.setWhitespaceChars( expr.whiteChars )
+            self.skipWhitespace = expr.skipWhitespace
+            self.saveAsList = expr.saveAsList
+            self.callPreparse = expr.callPreparse
+            self.ignoreExprs.extend(expr.ignoreExprs)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.expr is not None:
+            return self.expr._parse( instring, loc, doActions, callPreParse=False )
+        else:
+            raise ParseException("",loc,self.errmsg,self)
+
+    def leaveWhitespace( self ):
+        self.skipWhitespace = False
+        self.expr = self.expr.copy()
+        if self.expr is not None:
+            self.expr.leaveWhitespace()
+        return self
+
+    def ignore( self, other ):
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                super( ParseElementEnhance, self).ignore( other )
+                if self.expr is not None:
+                    self.expr.ignore( self.ignoreExprs[-1] )
+        else:
+            super( ParseElementEnhance, self).ignore( other )
+            if self.expr is not None:
+                self.expr.ignore( self.ignoreExprs[-1] )
+        return self
+
+    def streamline( self ):
+        super(ParseElementEnhance,self).streamline()
+        if self.expr is not None:
+            self.expr.streamline()
+        return self
+
+    def checkRecursion( self, parseElementList ):
+        if self in parseElementList:
+            raise RecursiveGrammarException( parseElementList+[self] )
+        subRecCheckList = parseElementList[:] + [ self ]
+        if self.expr is not None:
+            self.expr.checkRecursion( subRecCheckList )
+
+    def validate( self, validateTrace=[] ):
+        tmp = validateTrace[:]+[self]
+        if self.expr is not None:
+            self.expr.validate(tmp)
+        self.checkRecursion( [] )
+
+    def __str__( self ):
+        try:
+            return super(ParseElementEnhance,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None and self.expr is not None:
+            self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) )
+        return self.strRepr
+
+
+class FollowedBy(ParseElementEnhance):
+    """
+    Lookahead matching of the given parse expression.  C{FollowedBy}
+    does I{not} advance the parsing position within the input string, it only
+    verifies that the specified parse expression matches at the current
+    position.  C{FollowedBy} always returns a null token list.
+
+    Example::
+        # use FollowedBy to match a label only if it is followed by a ':'
+        data_word = Word(alphas)
+        label = data_word + FollowedBy(':')
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        
+        OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint()
+    prints::
+        [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']]
+    """
+    def __init__( self, expr ):
+        super(FollowedBy,self).__init__(expr)
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        self.expr.tryParse( instring, loc )
+        return loc, []
+
+
+class NotAny(ParseElementEnhance):
+    """
+    Lookahead to disallow matching with the given parse expression.  C{NotAny}
+    does I{not} advance the parsing position within the input string, it only
+    verifies that the specified parse expression does I{not} match at the current
+    position.  Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny}
+    always returns a null token list.  May be constructed using the '~' operator.
+
+    Example::
+        
+    """
+    def __init__( self, expr ):
+        super(NotAny,self).__init__(expr)
+        #~ self.leaveWhitespace()
+        self.skipWhitespace = False  # do NOT use self.leaveWhitespace(), don't want to propagate to exprs
+        self.mayReturnEmpty = True
+        self.errmsg = "Found unwanted token, "+_ustr(self.expr)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.expr.canParseNext(instring, loc):
+            raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "~{" + _ustr(self.expr) + "}"
+
+        return self.strRepr
+
+class _MultipleMatch(ParseElementEnhance):
+    def __init__( self, expr, stopOn=None):
+        super(_MultipleMatch, self).__init__(expr)
+        self.saveAsList = True
+        ender = stopOn
+        if isinstance(ender, basestring):
+            ender = ParserElement._literalStringClass(ender)
+        self.not_ender = ~ender if ender is not None else None
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        self_expr_parse = self.expr._parse
+        self_skip_ignorables = self._skipIgnorables
+        check_ender = self.not_ender is not None
+        if check_ender:
+            try_not_ender = self.not_ender.tryParse
+        
+        # must be at least one (but first see if we are the stopOn sentinel;
+        # if so, fail)
+        if check_ender:
+            try_not_ender(instring, loc)
+        loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False )
+        try:
+            hasIgnoreExprs = (not not self.ignoreExprs)
+            while 1:
+                if check_ender:
+                    try_not_ender(instring, loc)
+                if hasIgnoreExprs:
+                    preloc = self_skip_ignorables( instring, loc )
+                else:
+                    preloc = loc
+                loc, tmptokens = self_expr_parse( instring, preloc, doActions )
+                if tmptokens or tmptokens.haskeys():
+                    tokens += tmptokens
+        except (ParseException,IndexError):
+            pass
+
+        return loc, tokens
+        
+class OneOrMore(_MultipleMatch):
+    """
+    Repetition of one or more of the given expression.
+    
+    Parameters:
+     - expr - expression that must match one or more times
+     - stopOn - (default=C{None}) - expression for a terminating sentinel
+          (only required if the sentinel would ordinarily match the repetition 
+          expression)          
+
+    Example::
+        data_word = Word(alphas)
+        label = data_word + FollowedBy(':')
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join))
+
+        text = "shape: SQUARE posn: upper left color: BLACK"
+        OneOrMore(attr_expr).parseString(text).pprint()  # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']]
+
+        # use stopOn attribute for OneOrMore to avoid reading label string as part of the data
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']]
+        
+        # could also be written as
+        (attr_expr * (1,)).parseString(text).pprint()
+    """
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + _ustr(self.expr) + "}..."
+
+        return self.strRepr
+
+class ZeroOrMore(_MultipleMatch):
+    """
+    Optional repetition of zero or more of the given expression.
+    
+    Parameters:
+     - expr - expression that must match zero or more times
+     - stopOn - (default=C{None}) - expression for a terminating sentinel
+          (only required if the sentinel would ordinarily match the repetition 
+          expression)          
+
+    Example: similar to L{OneOrMore}
+    """
+    def __init__( self, expr, stopOn=None):
+        super(ZeroOrMore,self).__init__(expr, stopOn=stopOn)
+        self.mayReturnEmpty = True
+        
+    def parseImpl( self, instring, loc, doActions=True ):
+        try:
+            return super(ZeroOrMore, self).parseImpl(instring, loc, doActions)
+        except (ParseException,IndexError):
+            return loc, []
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "[" + _ustr(self.expr) + "]..."
+
+        return self.strRepr
+
+class _NullToken(object):
+    def __bool__(self):
+        return False
+    __nonzero__ = __bool__
+    def __str__(self):
+        return ""
+
+_optionalNotMatched = _NullToken()
+class Optional(ParseElementEnhance):
+    """
+    Optional matching of the given expression.
+
+    Parameters:
+     - expr - expression that must match zero or more times
+     - default (optional) - value to be returned if the optional expression is not found.
+
+    Example::
+        # US postal code can be a 5-digit zip, plus optional 4-digit qualifier
+        zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4)))
+        zip.runTests('''
+            # traditional ZIP code
+            12345
+            
+            # ZIP+4 form
+            12101-0001
+            
+            # invalid ZIP
+            98765-
+            ''')
+    prints::
+        # traditional ZIP code
+        12345
+        ['12345']
+
+        # ZIP+4 form
+        12101-0001
+        ['12101-0001']
+
+        # invalid ZIP
+        98765-
+             ^
+        FAIL: Expected end of text (at char 5), (line:1, col:6)
+    """
+    def __init__( self, expr, default=_optionalNotMatched ):
+        super(Optional,self).__init__( expr, savelist=False )
+        self.saveAsList = self.expr.saveAsList
+        self.defaultValue = default
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        try:
+            loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False )
+        except (ParseException,IndexError):
+            if self.defaultValue is not _optionalNotMatched:
+                if self.expr.resultsName:
+                    tokens = ParseResults([ self.defaultValue ])
+                    tokens[self.expr.resultsName] = self.defaultValue
+                else:
+                    tokens = [ self.defaultValue ]
+            else:
+                tokens = []
+        return loc, tokens
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "[" + _ustr(self.expr) + "]"
+
+        return self.strRepr
+
+class SkipTo(ParseElementEnhance):
+    """
+    Token for skipping over all undefined text until the matched expression is found.
+
+    Parameters:
+     - expr - target expression marking the end of the data to be skipped
+     - include - (default=C{False}) if True, the target expression is also parsed 
+          (the skipped text and target expression are returned as a 2-element list).
+     - ignore - (default=C{None}) used to define grammars (typically quoted strings and 
+          comments) that might contain false matches to the target expression
+     - failOn - (default=C{None}) define expressions that are not allowed to be 
+          included in the skipped test; if found before the target expression is found, 
+          the SkipTo is not a match
+
+    Example::
+        report = '''
+            Outstanding Issues Report - 1 Jan 2000
+
+               # | Severity | Description                               |  Days Open
+            -----+----------+-------------------------------------------+-----------
+             101 | Critical | Intermittent system crash                 |          6
+              94 | Cosmetic | Spelling error on Login ('log|n')         |         14
+              79 | Minor    | System slow when running too many reports |         47
+            '''
+        integer = Word(nums)
+        SEP = Suppress('|')
+        # use SkipTo to simply match everything up until the next SEP
+        # - ignore quoted strings, so that a '|' character inside a quoted string does not match
+        # - parse action will call token.strip() for each matched token, i.e., the description body
+        string_data = SkipTo(SEP, ignore=quotedString)
+        string_data.setParseAction(tokenMap(str.strip))
+        ticket_expr = (integer("issue_num") + SEP 
+                      + string_data("sev") + SEP 
+                      + string_data("desc") + SEP 
+                      + integer("days_open"))
+        
+        for tkt in ticket_expr.searchString(report):
+            print tkt.dump()
+    prints::
+        ['101', 'Critical', 'Intermittent system crash', '6']
+        - days_open: 6
+        - desc: Intermittent system crash
+        - issue_num: 101
+        - sev: Critical
+        ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14']
+        - days_open: 14
+        - desc: Spelling error on Login ('log|n')
+        - issue_num: 94
+        - sev: Cosmetic
+        ['79', 'Minor', 'System slow when running too many reports', '47']
+        - days_open: 47
+        - desc: System slow when running too many reports
+        - issue_num: 79
+        - sev: Minor
+    """
+    def __init__( self, other, include=False, ignore=None, failOn=None ):
+        super( SkipTo, self ).__init__( other )
+        self.ignoreExpr = ignore
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+        self.includeMatch = include
+        self.asList = False
+        if isinstance(failOn, basestring):
+            self.failOn = ParserElement._literalStringClass(failOn)
+        else:
+            self.failOn = failOn
+        self.errmsg = "No match found for "+_ustr(self.expr)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        startloc = loc
+        instrlen = len(instring)
+        expr = self.expr
+        expr_parse = self.expr._parse
+        self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None
+        self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None
+        
+        tmploc = loc
+        while tmploc <= instrlen:
+            if self_failOn_canParseNext is not None:
+                # break if failOn expression matches
+                if self_failOn_canParseNext(instring, tmploc):
+                    break
+                    
+            if self_ignoreExpr_tryParse is not None:
+                # advance past ignore expressions
+                while 1:
+                    try:
+                        tmploc = self_ignoreExpr_tryParse(instring, tmploc)
+                    except ParseBaseException:
+                        break
+            
+            try:
+                expr_parse(instring, tmploc, doActions=False, callPreParse=False)
+            except (ParseException, IndexError):
+                # no match, advance loc in string
+                tmploc += 1
+            else:
+                # matched skipto expr, done
+                break
+
+        else:
+            # ran off the end of the input string without matching skipto expr, fail
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        # build up return values
+        loc = tmploc
+        skiptext = instring[startloc:loc]
+        skipresult = ParseResults(skiptext)
+        
+        if self.includeMatch:
+            loc, mat = expr_parse(instring,loc,doActions,callPreParse=False)
+            skipresult += mat
+
+        return loc, skipresult
+
+class Forward(ParseElementEnhance):
+    """
+    Forward declaration of an expression to be defined later -
+    used for recursive grammars, such as algebraic infix notation.
+    When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator.
+
+    Note: take care when assigning to C{Forward} not to overlook precedence of operators.
+    Specifically, '|' has a lower precedence than '<<', so that::
+        fwdExpr << a | b | c
+    will actually be evaluated as::
+        (fwdExpr << a) | b | c
+    thereby leaving b and c out as parseable alternatives.  It is recommended that you
+    explicitly group the values inserted into the C{Forward}::
+        fwdExpr << (a | b | c)
+    Converting to use the '<<=' operator instead will avoid this problem.
+
+    See L{ParseResults.pprint} for an example of a recursive parser created using
+    C{Forward}.
+    """
+    def __init__( self, other=None ):
+        super(Forward,self).__init__( other, savelist=False )
+
+    def __lshift__( self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass(other)
+        self.expr = other
+        self.strRepr = None
+        self.mayIndexError = self.expr.mayIndexError
+        self.mayReturnEmpty = self.expr.mayReturnEmpty
+        self.setWhitespaceChars( self.expr.whiteChars )
+        self.skipWhitespace = self.expr.skipWhitespace
+        self.saveAsList = self.expr.saveAsList
+        self.ignoreExprs.extend(self.expr.ignoreExprs)
+        return self
+        
+    def __ilshift__(self, other):
+        return self << other
+    
+    def leaveWhitespace( self ):
+        self.skipWhitespace = False
+        return self
+
+    def streamline( self ):
+        if not self.streamlined:
+            self.streamlined = True
+            if self.expr is not None:
+                self.expr.streamline()
+        return self
+
+    def validate( self, validateTrace=[] ):
+        if self not in validateTrace:
+            tmp = validateTrace[:]+[self]
+            if self.expr is not None:
+                self.expr.validate(tmp)
+        self.checkRecursion([])
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+        return self.__class__.__name__ + ": ..."
+
+        # stubbed out for now - creates awful memory and perf issues
+        self._revertClass = self.__class__
+        self.__class__ = _ForwardNoRecurse
+        try:
+            if self.expr is not None:
+                retString = _ustr(self.expr)
+            else:
+                retString = "None"
+        finally:
+            self.__class__ = self._revertClass
+        return self.__class__.__name__ + ": " + retString
+
+    def copy(self):
+        if self.expr is not None:
+            return super(Forward,self).copy()
+        else:
+            ret = Forward()
+            ret <<= self
+            return ret
+
+class _ForwardNoRecurse(Forward):
+    def __str__( self ):
+        return "..."
+
+class TokenConverter(ParseElementEnhance):
+    """
+    Abstract subclass of C{ParseExpression}, for converting parsed results.
+    """
+    def __init__( self, expr, savelist=False ):
+        super(TokenConverter,self).__init__( expr )#, savelist )
+        self.saveAsList = False
+
+class Combine(TokenConverter):
+    """
+    Converter to concatenate all matching tokens to a single string.
+    By default, the matching patterns must also be contiguous in the input string;
+    this can be disabled by specifying C{'adjacent=False'} in the constructor.
+
+    Example::
+        real = Word(nums) + '.' + Word(nums)
+        print(real.parseString('3.1416')) # -> ['3', '.', '1416']
+        # will also erroneously match the following
+        print(real.parseString('3. 1416')) # -> ['3', '.', '1416']
+
+        real = Combine(Word(nums) + '.' + Word(nums))
+        print(real.parseString('3.1416')) # -> ['3.1416']
+        # no match when there are internal spaces
+        print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...)
+    """
+    def __init__( self, expr, joinString="", adjacent=True ):
+        super(Combine,self).__init__( expr )
+        # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself
+        if adjacent:
+            self.leaveWhitespace()
+        self.adjacent = adjacent
+        self.skipWhitespace = True
+        self.joinString = joinString
+        self.callPreparse = True
+
+    def ignore( self, other ):
+        if self.adjacent:
+            ParserElement.ignore(self, other)
+        else:
+            super( Combine, self).ignore( other )
+        return self
+
+    def postParse( self, instring, loc, tokenlist ):
+        retToks = tokenlist.copy()
+        del retToks[:]
+        retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults)
+
+        if self.resultsName and retToks.haskeys():
+            return [ retToks ]
+        else:
+            return retToks
+
+class Group(TokenConverter):
+    """
+    Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions.
+
+    Example::
+        ident = Word(alphas)
+        num = Word(nums)
+        term = ident | num
+        func = ident + Optional(delimitedList(term))
+        print(func.parseString("fn a,b,100"))  # -> ['fn', 'a', 'b', '100']
+
+        func = ident + Group(Optional(delimitedList(term)))
+        print(func.parseString("fn a,b,100"))  # -> ['fn', ['a', 'b', '100']]
+    """
+    def __init__( self, expr ):
+        super(Group,self).__init__( expr )
+        self.saveAsList = True
+
+    def postParse( self, instring, loc, tokenlist ):
+        return [ tokenlist ]
+
+class Dict(TokenConverter):
+    """
+    Converter to return a repetitive expression as a list, but also as a dictionary.
+    Each element can also be referenced using the first token in the expression as its key.
+    Useful for tabular report scraping when the first column can be used as a item key.
+
+    Example::
+        data_word = Word(alphas)
+        label = data_word + FollowedBy(':')
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join))
+
+        text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
+        attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        
+        # print attributes as plain groups
+        print(OneOrMore(attr_expr).parseString(text).dump())
+        
+        # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names
+        result = Dict(OneOrMore(Group(attr_expr))).parseString(text)
+        print(result.dump())
+        
+        # access named fields as dict entries, or output as dict
+        print(result['shape'])        
+        print(result.asDict())
+    prints::
+        ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap']
+
+        [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
+        - color: light blue
+        - posn: upper left
+        - shape: SQUARE
+        - texture: burlap
+        SQUARE
+        {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'}
+    See more examples at L{ParseResults} of accessing fields by results name.
+    """
+    def __init__( self, expr ):
+        super(Dict,self).__init__( expr )
+        self.saveAsList = True
+
+    def postParse( self, instring, loc, tokenlist ):
+        for i,tok in enumerate(tokenlist):
+            if len(tok) == 0:
+                continue
+            ikey = tok[0]
+            if isinstance(ikey,int):
+                ikey = _ustr(tok[0]).strip()
+            if len(tok)==1:
+                tokenlist[ikey] = _ParseResultsWithOffset("",i)
+            elif len(tok)==2 and not isinstance(tok[1],ParseResults):
+                tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i)
+            else:
+                dictvalue = tok.copy() #ParseResults(i)
+                del dictvalue[0]
+                if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()):
+                    tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i)
+                else:
+                    tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i)
+
+        if self.resultsName:
+            return [ tokenlist ]
+        else:
+            return tokenlist
+
+
+class Suppress(TokenConverter):
+    """
+    Converter for ignoring the results of a parsed expression.
+
+    Example::
+        source = "a, b, c,d"
+        wd = Word(alphas)
+        wd_list1 = wd + ZeroOrMore(',' + wd)
+        print(wd_list1.parseString(source))
+
+        # often, delimiters that are useful during parsing are just in the
+        # way afterward - use Suppress to keep them out of the parsed output
+        wd_list2 = wd + ZeroOrMore(Suppress(',') + wd)
+        print(wd_list2.parseString(source))
+    prints::
+        ['a', ',', 'b', ',', 'c', ',', 'd']
+        ['a', 'b', 'c', 'd']
+    (See also L{delimitedList}.)
+    """
+    def postParse( self, instring, loc, tokenlist ):
+        return []
+
+    def suppress( self ):
+        return self
+
+
+class OnlyOnce(object):
+    """
+    Wrapper for parse actions, to ensure they are only called once.
+    """
+    def __init__(self, methodCall):
+        self.callable = _trim_arity(methodCall)
+        self.called = False
+    def __call__(self,s,l,t):
+        if not self.called:
+            results = self.callable(s,l,t)
+            self.called = True
+            return results
+        raise ParseException(s,l,"")
+    def reset(self):
+        self.called = False
+
+def traceParseAction(f):
+    """
+    Decorator for debugging parse actions. 
+    
+    When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".}
+    When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised.
+
+    Example::
+        wd = Word(alphas)
+
+        @traceParseAction
+        def remove_duplicate_chars(tokens):
+            return ''.join(sorted(set(''.join(tokens)))
+
+        wds = OneOrMore(wd).setParseAction(remove_duplicate_chars)
+        print(wds.parseString("slkdjs sld sldd sdlf sdljf"))
+    prints::
+        >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {}))
+        <<leaving remove_duplicate_chars (ret: 'dfjkls')
+        ['dfjkls']
+    """
+    f = _trim_arity(f)
+    def z(*paArgs):
+        thisFunc = f.__name__
+        s,l,t = paArgs[-3:]
+        if len(paArgs)>3:
+            thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc
+        sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) )
+        try:
+            ret = f(*paArgs)
+        except Exception as exc:
+            sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) )
+            raise
+        sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) )
+        return ret
+    try:
+        z.__name__ = f.__name__
+    except AttributeError:
+        pass
+    return z
+
+#
+# global helpers
+#
+def delimitedList( expr, delim=",", combine=False ):
+    """
+    Helper to define a delimited list of expressions - the delimiter defaults to ','.
+    By default, the list elements and delimiters can have intervening whitespace, and
+    comments, but this can be overridden by passing C{combine=True} in the constructor.
+    If C{combine} is set to C{True}, the matching tokens are returned as a single token
+    string, with the delimiters included; otherwise, the matching tokens are returned
+    as a list of tokens, with the delimiters suppressed.
+
+    Example::
+        delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc']
+        delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE']
+    """
+    dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..."
+    if combine:
+        return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName)
+    else:
+        return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName)
+
+def countedArray( expr, intExpr=None ):
+    """
+    Helper to define a counted list of expressions.
+    This helper defines a pattern of the form::
+        integer expr expr expr...
+    where the leading integer tells how many expr expressions follow.
+    The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed.
+    
+    If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value.
+
+    Example::
+        countedArray(Word(alphas)).parseString('2 ab cd ef')  # -> ['ab', 'cd']
+
+        # in this parser, the leading integer value is given in binary,
+        # '10' indicating that 2 values are in the array
+        binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2))
+        countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef')  # -> ['ab', 'cd']
+    """
+    arrayExpr = Forward()
+    def countFieldParseAction(s,l,t):
+        n = t[0]
+        arrayExpr << (n and Group(And([expr]*n)) or Group(empty))
+        return []
+    if intExpr is None:
+        intExpr = Word(nums).setParseAction(lambda t:int(t[0]))
+    else:
+        intExpr = intExpr.copy()
+    intExpr.setName("arrayLen")
+    intExpr.addParseAction(countFieldParseAction, callDuringTry=True)
+    return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...')
+
+def _flatten(L):
+    ret = []
+    for i in L:
+        if isinstance(i,list):
+            ret.extend(_flatten(i))
+        else:
+            ret.append(i)
+    return ret
+
+def matchPreviousLiteral(expr):
+    """
+    Helper to define an expression that is indirectly defined from
+    the tokens matched in a previous expression, that is, it looks
+    for a 'repeat' of a previous expression.  For example::
+        first = Word(nums)
+        second = matchPreviousLiteral(first)
+        matchExpr = first + ":" + second
+    will match C{"1:1"}, but not C{"1:2"}.  Because this matches a
+    previous literal, will also match the leading C{"1:1"} in C{"1:10"}.
+    If this is not desired, use C{matchPreviousExpr}.
+    Do I{not} use with packrat parsing enabled.
+    """
+    rep = Forward()
+    def copyTokenToRepeater(s,l,t):
+        if t:
+            if len(t) == 1:
+                rep << t[0]
+            else:
+                # flatten t tokens
+                tflat = _flatten(t.asList())
+                rep << And(Literal(tt) for tt in tflat)
+        else:
+            rep << Empty()
+    expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
+    rep.setName('(prev) ' + _ustr(expr))
+    return rep
+
+def matchPreviousExpr(expr):
+    """
+    Helper to define an expression that is indirectly defined from
+    the tokens matched in a previous expression, that is, it looks
+    for a 'repeat' of a previous expression.  For example::
+        first = Word(nums)
+        second = matchPreviousExpr(first)
+        matchExpr = first + ":" + second
+    will match C{"1:1"}, but not C{"1:2"}.  Because this matches by
+    expressions, will I{not} match the leading C{"1:1"} in C{"1:10"};
+    the expressions are evaluated first, and then compared, so
+    C{"1"} is compared with C{"10"}.
+    Do I{not} use with packrat parsing enabled.
+    """
+    rep = Forward()
+    e2 = expr.copy()
+    rep <<= e2
+    def copyTokenToRepeater(s,l,t):
+        matchTokens = _flatten(t.asList())
+        def mustMatchTheseTokens(s,l,t):
+            theseTokens = _flatten(t.asList())
+            if  theseTokens != matchTokens:
+                raise ParseException("",0,"")
+        rep.setParseAction( mustMatchTheseTokens, callDuringTry=True )
+    expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
+    rep.setName('(prev) ' + _ustr(expr))
+    return rep
+
+def _escapeRegexRangeChars(s):
+    #~  escape these chars: ^-]
+    for c in r"\^-]":
+        s = s.replace(c,_bslash+c)
+    s = s.replace("\n",r"\n")
+    s = s.replace("\t",r"\t")
+    return _ustr(s)
+
+def oneOf( strs, caseless=False, useRegex=True ):
+    """
+    Helper to quickly define a set of alternative Literals, and makes sure to do
+    longest-first testing when there is a conflict, regardless of the input order,
+    but returns a C{L{MatchFirst}} for best performance.
+
+    Parameters:
+     - strs - a string of space-delimited literals, or a collection of string literals
+     - caseless - (default=C{False}) - treat all literals as caseless
+     - useRegex - (default=C{True}) - as an optimization, will generate a Regex
+          object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or
+          if creating a C{Regex} raises an exception)
+
+    Example::
+        comp_oper = oneOf("< = > <= >= !=")
+        var = Word(alphas)
+        number = Word(nums)
+        term = var | number
+        comparison_expr = term + comp_oper + term
+        print(comparison_expr.searchString("B = 12  AA=23 B<=AA AA>12"))
+    prints::
+        [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']]
+    """
+    if caseless:
+        isequal = ( lambda a,b: a.upper() == b.upper() )
+        masks = ( lambda a,b: b.upper().startswith(a.upper()) )
+        parseElementClass = CaselessLiteral
+    else:
+        isequal = ( lambda a,b: a == b )
+        masks = ( lambda a,b: b.startswith(a) )
+        parseElementClass = Literal
+
+    symbols = []
+    if isinstance(strs,basestring):
+        symbols = strs.split()
+    elif isinstance(strs, collections.Iterable):
+        symbols = list(strs)
+    else:
+        warnings.warn("Invalid argument to oneOf, expected string or iterable",
+                SyntaxWarning, stacklevel=2)
+    if not symbols:
+        return NoMatch()
+
+    i = 0
+    while i < len(symbols)-1:
+        cur = symbols[i]
+        for j,other in enumerate(symbols[i+1:]):
+            if ( isequal(other, cur) ):
+                del symbols[i+j+1]
+                break
+            elif ( masks(cur, other) ):
+                del symbols[i+j+1]
+                symbols.insert(i,other)
+                cur = other
+                break
+        else:
+            i += 1
+
+    if not caseless and useRegex:
+        #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] ))
+        try:
+            if len(symbols)==len("".join(symbols)):
+                return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols))
+            else:
+                return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols))
+        except Exception:
+            warnings.warn("Exception creating Regex for oneOf, building MatchFirst",
+                    SyntaxWarning, stacklevel=2)
+
+
+    # last resort, just use MatchFirst
+    return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols))
+
+def dictOf( key, value ):
+    """
+    Helper to easily and clearly define a dictionary by specifying the respective patterns
+    for the key and value.  Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens
+    in the proper order.  The key pattern can include delimiting markers or punctuation,
+    as long as they are suppressed, thereby leaving the significant key text.  The value
+    pattern can include named results, so that the C{Dict} results can include named token
+    fields.
+
+    Example::
+        text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
+        attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        print(OneOrMore(attr_expr).parseString(text).dump())
+        
+        attr_label = label
+        attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)
+
+        # similar to Dict, but simpler call format
+        result = dictOf(attr_label, attr_value).parseString(text)
+        print(result.dump())
+        print(result['shape'])
+        print(result.shape)  # object attribute access works too
+        print(result.asDict())
+    prints::
+        [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
+        - color: light blue
+        - posn: upper left
+        - shape: SQUARE
+        - texture: burlap
+        SQUARE
+        SQUARE
+        {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'}
+    """
+    return Dict( ZeroOrMore( Group ( key + value ) ) )
+
+def originalTextFor(expr, asString=True):
+    """
+    Helper to return the original, untokenized text for a given expression.  Useful to
+    restore the parsed fields of an HTML start tag into the raw tag text itself, or to
+    revert separate tokens with intervening whitespace back to the original matching
+    input text. By default, returns astring containing the original parsed text.  
+       
+    If the optional C{asString} argument is passed as C{False}, then the return value is a 
+    C{L{ParseResults}} containing any results names that were originally matched, and a 
+    single token containing the original matched text from the input string.  So if 
+    the expression passed to C{L{originalTextFor}} contains expressions with defined
+    results names, you must set C{asString} to C{False} if you want to preserve those
+    results name values.
+
+    Example::
+        src = "this is test <b> bold <i>text</i> </b> normal text "
+        for tag in ("b","i"):
+            opener,closer = makeHTMLTags(tag)
+            patt = originalTextFor(opener + SkipTo(closer) + closer)
+            print(patt.searchString(src)[0])
+    prints::
+        ['<b> bold <i>text</i> </b>']
+        ['<i>text</i>']
+    """
+    locMarker = Empty().setParseAction(lambda s,loc,t: loc)
+    endlocMarker = locMarker.copy()
+    endlocMarker.callPreparse = False
+    matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end")
+    if asString:
+        extractText = lambda s,l,t: s[t._original_start:t._original_end]
+    else:
+        def extractText(s,l,t):
+            t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]]
+    matchExpr.setParseAction(extractText)
+    matchExpr.ignoreExprs = expr.ignoreExprs
+    return matchExpr
+
+def ungroup(expr): 
+    """
+    Helper to undo pyparsing's default grouping of And expressions, even
+    if all but one are non-empty.
+    """
+    return TokenConverter(expr).setParseAction(lambda t:t[0])
+
+def locatedExpr(expr):
+    """
+    Helper to decorate a returned token with its starting and ending locations in the input string.
+    This helper adds the following results names:
+     - locn_start = location where matched expression begins
+     - locn_end = location where matched expression ends
+     - value = the actual parsed results
+
+    Be careful if the input text contains C{<TAB>} characters, you may want to call
+    C{L{ParserElement.parseWithTabs}}
+
+    Example::
+        wd = Word(alphas)
+        for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"):
+            print(match)
+    prints::
+        [[0, 'ljsdf', 5]]
+        [[8, 'lksdjjf', 15]]
+        [[18, 'lkkjj', 23]]
+    """
+    locator = Empty().setParseAction(lambda s,l,t: l)
+    return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end"))
+
+
+# convenience constants for positional expressions
+empty       = Empty().setName("empty")
+lineStart   = LineStart().setName("lineStart")
+lineEnd     = LineEnd().setName("lineEnd")
+stringStart = StringStart().setName("stringStart")
+stringEnd   = StringEnd().setName("stringEnd")
+
+_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1])
+_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16)))
+_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8)))
+_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(printables, excludeChars=r'\]', exact=1) | Regex(r"\w", re.UNICODE)
+_charRange = Group(_singleChar + Suppress("-") + _singleChar)
+_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]"
+
+def srange(s):
+    r"""
+    Helper to easily define string ranges for use in Word construction.  Borrows
+    syntax from regexp '[]' string range definitions::
+        srange("[0-9]")   -> "0123456789"
+        srange("[a-z]")   -> "abcdefghijklmnopqrstuvwxyz"
+        srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_"
+    The input string must be enclosed in []'s, and the returned string is the expanded
+    character set joined into a single string.
+    The values enclosed in the []'s may be:
+     - a single character
+     - an escaped character with a leading backslash (such as C{\-} or C{\]})
+     - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) 
+         (C{\0x##} is also supported for backwards compatibility) 
+     - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character)
+     - a range of any of the above, separated by a dash (C{'a-z'}, etc.)
+     - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.)
+    """
+    _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1))
+    try:
+        return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body)
+    except Exception:
+        return ""
+
+def matchOnlyAtCol(n):
+    """
+    Helper method for defining parse actions that require matching at a specific
+    column in the input text.
+    """
+    def verifyCol(strg,locn,toks):
+        if col(locn,strg) != n:
+            raise ParseException(strg,locn,"matched token not at column %d" % n)
+    return verifyCol
+
+def replaceWith(replStr):
+    """
+    Helper method for common parse actions that simply return a literal value.  Especially
+    useful when used with C{L{transformString<ParserElement.transformString>}()}.
+
+    Example::
+        num = Word(nums).setParseAction(lambda toks: int(toks[0]))
+        na = oneOf("N/A NA").setParseAction(replaceWith(math.nan))
+        term = na | num
+        
+        OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234]
+    """
+    return lambda s,l,t: [replStr]
+
+def removeQuotes(s,l,t):
+    """
+    Helper parse action for removing quotation marks from parsed quoted strings.
+
+    Example::
+        # by default, quotation marks are included in parsed results
+        quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"]
+
+        # use removeQuotes to strip quotation marks from parsed results
+        quotedString.setParseAction(removeQuotes)
+        quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"]
+    """
+    return t[0][1:-1]
+
+def tokenMap(func, *args):
+    """
+    Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional 
+    args are passed, they are forwarded to the given function as additional arguments after
+    the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the
+    parsed data to an integer using base 16.
+
+    Example (compare the last to example in L{ParserElement.transformString}::
+        hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16))
+        hex_ints.runTests('''
+            00 11 22 aa FF 0a 0d 1a
+            ''')
+        
+        upperword = Word(alphas).setParseAction(tokenMap(str.upper))
+        OneOrMore(upperword).runTests('''
+            my kingdom for a horse
+            ''')
+
+        wd = Word(alphas).setParseAction(tokenMap(str.title))
+        OneOrMore(wd).setParseAction(' '.join).runTests('''
+            now is the winter of our discontent made glorious summer by this sun of york
+            ''')
+    prints::
+        00 11 22 aa FF 0a 0d 1a
+        [0, 17, 34, 170, 255, 10, 13, 26]
+
+        my kingdom for a horse
+        ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE']
+
+        now is the winter of our discontent made glorious summer by this sun of york
+        ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York']
+    """
+    def pa(s,l,t):
+        return [func(tokn, *args) for tokn in t]
+
+    try:
+        func_name = getattr(func, '__name__', 
+                            getattr(func, '__class__').__name__)
+    except Exception:
+        func_name = str(func)
+    pa.__name__ = func_name
+
+    return pa
+
+upcaseTokens = tokenMap(lambda t: _ustr(t).upper())
+"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}"""
+
+downcaseTokens = tokenMap(lambda t: _ustr(t).lower())
+"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}"""
+    
+def _makeTags(tagStr, xml):
+    """Internal helper to construct opening and closing tag expressions, given a tag name"""
+    if isinstance(tagStr,basestring):
+        resname = tagStr
+        tagStr = Keyword(tagStr, caseless=not xml)
+    else:
+        resname = tagStr.name
+
+    tagAttrName = Word(alphas,alphanums+"_-:")
+    if (xml):
+        tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes )
+        openTag = Suppress("<") + tagStr("tag") + \
+                Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \
+                Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
+    else:
+        printablesLessRAbrack = "".join(c for c in printables if c not in ">")
+        tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack)
+        openTag = Suppress("<") + tagStr("tag") + \
+                Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \
+                Optional( Suppress("=") + tagAttrValue ) ))) + \
+                Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
+    closeTag = Combine(_L("</") + tagStr + ">")
+
+    openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname)
+    closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname)
+    openTag.tag = resname
+    closeTag.tag = resname
+    return openTag, closeTag
+
+def makeHTMLTags(tagStr):
+    """
+    Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches
+    tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values.
+
+    Example::
+        text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>'
+        # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple
+        a,a_end = makeHTMLTags("A")
+        link_expr = a + SkipTo(a_end)("link_text") + a_end
+        
+        for link in link_expr.searchString(text):
+            # attributes in the <A> tag (like "href" shown here) are also accessible as named results
+            print(link.link_text, '->', link.href)
+    prints::
+        pyparsing -> http://pyparsing.wikispaces.com
+    """
+    return _makeTags( tagStr, False )
+
+def makeXMLTags(tagStr):
+    """
+    Helper to construct opening and closing tag expressions for XML, given a tag name. Matches
+    tags only in the given upper/lower case.
+
+    Example: similar to L{makeHTMLTags}
+    """
+    return _makeTags( tagStr, True )
+
+def withAttribute(*args,**attrDict):
+    """
+    Helper to create a validating parse action to be used with start tags created
+    with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag
+    with a required attribute value, to avoid false matches on common tags such as
+    C{<TD>} or C{<DIV>}.
+
+    Call C{withAttribute} with a series of attribute names and values. Specify the list
+    of filter attributes names and values as:
+     - keyword arguments, as in C{(align="right")}, or
+     - as an explicit dict with C{**} operator, when an attribute name is also a Python
+          reserved word, as in C{**{"class":"Customer", "align":"right"}}
+     - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") )
+    For attribute names with a namespace prefix, you must use the second form.  Attribute
+    names are matched insensitive to upper/lower case.
+       
+    If just testing for C{class} (with or without a namespace), use C{L{withClass}}.
+
+    To verify that the attribute exists, but without specifying a value, pass
+    C{withAttribute.ANY_VALUE} as the value.
+
+    Example::
+        html = '''
+            <div>
+            Some text
+            <div type="grid">1 4 0 1 0</div>
+            <div type="graph">1,3 2,3 1,1</div>
+            <div>this has no type</div>
+            </div>
+                
+        '''
+        div,div_end = makeHTMLTags("div")
+
+        # only match div tag having a type attribute with value "grid"
+        div_grid = div().setParseAction(withAttribute(type="grid"))
+        grid_expr = div_grid + SkipTo(div | div_end)("body")
+        for grid_header in grid_expr.searchString(html):
+            print(grid_header.body)
+        
+        # construct a match with any div tag having a type attribute, regardless of the value
+        div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE))
+        div_expr = div_any_type + SkipTo(div | div_end)("body")
+        for div_header in div_expr.searchString(html):
+            print(div_header.body)
+    prints::
+        1 4 0 1 0
+
+        1 4 0 1 0
+        1,3 2,3 1,1
+    """
+    if args:
+        attrs = args[:]
+    else:
+        attrs = attrDict.items()
+    attrs = [(k,v) for k,v in attrs]
+    def pa(s,l,tokens):
+        for attrName,attrValue in attrs:
+            if attrName not in tokens:
+                raise ParseException(s,l,"no matching attribute " + attrName)
+            if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue:
+                raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" %
+                                            (attrName, tokens[attrName], attrValue))
+    return pa
+withAttribute.ANY_VALUE = object()
+
+def withClass(classname, namespace=''):
+    """
+    Simplified version of C{L{withAttribute}} when matching on a div class - made
+    difficult because C{class} is a reserved word in Python.
+
+    Example::
+        html = '''
+            <div>
+            Some text
+            <div class="grid">1 4 0 1 0</div>
+            <div class="graph">1,3 2,3 1,1</div>
+            <div>this &lt;div&gt; has no class</div>
+            </div>
+                
+        '''
+        div,div_end = makeHTMLTags("div")
+        div_grid = div().setParseAction(withClass("grid"))
+        
+        grid_expr = div_grid + SkipTo(div | div_end)("body")
+        for grid_header in grid_expr.searchString(html):
+            print(grid_header.body)
+        
+        div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE))
+        div_expr = div_any_type + SkipTo(div | div_end)("body")
+        for div_header in div_expr.searchString(html):
+            print(div_header.body)
+    prints::
+        1 4 0 1 0
+
+        1 4 0 1 0
+        1,3 2,3 1,1
+    """
+    classattr = "%s:class" % namespace if namespace else "class"
+    return withAttribute(**{classattr : classname})        
+
+opAssoc = _Constants()
+opAssoc.LEFT = object()
+opAssoc.RIGHT = object()
+
+def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ):
+    """
+    Helper method for constructing grammars of expressions made up of
+    operators working in a precedence hierarchy.  Operators may be unary or
+    binary, left- or right-associative.  Parse actions can also be attached
+    to operator expressions. The generated parser will also recognize the use 
+    of parentheses to override operator precedences (see example below).
+    
+    Note: if you define a deep operator list, you may see performance issues
+    when using infixNotation. See L{ParserElement.enablePackrat} for a
+    mechanism to potentially improve your parser performance.
+
+    Parameters:
+     - baseExpr - expression representing the most basic element for the nested
+     - opList - list of tuples, one for each operator precedence level in the
+      expression grammar; each tuple is of the form
+      (opExpr, numTerms, rightLeftAssoc, parseAction), where:
+       - opExpr is the pyparsing expression for the operator;
+          may also be a string, which will be converted to a Literal;
+          if numTerms is 3, opExpr is a tuple of two expressions, for the
+          two operators separating the 3 terms
+       - numTerms is the number of terms for this operator (must
+          be 1, 2, or 3)
+       - rightLeftAssoc is the indicator whether the operator is
+          right or left associative, using the pyparsing-defined
+          constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}.
+       - parseAction is the parse action to be associated with
+          expressions matching this operator expression (the
+          parse action tuple member may be omitted)
+     - lpar - expression for matching left-parentheses (default=C{Suppress('(')})
+     - rpar - expression for matching right-parentheses (default=C{Suppress(')')})
+
+    Example::
+        # simple example of four-function arithmetic with ints and variable names
+        integer = pyparsing_common.signed_integer
+        varname = pyparsing_common.identifier 
+        
+        arith_expr = infixNotation(integer | varname,
+            [
+            ('-', 1, opAssoc.RIGHT),
+            (oneOf('* /'), 2, opAssoc.LEFT),
+            (oneOf('+ -'), 2, opAssoc.LEFT),
+            ])
+        
+        arith_expr.runTests('''
+            5+3*6
+            (5+3)*6
+            -2--11
+            ''', fullDump=False)
+    prints::
+        5+3*6
+        [[5, '+', [3, '*', 6]]]
+
+        (5+3)*6
+        [[[5, '+', 3], '*', 6]]
+
+        -2--11
+        [[['-', 2], '-', ['-', 11]]]
+    """
+    ret = Forward()
+    lastExpr = baseExpr | ( lpar + ret + rpar )
+    for i,operDef in enumerate(opList):
+        opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4]
+        termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr
+        if arity == 3:
+            if opExpr is None or len(opExpr) != 2:
+                raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions")
+            opExpr1, opExpr2 = opExpr
+        thisExpr = Forward().setName(termName)
+        if rightLeftAssoc == opAssoc.LEFT:
+            if arity == 1:
+                matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) )
+            elif arity == 2:
+                if opExpr is not None:
+                    matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) )
+                else:
+                    matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) )
+            elif arity == 3:
+                matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \
+                            Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr )
+            else:
+                raise ValueError("operator must be unary (1), binary (2), or ternary (3)")
+        elif rightLeftAssoc == opAssoc.RIGHT:
+            if arity == 1:
+                # try to avoid LR with this extra test
+                if not isinstance(opExpr, Optional):
+                    opExpr = Optional(opExpr)
+                matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr )
+            elif arity == 2:
+                if opExpr is not None:
+                    matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) )
+                else:
+                    matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) )
+            elif arity == 3:
+                matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \
+                            Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr )
+            else:
+                raise ValueError("operator must be unary (1), binary (2), or ternary (3)")
+        else:
+            raise ValueError("operator must indicate right or left associativity")
+        if pa:
+            matchExpr.setParseAction( pa )
+        thisExpr <<= ( matchExpr.setName(termName) | lastExpr )
+        lastExpr = thisExpr
+    ret <<= lastExpr
+    return ret
+
+operatorPrecedence = infixNotation
+"""(Deprecated) Former name of C{L{infixNotation}}, will be dropped in a future release."""
+
+dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes")
+sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes")
+quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'|
+                       Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes")
+unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal")
+
+def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()):
+    """
+    Helper method for defining nested lists enclosed in opening and closing
+    delimiters ("(" and ")" are the default).
+
+    Parameters:
+     - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression
+     - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression
+     - content - expression for items within the nested lists (default=C{None})
+     - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString})
+
+    If an expression is not provided for the content argument, the nested
+    expression will capture all whitespace-delimited content between delimiters
+    as a list of separate values.
+
+    Use the C{ignoreExpr} argument to define expressions that may contain
+    opening or closing characters that should not be treated as opening
+    or closing characters for nesting, such as quotedString or a comment
+    expression.  Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}.
+    The default is L{quotedString}, but if no expressions are to be ignored,
+    then pass C{None} for this argument.
+
+    Example::
+        data_type = oneOf("void int short long char float double")
+        decl_data_type = Combine(data_type + Optional(Word('*')))
+        ident = Word(alphas+'_', alphanums+'_')
+        number = pyparsing_common.number
+        arg = Group(decl_data_type + ident)
+        LPAR,RPAR = map(Suppress, "()")
+
+        code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment))
+
+        c_function = (decl_data_type("type") 
+                      + ident("name")
+                      + LPAR + Optional(delimitedList(arg), [])("args") + RPAR 
+                      + code_body("body"))
+        c_function.ignore(cStyleComment)
+        
+        source_code = '''
+            int is_odd(int x) { 
+                return (x%2); 
+            }
+                
+            int dec_to_hex(char hchar) { 
+                if (hchar >= '0' && hchar <= '9') { 
+                    return (ord(hchar)-ord('0')); 
+                } else { 
+                    return (10+ord(hchar)-ord('A'));
+                } 
+            }
+        '''
+        for func in c_function.searchString(source_code):
+            print("%(name)s (%(type)s) args: %(args)s" % func)
+
+    prints::
+        is_odd (int) args: [['int', 'x']]
+        dec_to_hex (int) args: [['char', 'hchar']]
+    """
+    if opener == closer:
+        raise ValueError("opening and closing strings cannot be the same")
+    if content is None:
+        if isinstance(opener,basestring) and isinstance(closer,basestring):
+            if len(opener) == 1 and len(closer)==1:
+                if ignoreExpr is not None:
+                    content = (Combine(OneOrMore(~ignoreExpr +
+                                    CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1))
+                                ).setParseAction(lambda t:t[0].strip()))
+                else:
+                    content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS
+                                ).setParseAction(lambda t:t[0].strip()))
+            else:
+                if ignoreExpr is not None:
+                    content = (Combine(OneOrMore(~ignoreExpr + 
+                                    ~Literal(opener) + ~Literal(closer) +
+                                    CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1))
+                                ).setParseAction(lambda t:t[0].strip()))
+                else:
+                    content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) +
+                                    CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1))
+                                ).setParseAction(lambda t:t[0].strip()))
+        else:
+            raise ValueError("opening and closing arguments must be strings if no content expression is given")
+    ret = Forward()
+    if ignoreExpr is not None:
+        ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) )
+    else:
+        ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content )  + Suppress(closer) )
+    ret.setName('nested %s%s expression' % (opener,closer))
+    return ret
+
+def indentedBlock(blockStatementExpr, indentStack, indent=True):
+    """
+    Helper method for defining space-delimited indentation blocks, such as
+    those used to define block statements in Python source code.
+
+    Parameters:
+     - blockStatementExpr - expression defining syntax of statement that
+            is repeated within the indented block
+     - indentStack - list created by caller to manage indentation stack
+            (multiple statementWithIndentedBlock expressions within a single grammar
+            should share a common indentStack)
+     - indent - boolean indicating whether block must be indented beyond the
+            the current level; set to False for block of left-most statements
+            (default=C{True})
+
+    A valid block must contain at least one C{blockStatement}.
+
+    Example::
+        data = '''
+        def A(z):
+          A1
+          B = 100
+          G = A2
+          A2
+          A3
+        B
+        def BB(a,b,c):
+          BB1
+          def BBA():
+            bba1
+            bba2
+            bba3
+        C
+        D
+        def spam(x,y):
+             def eggs(z):
+                 pass
+        '''
+
+
+        indentStack = [1]
+        stmt = Forward()
+
+        identifier = Word(alphas, alphanums)
+        funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":")
+        func_body = indentedBlock(stmt, indentStack)
+        funcDef = Group( funcDecl + func_body )
+
+        rvalue = Forward()
+        funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")")
+        rvalue << (funcCall | identifier | Word(nums))
+        assignment = Group(identifier + "=" + rvalue)
+        stmt << ( funcDef | assignment | identifier )
+
+        module_body = OneOrMore(stmt)
+
+        parseTree = module_body.parseString(data)
+        parseTree.pprint()
+    prints::
+        [['def',
+          'A',
+          ['(', 'z', ')'],
+          ':',
+          [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]],
+         'B',
+         ['def',
+          'BB',
+          ['(', 'a', 'b', 'c', ')'],
+          ':',
+          [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]],
+         'C',
+         'D',
+         ['def',
+          'spam',
+          ['(', 'x', 'y', ')'],
+          ':',
+          [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] 
+    """
+    def checkPeerIndent(s,l,t):
+        if l >= len(s): return
+        curCol = col(l,s)
+        if curCol != indentStack[-1]:
+            if curCol > indentStack[-1]:
+                raise ParseFatalException(s,l,"illegal nesting")
+            raise ParseException(s,l,"not a peer entry")
+
+    def checkSubIndent(s,l,t):
+        curCol = col(l,s)
+        if curCol > indentStack[-1]:
+            indentStack.append( curCol )
+        else:
+            raise ParseException(s,l,"not a subentry")
+
+    def checkUnindent(s,l,t):
+        if l >= len(s): return
+        curCol = col(l,s)
+        if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]):
+            raise ParseException(s,l,"not an unindent")
+        indentStack.pop()
+
+    NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress())
+    INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT')
+    PEER   = Empty().setParseAction(checkPeerIndent).setName('')
+    UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT')
+    if indent:
+        smExpr = Group( Optional(NL) +
+            #~ FollowedBy(blockStatementExpr) +
+            INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT)
+    else:
+        smExpr = Group( Optional(NL) +
+            (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) )
+    blockStatementExpr.ignore(_bslash + LineEnd())
+    return smExpr.setName('indented block')
+
+alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]")
+punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]")
+
+anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag'))
+_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\''))
+commonHTMLEntity = Regex('&(?P<entity>' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity")
+def replaceHTMLEntity(t):
+    """Helper parser action to replace common HTML entities with their special characters"""
+    return _htmlEntityMap.get(t.entity)
+
+# it's easy to get these comment structures wrong - they're very common, so may as well make them available
+cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment")
+"Comment of the form C{/* ... */}"
+
+htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment")
+"Comment of the form C{<!-- ... -->}"
+
+restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line")
+dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment")
+"Comment of the form C{// ... (to end of line)}"
+
+cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment")
+"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}"
+
+javaStyleComment = cppStyleComment
+"Same as C{L{cppStyleComment}}"
+
+pythonStyleComment = Regex(r"#.*").setName("Python style comment")
+"Comment of the form C{# ... (to end of line)}"
+
+_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') +
+                                  Optional( Word(" \t") +
+                                            ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem")
+commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList")
+"""(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas.
+   This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}."""
+
+# some other useful expressions - using lower-case class name since we are really using this as a namespace
+class pyparsing_common:
+    """
+    Here are some common low-level expressions that may be useful in jump-starting parser development:
+     - numeric forms (L{integers<integer>}, L{reals<real>}, L{scientific notation<sci_real>})
+     - common L{programming identifiers<identifier>}
+     - network addresses (L{MAC<mac_address>}, L{IPv4<ipv4_address>}, L{IPv6<ipv6_address>})
+     - ISO8601 L{dates<iso8601_date>} and L{datetime<iso8601_datetime>}
+     - L{UUID<uuid>}
+     - L{comma-separated list<comma_separated_list>}
+    Parse actions:
+     - C{L{convertToInteger}}
+     - C{L{convertToFloat}}
+     - C{L{convertToDate}}
+     - C{L{convertToDatetime}}
+     - C{L{stripHTMLTags}}
+     - C{L{upcaseTokens}}
+     - C{L{downcaseTokens}}
+
+    Example::
+        pyparsing_common.number.runTests('''
+            # any int or real number, returned as the appropriate type
+            100
+            -100
+            +100
+            3.14159
+            6.02e23
+            1e-12
+            ''')
+
+        pyparsing_common.fnumber.runTests('''
+            # any int or real number, returned as float
+            100
+            -100
+            +100
+            3.14159
+            6.02e23
+            1e-12
+            ''')
+
+        pyparsing_common.hex_integer.runTests('''
+            # hex numbers
+            100
+            FF
+            ''')
+
+        pyparsing_common.fraction.runTests('''
+            # fractions
+            1/2
+            -3/4
+            ''')
+
+        pyparsing_common.mixed_integer.runTests('''
+            # mixed fractions
+            1
+            1/2
+            -3/4
+            1-3/4
+            ''')
+
+        import uuid
+        pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID))
+        pyparsing_common.uuid.runTests('''
+            # uuid
+            12345678-1234-5678-1234-567812345678
+            ''')
+    prints::
+        # any int or real number, returned as the appropriate type
+        100
+        [100]
+
+        -100
+        [-100]
+
+        +100
+        [100]
+
+        3.14159
+        [3.14159]
+
+        6.02e23
+        [6.02e+23]
+
+        1e-12
+        [1e-12]
+
+        # any int or real number, returned as float
+        100
+        [100.0]
+
+        -100
+        [-100.0]
+
+        +100
+        [100.0]
+
+        3.14159
+        [3.14159]
+
+        6.02e23
+        [6.02e+23]
+
+        1e-12
+        [1e-12]
+
+        # hex numbers
+        100
+        [256]
+
+        FF
+        [255]
+
+        # fractions
+        1/2
+        [0.5]
+
+        -3/4
+        [-0.75]
+
+        # mixed fractions
+        1
+        [1]
+
+        1/2
+        [0.5]
+
+        -3/4
+        [-0.75]
+
+        1-3/4
+        [1.75]
+
+        # uuid
+        12345678-1234-5678-1234-567812345678
+        [UUID('12345678-1234-5678-1234-567812345678')]
+    """
+
+    convertToInteger = tokenMap(int)
+    """
+    Parse action for converting parsed integers to Python int
+    """
+
+    convertToFloat = tokenMap(float)
+    """
+    Parse action for converting parsed numbers to Python float
+    """
+
+    integer = Word(nums).setName("integer").setParseAction(convertToInteger)
+    """expression that parses an unsigned integer, returns an int"""
+
+    hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16))
+    """expression that parses a hexadecimal integer, returns an int"""
+
+    signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger)
+    """expression that parses an integer with optional leading sign, returns an int"""
+
+    fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction")
+    """fractional expression of an integer divided by an integer, returns a float"""
+    fraction.addParseAction(lambda t: t[0]/t[-1])
+
+    mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction")
+    """mixed integer of the form 'integer - fraction', with optional leading integer, returns float"""
+    mixed_integer.addParseAction(sum)
+
+    real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat)
+    """expression that parses a floating point number and returns a float"""
+
+    sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat)
+    """expression that parses a floating point number with optional scientific notation and returns a float"""
+
+    # streamlining this expression makes the docs nicer-looking
+    number = (sci_real | real | signed_integer).streamline()
+    """any numeric expression, returns the corresponding Python type"""
+
+    fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat)
+    """any int or real number, returned as float"""
+    
+    identifier = Word(alphas+'_', alphanums+'_').setName("identifier")
+    """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')"""
+    
+    ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address")
+    "IPv4 address (C{0.0.0.0 - 255.255.255.255})"
+
+    _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer")
+    _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address")
+    _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address")
+    _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8)
+    _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address")
+    ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address")
+    "IPv6 address (long, short, or mixed form)"
+    
+    mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address")
+    "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)"
+
+    @staticmethod
+    def convertToDate(fmt="%Y-%m-%d"):
+        """
+        Helper to create a parse action for converting parsed date string to Python datetime.date
+
+        Params -
+         - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"})
+
+        Example::
+            date_expr = pyparsing_common.iso8601_date.copy()
+            date_expr.setParseAction(pyparsing_common.convertToDate())
+            print(date_expr.parseString("1999-12-31"))
+        prints::
+            [datetime.date(1999, 12, 31)]
+        """
+        def cvt_fn(s,l,t):
+            try:
+                return datetime.strptime(t[0], fmt).date()
+            except ValueError as ve:
+                raise ParseException(s, l, str(ve))
+        return cvt_fn
+
+    @staticmethod
+    def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"):
+        """
+        Helper to create a parse action for converting parsed datetime string to Python datetime.datetime
+
+        Params -
+         - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"})
+
+        Example::
+            dt_expr = pyparsing_common.iso8601_datetime.copy()
+            dt_expr.setParseAction(pyparsing_common.convertToDatetime())
+            print(dt_expr.parseString("1999-12-31T23:59:59.999"))
+        prints::
+            [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)]
+        """
+        def cvt_fn(s,l,t):
+            try:
+                return datetime.strptime(t[0], fmt)
+            except ValueError as ve:
+                raise ParseException(s, l, str(ve))
+        return cvt_fn
+
+    iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date")
+    "ISO8601 date (C{yyyy-mm-dd})"
+
+    iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime")
+    "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}"
+
+    uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID")
+    "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})"
+
+    _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress()
+    @staticmethod
+    def stripHTMLTags(s, l, tokens):
+        """
+        Parse action to remove HTML tags from web page HTML source
+
+        Example::
+            # strip HTML links from normal text 
+            text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>'
+            td,td_end = makeHTMLTags("TD")
+            table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end
+            
+            print(table_text.parseString(text).body) # -> 'More info at the pyparsing wiki page'
+        """
+        return pyparsing_common._html_stripper.transformString(tokens[0])
+
+    _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') 
+                                        + Optional( White(" \t") ) ) ).streamline().setName("commaItem")
+    comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list")
+    """Predefined expression of 1 or more printable words or quoted strings, separated by commas."""
+
+    upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper()))
+    """Parse action to convert tokens to upper case."""
+
+    downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower()))
+    """Parse action to convert tokens to lower case."""
+
+
+if __name__ == "__main__":
+
+    selectToken    = CaselessLiteral("select")
+    fromToken      = CaselessLiteral("from")
+
+    ident          = Word(alphas, alphanums + "_$")
+
+    columnName     = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens)
+    columnNameList = Group(delimitedList(columnName)).setName("columns")
+    columnSpec     = ('*' | columnNameList)
+
+    tableName      = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens)
+    tableNameList  = Group(delimitedList(tableName)).setName("tables")
+    
+    simpleSQL      = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables")
+
+    # demo runTests method, including embedded comments in test string
+    simpleSQL.runTests("""
+        # '*' as column list and dotted table name
+        select * from SYS.XYZZY
+
+        # caseless match on "SELECT", and casts back to "select"
+        SELECT * from XYZZY, ABC
+
+        # list of column names, and mixed case SELECT keyword
+        Select AA,BB,CC from Sys.dual
+
+        # multiple tables
+        Select A, B, C from Sys.dual, Table2
+
+        # invalid SELECT keyword - should fail
+        Xelect A, B, C from Sys.dual
+
+        # incomplete command - should fail
+        Select
+
+        # invalid column name - should fail
+        Select ^^^ frox Sys.dual
+
+        """)
+
+    pyparsing_common.number.runTests("""
+        100
+        -100
+        +100
+        3.14159
+        6.02e23
+        1e-12
+        """)
+
+    # any int or real number, returned as float
+    pyparsing_common.fnumber.runTests("""
+        100
+        -100
+        +100
+        3.14159
+        6.02e23
+        1e-12
+        """)
+
+    pyparsing_common.hex_integer.runTests("""
+        100
+        FF
+        """)
+
+    import uuid
+    pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID))
+    pyparsing_common.uuid.runTests("""
+        12345678-1234-5678-1234-567812345678
+        """)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/six.py b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/six.py
new file mode 100644
index 00000000..190c0239
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/_vendor/six.py
@@ -0,0 +1,868 @@
+"""Utilities for writing code that runs on Python 2 and 3"""
+
+# Copyright (c) 2010-2015 Benjamin Peterson
+#
+# 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 __future__ import absolute_import
+
+import functools
+import itertools
+import operator
+import sys
+import types
+
+__author__ = "Benjamin Peterson <benjamin@python.org>"
+__version__ = "1.10.0"
+
+
+# Useful for very coarse version differentiation.
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
+PY34 = sys.version_info[0:2] >= (3, 4)
+
+if PY3:
+    string_types = str,
+    integer_types = int,
+    class_types = type,
+    text_type = str
+    binary_type = bytes
+
+    MAXSIZE = sys.maxsize
+else:
+    string_types = basestring,
+    integer_types = (int, long)
+    class_types = (type, types.ClassType)
+    text_type = unicode
+    binary_type = str
+
+    if sys.platform.startswith("java"):
+        # Jython always uses 32 bits.
+        MAXSIZE = int((1 << 31) - 1)
+    else:
+        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
+        class X(object):
+
+            def __len__(self):
+                return 1 << 31
+        try:
+            len(X())
+        except OverflowError:
+            # 32-bit
+            MAXSIZE = int((1 << 31) - 1)
+        else:
+            # 64-bit
+            MAXSIZE = int((1 << 63) - 1)
+        del X
+
+
+def _add_doc(func, doc):
+    """Add documentation to a function."""
+    func.__doc__ = doc
+
+
+def _import_module(name):
+    """Import module, returning the module after the last dot."""
+    __import__(name)
+    return sys.modules[name]
+
+
+class _LazyDescr(object):
+
+    def __init__(self, name):
+        self.name = name
+
+    def __get__(self, obj, tp):
+        result = self._resolve()
+        setattr(obj, self.name, result)  # Invokes __set__.
+        try:
+            # This is a bit ugly, but it avoids running this again by
+            # removing this descriptor.
+            delattr(obj.__class__, self.name)
+        except AttributeError:
+            pass
+        return result
+
+
+class MovedModule(_LazyDescr):
+
+    def __init__(self, name, old, new=None):
+        super(MovedModule, self).__init__(name)
+        if PY3:
+            if new is None:
+                new = name
+            self.mod = new
+        else:
+            self.mod = old
+
+    def _resolve(self):
+        return _import_module(self.mod)
+
+    def __getattr__(self, attr):
+        _module = self._resolve()
+        value = getattr(_module, attr)
+        setattr(self, attr, value)
+        return value
+
+
+class _LazyModule(types.ModuleType):
+
+    def __init__(self, name):
+        super(_LazyModule, self).__init__(name)
+        self.__doc__ = self.__class__.__doc__
+
+    def __dir__(self):
+        attrs = ["__doc__", "__name__"]
+        attrs += [attr.name for attr in self._moved_attributes]
+        return attrs
+
+    # Subclasses should override this
+    _moved_attributes = []
+
+
+class MovedAttribute(_LazyDescr):
+
+    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
+        super(MovedAttribute, self).__init__(name)
+        if PY3:
+            if new_mod is None:
+                new_mod = name
+            self.mod = new_mod
+            if new_attr is None:
+                if old_attr is None:
+                    new_attr = name
+                else:
+                    new_attr = old_attr
+            self.attr = new_attr
+        else:
+            self.mod = old_mod
+            if old_attr is None:
+                old_attr = name
+            self.attr = old_attr
+
+    def _resolve(self):
+        module = _import_module(self.mod)
+        return getattr(module, self.attr)
+
+
+class _SixMetaPathImporter(object):
+
+    """
+    A meta path importer to import six.moves and its submodules.
+
+    This class implements a PEP302 finder and loader. It should be compatible
+    with Python 2.5 and all existing versions of Python3
+    """
+
+    def __init__(self, six_module_name):
+        self.name = six_module_name
+        self.known_modules = {}
+
+    def _add_module(self, mod, *fullnames):
+        for fullname in fullnames:
+            self.known_modules[self.name + "." + fullname] = mod
+
+    def _get_module(self, fullname):
+        return self.known_modules[self.name + "." + fullname]
+
+    def find_module(self, fullname, path=None):
+        if fullname in self.known_modules:
+            return self
+        return None
+
+    def __get_module(self, fullname):
+        try:
+            return self.known_modules[fullname]
+        except KeyError:
+            raise ImportError("This loader does not know module " + fullname)
+
+    def load_module(self, fullname):
+        try:
+            # in case of a reload
+            return sys.modules[fullname]
+        except KeyError:
+            pass
+        mod = self.__get_module(fullname)
+        if isinstance(mod, MovedModule):
+            mod = mod._resolve()
+        else:
+            mod.__loader__ = self
+        sys.modules[fullname] = mod
+        return mod
+
+    def is_package(self, fullname):
+        """
+        Return true, if the named module is a package.
+
+        We need this method to get correct spec objects with
+        Python 3.4 (see PEP451)
+        """
+        return hasattr(self.__get_module(fullname), "__path__")
+
+    def get_code(self, fullname):
+        """Return None
+
+        Required, if is_package is implemented"""
+        self.__get_module(fullname)  # eventually raises ImportError
+        return None
+    get_source = get_code  # same as get_code
+
+_importer = _SixMetaPathImporter(__name__)
+
+
+class _MovedItems(_LazyModule):
+
+    """Lazy loading of moved objects"""
+    __path__ = []  # mark as package
+
+
+_moved_attributes = [
+    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
+    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
+    MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
+    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
+    MovedAttribute("intern", "__builtin__", "sys"),
+    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
+    MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
+    MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
+    MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
+    MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
+    MovedAttribute("reduce", "__builtin__", "functools"),
+    MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
+    MovedAttribute("StringIO", "StringIO", "io"),
+    MovedAttribute("UserDict", "UserDict", "collections"),
+    MovedAttribute("UserList", "UserList", "collections"),
+    MovedAttribute("UserString", "UserString", "collections"),
+    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
+    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
+    MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
+    MovedModule("builtins", "__builtin__"),
+    MovedModule("configparser", "ConfigParser"),
+    MovedModule("copyreg", "copy_reg"),
+    MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
+    MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
+    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
+    MovedModule("http_cookies", "Cookie", "http.cookies"),
+    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
+    MovedModule("html_parser", "HTMLParser", "html.parser"),
+    MovedModule("http_client", "httplib", "http.client"),
+    MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
+    MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
+    MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
+    MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
+    MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
+    MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
+    MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
+    MovedModule("cPickle", "cPickle", "pickle"),
+    MovedModule("queue", "Queue"),
+    MovedModule("reprlib", "repr"),
+    MovedModule("socketserver", "SocketServer"),
+    MovedModule("_thread", "thread", "_thread"),
+    MovedModule("tkinter", "Tkinter"),
+    MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
+    MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
+    MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
+    MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
+    MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
+    MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
+    MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
+    MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
+    MovedModule("tkinter_colorchooser", "tkColorChooser",
+                "tkinter.colorchooser"),
+    MovedModule("tkinter_commondialog", "tkCommonDialog",
+                "tkinter.commondialog"),
+    MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
+    MovedModule("tkinter_font", "tkFont", "tkinter.font"),
+    MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
+    MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
+                "tkinter.simpledialog"),
+    MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
+    MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
+    MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
+    MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
+    MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
+    MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
+]
+# Add windows specific modules.
+if sys.platform == "win32":
+    _moved_attributes += [
+        MovedModule("winreg", "_winreg"),
+    ]
+
+for attr in _moved_attributes:
+    setattr(_MovedItems, attr.name, attr)
+    if isinstance(attr, MovedModule):
+        _importer._add_module(attr, "moves." + attr.name)
+del attr
+
+_MovedItems._moved_attributes = _moved_attributes
+
+moves = _MovedItems(__name__ + ".moves")
+_importer._add_module(moves, "moves")
+
+
+class Module_six_moves_urllib_parse(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_parse"""
+
+
+_urllib_parse_moved_attributes = [
+    MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
+    MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
+    MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
+    MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
+    MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
+    MovedAttribute("urljoin", "urlparse", "urllib.parse"),
+    MovedAttribute("urlparse", "urlparse", "urllib.parse"),
+    MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
+    MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
+    MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
+    MovedAttribute("quote", "urllib", "urllib.parse"),
+    MovedAttribute("quote_plus", "urllib", "urllib.parse"),
+    MovedAttribute("unquote", "urllib", "urllib.parse"),
+    MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
+    MovedAttribute("urlencode", "urllib", "urllib.parse"),
+    MovedAttribute("splitquery", "urllib", "urllib.parse"),
+    MovedAttribute("splittag", "urllib", "urllib.parse"),
+    MovedAttribute("splituser", "urllib", "urllib.parse"),
+    MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_params", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_query", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
+]
+for attr in _urllib_parse_moved_attributes:
+    setattr(Module_six_moves_urllib_parse, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
+                      "moves.urllib_parse", "moves.urllib.parse")
+
+
+class Module_six_moves_urllib_error(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_error"""
+
+
+_urllib_error_moved_attributes = [
+    MovedAttribute("URLError", "urllib2", "urllib.error"),
+    MovedAttribute("HTTPError", "urllib2", "urllib.error"),
+    MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
+]
+for attr in _urllib_error_moved_attributes:
+    setattr(Module_six_moves_urllib_error, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
+                      "moves.urllib_error", "moves.urllib.error")
+
+
+class Module_six_moves_urllib_request(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_request"""
+
+
+_urllib_request_moved_attributes = [
+    MovedAttribute("urlopen", "urllib2", "urllib.request"),
+    MovedAttribute("install_opener", "urllib2", "urllib.request"),
+    MovedAttribute("build_opener", "urllib2", "urllib.request"),
+    MovedAttribute("pathname2url", "urllib", "urllib.request"),
+    MovedAttribute("url2pathname", "urllib", "urllib.request"),
+    MovedAttribute("getproxies", "urllib", "urllib.request"),
+    MovedAttribute("Request", "urllib2", "urllib.request"),
+    MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
+    MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
+    MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
+    MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
+    MovedAttribute("FileHandler", "urllib2", "urllib.request"),
+    MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
+    MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
+    MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
+    MovedAttribute("urlretrieve", "urllib", "urllib.request"),
+    MovedAttribute("urlcleanup", "urllib", "urllib.request"),
+    MovedAttribute("URLopener", "urllib", "urllib.request"),
+    MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
+    MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
+]
+for attr in _urllib_request_moved_attributes:
+    setattr(Module_six_moves_urllib_request, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
+                      "moves.urllib_request", "moves.urllib.request")
+
+
+class Module_six_moves_urllib_response(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_response"""
+
+
+_urllib_response_moved_attributes = [
+    MovedAttribute("addbase", "urllib", "urllib.response"),
+    MovedAttribute("addclosehook", "urllib", "urllib.response"),
+    MovedAttribute("addinfo", "urllib", "urllib.response"),
+    MovedAttribute("addinfourl", "urllib", "urllib.response"),
+]
+for attr in _urllib_response_moved_attributes:
+    setattr(Module_six_moves_urllib_response, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
+                      "moves.urllib_response", "moves.urllib.response")
+
+
+class Module_six_moves_urllib_robotparser(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_robotparser"""
+
+
+_urllib_robotparser_moved_attributes = [
+    MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
+]
+for attr in _urllib_robotparser_moved_attributes:
+    setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
+                      "moves.urllib_robotparser", "moves.urllib.robotparser")
+
+
+class Module_six_moves_urllib(types.ModuleType):
+
+    """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
+    __path__ = []  # mark as package
+    parse = _importer._get_module("moves.urllib_parse")
+    error = _importer._get_module("moves.urllib_error")
+    request = _importer._get_module("moves.urllib_request")
+    response = _importer._get_module("moves.urllib_response")
+    robotparser = _importer._get_module("moves.urllib_robotparser")
+
+    def __dir__(self):
+        return ['parse', 'error', 'request', 'response', 'robotparser']
+
+_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
+                      "moves.urllib")
+
+
+def add_move(move):
+    """Add an item to six.moves."""
+    setattr(_MovedItems, move.name, move)
+
+
+def remove_move(name):
+    """Remove item from six.moves."""
+    try:
+        delattr(_MovedItems, name)
+    except AttributeError:
+        try:
+            del moves.__dict__[name]
+        except KeyError:
+            raise AttributeError("no such move, %r" % (name,))
+
+
+if PY3:
+    _meth_func = "__func__"
+    _meth_self = "__self__"
+
+    _func_closure = "__closure__"
+    _func_code = "__code__"
+    _func_defaults = "__defaults__"
+    _func_globals = "__globals__"
+else:
+    _meth_func = "im_func"
+    _meth_self = "im_self"
+
+    _func_closure = "func_closure"
+    _func_code = "func_code"
+    _func_defaults = "func_defaults"
+    _func_globals = "func_globals"
+
+
+try:
+    advance_iterator = next
+except NameError:
+    def advance_iterator(it):
+        return it.next()
+next = advance_iterator
+
+
+try:
+    callable = callable
+except NameError:
+    def callable(obj):
+        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
+
+
+if PY3:
+    def get_unbound_function(unbound):
+        return unbound
+
+    create_bound_method = types.MethodType
+
+    def create_unbound_method(func, cls):
+        return func
+
+    Iterator = object
+else:
+    def get_unbound_function(unbound):
+        return unbound.im_func
+
+    def create_bound_method(func, obj):
+        return types.MethodType(func, obj, obj.__class__)
+
+    def create_unbound_method(func, cls):
+        return types.MethodType(func, None, cls)
+
+    class Iterator(object):
+
+        def next(self):
+            return type(self).__next__(self)
+
+    callable = callable
+_add_doc(get_unbound_function,
+         """Get the function out of a possibly unbound function""")
+
+
+get_method_function = operator.attrgetter(_meth_func)
+get_method_self = operator.attrgetter(_meth_self)
+get_function_closure = operator.attrgetter(_func_closure)
+get_function_code = operator.attrgetter(_func_code)
+get_function_defaults = operator.attrgetter(_func_defaults)
+get_function_globals = operator.attrgetter(_func_globals)
+
+
+if PY3:
+    def iterkeys(d, **kw):
+        return iter(d.keys(**kw))
+
+    def itervalues(d, **kw):
+        return iter(d.values(**kw))
+
+    def iteritems(d, **kw):
+        return iter(d.items(**kw))
+
+    def iterlists(d, **kw):
+        return iter(d.lists(**kw))
+
+    viewkeys = operator.methodcaller("keys")
+
+    viewvalues = operator.methodcaller("values")
+
+    viewitems = operator.methodcaller("items")
+else:
+    def iterkeys(d, **kw):
+        return d.iterkeys(**kw)
+
+    def itervalues(d, **kw):
+        return d.itervalues(**kw)
+
+    def iteritems(d, **kw):
+        return d.iteritems(**kw)
+
+    def iterlists(d, **kw):
+        return d.iterlists(**kw)
+
+    viewkeys = operator.methodcaller("viewkeys")
+
+    viewvalues = operator.methodcaller("viewvalues")
+
+    viewitems = operator.methodcaller("viewitems")
+
+_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
+_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
+_add_doc(iteritems,
+         "Return an iterator over the (key, value) pairs of a dictionary.")
+_add_doc(iterlists,
+         "Return an iterator over the (key, [values]) pairs of a dictionary.")
+
+
+if PY3:
+    def b(s):
+        return s.encode("latin-1")
+
+    def u(s):
+        return s
+    unichr = chr
+    import struct
+    int2byte = struct.Struct(">B").pack
+    del struct
+    byte2int = operator.itemgetter(0)
+    indexbytes = operator.getitem
+    iterbytes = iter
+    import io
+    StringIO = io.StringIO
+    BytesIO = io.BytesIO
+    _assertCountEqual = "assertCountEqual"
+    if sys.version_info[1] <= 1:
+        _assertRaisesRegex = "assertRaisesRegexp"
+        _assertRegex = "assertRegexpMatches"
+    else:
+        _assertRaisesRegex = "assertRaisesRegex"
+        _assertRegex = "assertRegex"
+else:
+    def b(s):
+        return s
+    # Workaround for standalone backslash
+
+    def u(s):
+        return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
+    unichr = unichr
+    int2byte = chr
+
+    def byte2int(bs):
+        return ord(bs[0])
+
+    def indexbytes(buf, i):
+        return ord(buf[i])
+    iterbytes = functools.partial(itertools.imap, ord)
+    import StringIO
+    StringIO = BytesIO = StringIO.StringIO
+    _assertCountEqual = "assertItemsEqual"
+    _assertRaisesRegex = "assertRaisesRegexp"
+    _assertRegex = "assertRegexpMatches"
+_add_doc(b, """Byte literal""")
+_add_doc(u, """Text literal""")
+
+
+def assertCountEqual(self, *args, **kwargs):
+    return getattr(self, _assertCountEqual)(*args, **kwargs)
+
+
+def assertRaisesRegex(self, *args, **kwargs):
+    return getattr(self, _assertRaisesRegex)(*args, **kwargs)
+
+
+def assertRegex(self, *args, **kwargs):
+    return getattr(self, _assertRegex)(*args, **kwargs)
+
+
+if PY3:
+    exec_ = getattr(moves.builtins, "exec")
+
+    def reraise(tp, value, tb=None):
+        if value is None:
+            value = tp()
+        if value.__traceback__ is not tb:
+            raise value.with_traceback(tb)
+        raise value
+
+else:
+    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 reraise(tp, value, tb=None):
+    raise tp, value, tb
+""")
+
+
+if sys.version_info[:2] == (3, 2):
+    exec_("""def raise_from(value, from_value):
+    if from_value is None:
+        raise value
+    raise value from from_value
+""")
+elif sys.version_info[:2] > (3, 2):
+    exec_("""def raise_from(value, from_value):
+    raise value from from_value
+""")
+else:
+    def raise_from(value, from_value):
+        raise value
+
+
+print_ = getattr(moves.builtins, "print", None)
+if print_ is None:
+    def print_(*args, **kwargs):
+        """The new-style print function for Python 2.4 and 2.5."""
+        fp = kwargs.pop("file", sys.stdout)
+        if fp is None:
+            return
+
+        def write(data):
+            if not isinstance(data, basestring):
+                data = str(data)
+            # If the file has an encoding, encode unicode with it.
+            if (isinstance(fp, file) and
+                    isinstance(data, unicode) and
+                    fp.encoding is not None):
+                errors = getattr(fp, "errors", None)
+                if errors is None:
+                    errors = "strict"
+                data = data.encode(fp.encoding, errors)
+            fp.write(data)
+        want_unicode = False
+        sep = kwargs.pop("sep", None)
+        if sep is not None:
+            if isinstance(sep, unicode):
+                want_unicode = True
+            elif not isinstance(sep, str):
+                raise TypeError("sep must be None or a string")
+        end = kwargs.pop("end", None)
+        if end is not None:
+            if isinstance(end, unicode):
+                want_unicode = True
+            elif not isinstance(end, str):
+                raise TypeError("end must be None or a string")
+        if kwargs:
+            raise TypeError("invalid keyword arguments to print()")
+        if not want_unicode:
+            for arg in args:
+                if isinstance(arg, unicode):
+                    want_unicode = True
+                    break
+        if want_unicode:
+            newline = unicode("\n")
+            space = unicode(" ")
+        else:
+            newline = "\n"
+            space = " "
+        if sep is None:
+            sep = space
+        if end is None:
+            end = newline
+        for i, arg in enumerate(args):
+            if i:
+                write(sep)
+            write(arg)
+        write(end)
+if sys.version_info[:2] < (3, 3):
+    _print = print_
+
+    def print_(*args, **kwargs):
+        fp = kwargs.get("file", sys.stdout)
+        flush = kwargs.pop("flush", False)
+        _print(*args, **kwargs)
+        if flush and fp is not None:
+            fp.flush()
+
+_add_doc(reraise, """Reraise an exception.""")
+
+if sys.version_info[0:2] < (3, 4):
+    def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
+              updated=functools.WRAPPER_UPDATES):
+        def wrapper(f):
+            f = functools.wraps(wrapped, assigned, updated)(f)
+            f.__wrapped__ = wrapped
+            return f
+        return wrapper
+else:
+    wraps = functools.wraps
+
+
+def with_metaclass(meta, *bases):
+    """Create a base class with a metaclass."""
+    # This requires a bit of explanation: the basic idea is to make a dummy
+    # metaclass for one level of class instantiation that replaces itself with
+    # the actual metaclass.
+    class metaclass(meta):
+
+        def __new__(cls, name, this_bases, d):
+            return meta(name, bases, d)
+    return type.__new__(metaclass, 'temporary_class', (), {})
+
+
+def add_metaclass(metaclass):
+    """Class decorator for creating a class with a metaclass."""
+    def wrapper(cls):
+        orig_vars = cls.__dict__.copy()
+        slots = orig_vars.get('__slots__')
+        if slots is not None:
+            if isinstance(slots, str):
+                slots = [slots]
+            for slots_var in slots:
+                orig_vars.pop(slots_var)
+        orig_vars.pop('__dict__', None)
+        orig_vars.pop('__weakref__', None)
+        return metaclass(cls.__name__, cls.__bases__, orig_vars)
+    return wrapper
+
+
+def python_2_unicode_compatible(klass):
+    """
+    A decorator that defines __unicode__ and __str__ methods under Python 2.
+    Under Python 3 it does nothing.
+
+    To support Python 2 and 3 with a single code base, define a __str__ method
+    returning text and apply this decorator to the class.
+    """
+    if PY2:
+        if '__str__' not in klass.__dict__:
+            raise ValueError("@python_2_unicode_compatible cannot be applied "
+                             "to %s because it doesn't define __str__()." %
+                             klass.__name__)
+        klass.__unicode__ = klass.__str__
+        klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
+    return klass
+
+
+# Complete the moves implementation.
+# This code is at the end of this module to speed up module loading.
+# Turn this module into a package.
+__path__ = []  # required for PEP 302 and PEP 451
+__package__ = __name__  # see PEP 366 @ReservedAssignment
+if globals().get("__spec__") is not None:
+    __spec__.submodule_search_locations = []  # PEP 451 @UndefinedVariable
+# Remove other six meta path importers, since they cause problems. This can
+# happen if six is removed from sys.modules and then reloaded. (Setuptools does
+# this for some reason.)
+if sys.meta_path:
+    for i, importer in enumerate(sys.meta_path):
+        # Here's some real nastiness: Another "instance" of the six module might
+        # be floating around. Therefore, we can't use isinstance() to check for
+        # the six meta path importer, since the other six instance will have
+        # inserted an importer with different class.
+        if (type(importer).__name__ == "_SixMetaPathImporter" and
+                importer.name == __name__):
+            del sys.meta_path[i]
+            break
+    del i, importer
+# Finally, add the importer to the meta path import hook.
+sys.meta_path.append(_importer)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/archive_util.py b/vendor/setuptools-39.0.1/build/lib/setuptools/archive_util.py
new file mode 100644
index 00000000..81436044
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/archive_util.py
@@ -0,0 +1,173 @@
+"""Utilities for extracting common archive formats"""
+
+import zipfile
+import tarfile
+import os
+import shutil
+import posixpath
+import contextlib
+from distutils.errors import DistutilsError
+
+from pkg_resources import ensure_directory
+
+__all__ = [
+    "unpack_archive", "unpack_zipfile", "unpack_tarfile", "default_filter",
+    "UnrecognizedFormat", "extraction_drivers", "unpack_directory",
+]
+
+
+class UnrecognizedFormat(DistutilsError):
+    """Couldn't recognize the archive type"""
+
+
+def default_filter(src, dst):
+    """The default progress/filter callback; returns True for all files"""
+    return dst
+
+
+def unpack_archive(filename, extract_dir, progress_filter=default_filter,
+        drivers=None):
+    """Unpack `filename` to `extract_dir`, or raise ``UnrecognizedFormat``
+
+    `progress_filter` is a function taking two arguments: a source path
+    internal to the archive ('/'-separated), and a filesystem path where it
+    will be extracted.  The callback must return the desired extract path
+    (which may be the same as the one passed in), or else ``None`` to skip
+    that file or directory.  The callback can thus be used to report on the
+    progress of the extraction, as well as to filter the items extracted or
+    alter their extraction paths.
+
+    `drivers`, if supplied, must be a non-empty sequence of functions with the
+    same signature as this function (minus the `drivers` argument), that raise
+    ``UnrecognizedFormat`` if they do not support extracting the designated
+    archive type.  The `drivers` are tried in sequence until one is found that
+    does not raise an error, or until all are exhausted (in which case
+    ``UnrecognizedFormat`` is raised).  If you do not supply a sequence of
+    drivers, the module's ``extraction_drivers`` constant will be used, which
+    means that ``unpack_zipfile`` and ``unpack_tarfile`` will be tried, in that
+    order.
+    """
+    for driver in drivers or extraction_drivers:
+        try:
+            driver(filename, extract_dir, progress_filter)
+        except UnrecognizedFormat:
+            continue
+        else:
+            return
+    else:
+        raise UnrecognizedFormat(
+            "Not a recognized archive type: %s" % filename
+        )
+
+
+def unpack_directory(filename, extract_dir, progress_filter=default_filter):
+    """"Unpack" a directory, using the same interface as for archives
+
+    Raises ``UnrecognizedFormat`` if `filename` is not a directory
+    """
+    if not os.path.isdir(filename):
+        raise UnrecognizedFormat("%s is not a directory" % filename)
+
+    paths = {
+        filename: ('', extract_dir),
+    }
+    for base, dirs, files in os.walk(filename):
+        src, dst = paths[base]
+        for d in dirs:
+            paths[os.path.join(base, d)] = src + d + '/', os.path.join(dst, d)
+        for f in files:
+            target = os.path.join(dst, f)
+            target = progress_filter(src + f, target)
+            if not target:
+                # skip non-files
+                continue
+            ensure_directory(target)
+            f = os.path.join(base, f)
+            shutil.copyfile(f, target)
+            shutil.copystat(f, target)
+
+
+def unpack_zipfile(filename, extract_dir, progress_filter=default_filter):
+    """Unpack zip `filename` to `extract_dir`
+
+    Raises ``UnrecognizedFormat`` if `filename` is not a zipfile (as determined
+    by ``zipfile.is_zipfile()``).  See ``unpack_archive()`` for an explanation
+    of the `progress_filter` argument.
+    """
+
+    if not zipfile.is_zipfile(filename):
+        raise UnrecognizedFormat("%s is not a zip file" % (filename,))
+
+    with zipfile.ZipFile(filename) as z:
+        for info in z.infolist():
+            name = info.filename
+
+            # don't extract absolute paths or ones with .. in them
+            if name.startswith('/') or '..' in name.split('/'):
+                continue
+
+            target = os.path.join(extract_dir, *name.split('/'))
+            target = progress_filter(name, target)
+            if not target:
+                continue
+            if name.endswith('/'):
+                # directory
+                ensure_directory(target)
+            else:
+                # file
+                ensure_directory(target)
+                data = z.read(info.filename)
+                with open(target, 'wb') as f:
+                    f.write(data)
+            unix_attributes = info.external_attr >> 16
+            if unix_attributes:
+                os.chmod(target, unix_attributes)
+
+
+def unpack_tarfile(filename, extract_dir, progress_filter=default_filter):
+    """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir`
+
+    Raises ``UnrecognizedFormat`` if `filename` is not a tarfile (as determined
+    by ``tarfile.open()``).  See ``unpack_archive()`` for an explanation
+    of the `progress_filter` argument.
+    """
+    try:
+        tarobj = tarfile.open(filename)
+    except tarfile.TarError:
+        raise UnrecognizedFormat(
+            "%s is not a compressed or uncompressed tar file" % (filename,)
+        )
+    with contextlib.closing(tarobj):
+        # don't do any chowning!
+        tarobj.chown = lambda *args: None
+        for member in tarobj:
+            name = member.name
+            # don't extract absolute paths or ones with .. in them
+            if not name.startswith('/') and '..' not in name.split('/'):
+                prelim_dst = os.path.join(extract_dir, *name.split('/'))
+
+                # resolve any links and to extract the link targets as normal
+                # files
+                while member is not None and (member.islnk() or member.issym()):
+                    linkpath = member.linkname
+                    if member.issym():
+                        base = posixpath.dirname(member.name)
+                        linkpath = posixpath.join(base, linkpath)
+                        linkpath = posixpath.normpath(linkpath)
+                    member = tarobj._getmember(linkpath)
+
+                if member is not None and (member.isfile() or member.isdir()):
+                    final_dst = progress_filter(name, prelim_dst)
+                    if final_dst:
+                        if final_dst.endswith(os.sep):
+                            final_dst = final_dst[:-1]
+                        try:
+                            # XXX Ugh
+                            tarobj._extract_member(member, final_dst)
+                        except tarfile.ExtractError:
+                            # chown/chmod/mkfifo/mknode/makedev failed
+                            pass
+        return True
+
+
+extraction_drivers = unpack_directory, unpack_zipfile, unpack_tarfile
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/build_meta.py b/vendor/setuptools-39.0.1/build/lib/setuptools/build_meta.py
new file mode 100644
index 00000000..609ea1e5
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/build_meta.py
@@ -0,0 +1,172 @@
+"""A PEP 517 interface to setuptools
+
+Previously, when a user or a command line tool (let's call it a "frontend")
+needed to make a request of setuptools to take a certain action, for
+example, generating a list of installation requirements, the frontend would
+would call "setup.py egg_info" or "setup.py bdist_wheel" on the command line.
+
+PEP 517 defines a different method of interfacing with setuptools. Rather
+than calling "setup.py" directly, the frontend should:
+
+  1. Set the current directory to the directory with a setup.py file
+  2. Import this module into a safe python interpreter (one in which
+     setuptools can potentially set global variables or crash hard).
+  3. Call one of the functions defined in PEP 517.
+
+What each function does is defined in PEP 517. However, here is a "casual"
+definition of the functions (this definition should not be relied on for
+bug reports or API stability):
+
+  - `build_wheel`: build a wheel in the folder and return the basename
+  - `get_requires_for_build_wheel`: get the `setup_requires` to build
+  - `prepare_metadata_for_build_wheel`: get the `install_requires`
+  - `build_sdist`: build an sdist in the folder and return the basename
+  - `get_requires_for_build_sdist`: get the `setup_requires` to build
+
+Again, this is not a formal definition! Just a "taste" of the module.
+"""
+
+import os
+import sys
+import tokenize
+import shutil
+import contextlib
+
+import setuptools
+import distutils
+
+
+class SetupRequirementsError(BaseException):
+    def __init__(self, specifiers):
+        self.specifiers = specifiers
+
+
+class Distribution(setuptools.dist.Distribution):
+    def fetch_build_eggs(self, specifiers):
+        raise SetupRequirementsError(specifiers)
+
+    @classmethod
+    @contextlib.contextmanager
+    def patch(cls):
+        """
+        Replace
+        distutils.dist.Distribution with this class
+        for the duration of this context.
+        """
+        orig = distutils.core.Distribution
+        distutils.core.Distribution = cls
+        try:
+            yield
+        finally:
+            distutils.core.Distribution = orig
+
+
+def _run_setup(setup_script='setup.py'):
+    # Note that we can reuse our build directory between calls
+    # Correctness comes first, then optimization later
+    __file__ = setup_script
+    __name__ = '__main__'
+    f = getattr(tokenize, 'open', open)(__file__)
+    code = f.read().replace('\\r\\n', '\\n')
+    f.close()
+    exec(compile(code, __file__, 'exec'), locals())
+
+
+def _fix_config(config_settings):
+    config_settings = config_settings or {}
+    config_settings.setdefault('--global-option', [])
+    return config_settings
+
+
+def _get_build_requires(config_settings):
+    config_settings = _fix_config(config_settings)
+    requirements = ['setuptools', 'wheel']
+
+    sys.argv = sys.argv[:1] + ['egg_info'] + \
+        config_settings["--global-option"]
+    try:
+        with Distribution.patch():
+            _run_setup()
+    except SetupRequirementsError as e:
+        requirements += e.specifiers
+
+    return requirements
+
+
+def _get_immediate_subdirectories(a_dir):
+    return [name for name in os.listdir(a_dir)
+            if os.path.isdir(os.path.join(a_dir, name))]
+
+
+def get_requires_for_build_wheel(config_settings=None):
+    config_settings = _fix_config(config_settings)
+    return _get_build_requires(config_settings)
+
+
+def get_requires_for_build_sdist(config_settings=None):
+    config_settings = _fix_config(config_settings)
+    return _get_build_requires(config_settings)
+
+
+def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
+    sys.argv = sys.argv[:1] + ['dist_info', '--egg-base', metadata_directory]
+    _run_setup()
+    
+    dist_info_directory = metadata_directory
+    while True:    
+        dist_infos = [f for f in os.listdir(dist_info_directory)
+                      if f.endswith('.dist-info')]
+
+        if len(dist_infos) == 0 and \
+                len(_get_immediate_subdirectories(dist_info_directory)) == 1:
+            dist_info_directory = os.path.join(
+                dist_info_directory, os.listdir(dist_info_directory)[0])
+            continue
+
+        assert len(dist_infos) == 1
+        break
+
+    # PEP 517 requires that the .dist-info directory be placed in the
+    # metadata_directory. To comply, we MUST copy the directory to the root
+    if dist_info_directory != metadata_directory:
+        shutil.move(
+            os.path.join(dist_info_directory, dist_infos[0]),
+            metadata_directory)
+        shutil.rmtree(dist_info_directory, ignore_errors=True)
+
+    return dist_infos[0]
+
+
+def build_wheel(wheel_directory, config_settings=None,
+                metadata_directory=None):
+    config_settings = _fix_config(config_settings)
+    wheel_directory = os.path.abspath(wheel_directory)
+    sys.argv = sys.argv[:1] + ['bdist_wheel'] + \
+        config_settings["--global-option"]
+    _run_setup()
+    if wheel_directory != 'dist':
+        shutil.rmtree(wheel_directory)
+        shutil.copytree('dist', wheel_directory)
+
+    wheels = [f for f in os.listdir(wheel_directory)
+              if f.endswith('.whl')]
+
+    assert len(wheels) == 1
+    return wheels[0]
+
+
+def build_sdist(sdist_directory, config_settings=None):
+    config_settings = _fix_config(config_settings)
+    sdist_directory = os.path.abspath(sdist_directory)
+    sys.argv = sys.argv[:1] + ['sdist'] + \
+        config_settings["--global-option"]
+    _run_setup()
+    if sdist_directory != 'dist':
+        shutil.rmtree(sdist_directory)
+        shutil.copytree('dist', sdist_directory)
+
+    sdists = [f for f in os.listdir(sdist_directory)
+              if f.endswith('.tar.gz')]
+
+    assert len(sdists) == 1
+    return sdists[0]
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/cli-32.exe b/vendor/setuptools-39.0.1/build/lib/setuptools/cli-32.exe
new file mode 100644
index 0000000000000000000000000000000000000000..b1487b7819e7286577a043c7726fbe0ca1543083
GIT binary patch
literal 65536
zcmeFae|%KMxj%k3yGc&ShO@v10t8qfC>m5WpovRhA=wa=z=p_%6%z1@blsvwI0vv2
zNIY4alVK~j)mwY3trY!Sy|tffZ$+^cObBMdpZutbN^PuECoa`kXb2K>zVBzw<_Fq)
zU-$d^{_*|%@qt&)nVIv<%rnnC&oeX6JTqHy>n_PINs<G9rYTAL@TPx0@%--}9r!$a
z((i^#&t<$Zd7o|Z8<TGd-?_=NVdM9{v+=gOJh$I=_ub!9J^yrvXQOtv=gzx5rAw<k
zcYSZ|9am>%4a-Xw9jfY!Ot@}WQUBkK=MqH|Mf{(O%J6=?F0E)R-u5-_q9XB5EmFjL
zRMB1HZ7a&fd)b}0hpCKjVjS>G(qfxk>Uow`_J8Y;?6yo>h9td;lqFW`r_=Cu;je?@
zJ}aCeNvRaYzy7!6vsuJK8t7Ip04X137Vm)<B}y|cNYZo>`v3N5I`@q}=|CK){8#_3
zR`1xV;$zJbJP0ppD|Paae;!F%bM?lxx2d-wfQV@O6ujTW-;jSkRCTolCLPMh2Nx=)
zGP{NVA?TB&mP=FqZ|whc3RJSvJUJGyHOs!nBie<k<-z=e)r`kVud+vM0lsONB<Y9b
z0<+))qcqReE=`GTutop6y*iN=`x&*3EzZknc4W?3rP&uIJaeXK<D%wvS9N4nkT;0D
zPW$-+vpsE9St6ytWVaCXsHU`%GVdR^wE=Xv01fto0vp%r_OvPOWj3j{W@V_Y;fxbp
zySskme5v4&(U>PA7G%%m<=|b-UJ~!-boN$bi#jT{Hcy&A=Niq?KHpr`Y-?=MzKk{I
zIl-)f*v>o`q`5M7OP+gKtTfLZsOCS(qPDr~x8=!_5`6-VLD0EMY5XaI$Uqq@V-Jap
zR-V}6Ja=V~*CHdz@F4Rb<?;{KZ*yd>ij_JtwPEG;g{#zT!Uq*Py$3gDv`Z2tYF|X8
zYEi!^3#I2mi!9?8K!AuX>_C;=ltI=m5eE7*@I4UZ&p}=3ho&bc^h3P|C;`K|s)PJt
z@!8GLOb})@Yp*SMou>fLhC@WZw%7ar>1Sm0aW&hPm&@Wqv5z<cJW4gM&zmkfJJ+a@
zj6&r=dVrlbR^{dLe--p{MqAX8%7LY}g_XQXq&T82+UL#6!luP}xs6BE?<fb3E#r6f
ze^S%+ZFw$9UEExnmrHC?k~jf28Qa}v(?%Aw6cJb9i=;f%LL7GNV)O&mRYm+WAK2)J
zoc6N?AE0A$CG}^`sG(_iS>i_&0GwOEjRhPMrYB*+WA64e$@ELiFO?ay?gvgcC<n$Y
z<L^1CK%h$vSZG@q;PL(x?eqG1V1nyS(*z5;SA+M!_HB5xgCaCQzioLANgKIa^30b|
zP)0-wnAuW?PuhpB1D*9VD+*d7r2(|XN$tU(8-F?I^V~ojiGY&$x^&Sr^ySP^J_*UW
zrARijT__0kuL5&8h*xu#MI`axM$bS5AWndQ;JM+aKJrO?BE}`X#TVcgz$PT9E&8Dq
zZ6JXIg6WKy%Zx0-)XbKtWRx0n<OM3tY=>1!dbl2?B=#{!9_2$Llg!~3%n@58CG`RW
z1LPlkk=p2eFSa3N`&F?g@~A1mHitQyVq0yNK4^CN8joui^5gTpuf^0f+qMtEYVL?F
z$fu`~#PaZA)VQ4Amx;XbZ%EJqQT~UlXZwx7HHW!>vn=MgCVU7v0(=qWSe%!~9KS(N
zgLM=3LHzO$mU+*{wx!#)wXd#auhgvU=lF&*IVnT+hZ`~0nCHPOETKA3I;S!sQ8$^{
zZcv4UbEsTEpxvZ3yazYCQD1%G)vA+(ndH~oy5$RmDNA{h9?j)8QlvdBd-|V!63d!_
zr{P-1vS(7D+|itM9Rk61MnI<ijY!Ly%7^jv=YUlg`cLmOwOJ@HClJm79G^?wO8q+)
z2vf7m?6nYbY6S#*GNiuY5H+x^+G@?tJP#TL9re>+K~KhBa?C)KKh+E*p-K?e54p;H
z-uNb0vkbWyR)1lbnp%G$OG`vjpo}PU*o}&pp;`PEODluTuiNcFBFmELneD_AsyG+G
zkGm*r)oMJHmxrXL#=Plxfj%;6&nXBm<I#%{teK#)2aU^vKFj+G2|d8ZfX<DYT4pfZ
zfo|^HD@jrnxXrnoJ(D*BEsHtwkuBFp`spvA2GpIQLK~G_Fij)vWt2{I(c2x~KW)!t
zCOE{y+%GQUQ^og%kazlaaoZ=NV(uK8O?>)d`#6i)km>UtDzrb-*V{hPU&@;WB&3=+
zxL1-^s(vuM%+x$5wc!b>TMmX_2j=|8Kt*)b-4;r#_ff_ny|oEKpX@DE=!THWD9l;8
zEWjV=HO&BTAtLP*tp;IMlM0_Vn8(sUqI$?Nv_U1G^tEZC@of=jxa%BH_{Ai!MYo}y
zE@)vjviC#f;TCVZ=HXtX$EDFgCrJNz+eAX#tsgc!-#{X?u;vu7>K}|6xr+Y+O$ixV
zZ+D5)r){a?S581&?=jW!dQYD^njLNZDwQ49Kbq9~QJUTP@Z(p`mlCNjK7uj2dw$*y
z?Fs@NOQ3Fcxb;G+-Z81QBhBuJS%CWlpf9gp&E>m+$xzI$NMcrT+APveYg4QEVhkj#
zC+2qrf~MxI;{Q2Zk_`Xps%rkG7-Dkc{@y;QZ4Oz0#y`#fgd*BZP3DWK6>a+@*L<mM
zcZ+wv6pXlQp*qv|N$8nGnzy|!owe_wFT`9w_5eJz=cRm7?ApYLBWTQ~Z~Xh0d`OLq
zTT$CqaQsCoH<7xV;0<Sr-s;g0IvOs}L}lA&k-l0$xByYj4z~8BGDno!&c4z=oz(hi
z8grx*iDYlPN`q&LaV@ehXt=Ne8MeK-x}c@DjsM$J%twl6LU~JSD&H^}!^3Q<i@!_g
zv@vrzI}>D@EZXPo+Bl`5Zw>0+GLF5OFNogis^p(SM>i~SO7+N+7^b&-f@XG3hYwRL
zs{rPg^&WTKXuZW1;J*Vf^E(^LEqH+VoqCH0;~Qle%pqFtZQVGjSX7wPu*PZbFwOi{
zG*lGy6QCZdX|wX?4#`^~>lfT8wQf{0k4{L2{|oR+{f=JfFn@0V9WOeR5QLU=M!U6~
zB7d(sir<zi(J(xWuRwrR^cpgzK1ceMKSTyn=7h94qQ})c3tBJ-kufbC-S8FZ{*A-+
z;wE$p2;6zcG#Z^Q=wCTDUVHvM{Uf{T%s<wYuE%Y9r%meyA9u+1R(iScdR70ky|pt%
zO*{K56g<p=`;6dF!Rj_V9Z4Kex3fBWL}~ny1nH|{??HFC&$rtV!@%g$GEs~YjUt-3
zyg5y8xAoVl=3`2GjRmRwg}nzj?Kb^myE<wR3=lWy37hs;ROnh+ySnXsoC;P)_ZOlx
zK7zQFs(oe^qFNu3t$Ssyg|9J2k2}y#^%uW0`}(%CH2YD#%Pcs^MniW#E!k`h>Z!)#
z>Ws#2b>jJh;6zDv(pxgML&lgyPQ#zcbb!!sgpiDoqu{tG6%!Ja>nvz7KufAa>qaA#
z=oV|HC9oE}Y-%~C<~B7KIy+)gcYDw!`k|a8<5gBx6?_n^Hfnl`YGk#JRXDw`Y3W5Z
zF72K~Dqd=&sK!kRIocXZ$WcQ@HMx}F(UwwzM=dX^$<yW*)lApsLU0ONe1#L$wDK}<
z+m`P7xi@OFy|1a`^g5Sax&QBIL?i`BM9fM)?J~l{Rc2^%VhrUz829&peWXrWCnHlz
z(^x9cG-`TL;&SCcT7aJf@*!}hy(}@hIc?50YSx@pYQ~(aH5qypGnehQvcielAG{aU
zX~0_@&*J%hxyYZhxenZpYC#MBj39u^sFM>J%<uNLp{5+>??vDyuV3EiM+4QdBA;io
zzdv6tSFL<#t<s2TfRwNG7HQKrPlW>QrIPdbG7F+JhObn}j(kln(mY$%K{!!5k#)1E
ziz+3WTCrR!=CNXVR%|-O_{kh9N!CV3M%Px+KVv3eg)|H^tUYmMQB9Bbm&lY5<g+!A
z3q(W{bNLa7G-%8GR2a%BXjxsm@<>uSRpgw1Z~T#cB&t&nSAs!Ug_}|kVHMz$WCS?l
zqwD<1@hy6X9b^#7A}+?pyqY#|7U^Uy<!oE$R#G6OIHC7~?928tC#m||`Rwb!vt=?X
zUvCU&<zZuqgAMm)Z5TgaQb)3^o#QYflyA_|`O&KZm&VE*-qc-V@o_Xmrh)G=FTI?~
zaUiwZw;@Gy>*X6#P>C%ujL9h3=b(@6wKWGF78?2)w89yy=;G^09Q<ASzGu)Qw(X;0
z{;ohoCMo#dETWJz;bQfN@r_l;$_tKiy+f|A>y^}WR?(y1w&Cj}$@F5L2YsfEL<3pY
z8Z-dF^8sAbhP4Aqi=v(obhDs>e#QftDyng66L`)T%)98HH5&8BF<Y>v2#E?5hTb_9
zH2mD~chFE=MQHmw0&)Lo6u2YqKeGV1@zG*g<1#Bwv#zb_%-_+JlMrxKd<~ir3Ze1+
zy(_eP6{~SYKhV+(S~~v~1yt)79UHaSeZ5h0^WBheRNU;+TO4|;1L|kljg`GxMRVY5
zgy-B?`L%XKbD$65%Wkaf(<V0uOoUxGf)z4#f3Kscu6N_X#60DBpQ${*$V`+W)Q3=C
zVh%!IBlLCRI)r)=>P<|yYD*~1E|lWFafIgb%{TqMMK!$}&wwd`weq~AJfD%@n)sU_
zUiHfyy0+TP&cgr)(wf;G1RCO$+F-8vOp><HO7p|jNn-Q6t|xsd^WT9I=Ikc$B){h>
zOt(p4nn%&aNx*RFpHZMF4f(Ufvk=7?JRPMYo=R06O@dN!hp9(J{WAdZdPL@b!%!G%
zLqHJ$fo+g=B{EqW3P?d+m=J67#;*QZ08JwbS`rFm!NrD0j{xSFfN^d-(+{H;KZnVO
zq>c^Kn`akV>TQ^)nUX?$=?!SjnvZ-^xEv3@Td*3+ToB$GLi`Q1f1eLu;*Pvh0=OLj
zdhtFgHl&UZQ-JSB8KgFySnsCLa+gvITEM<JVb|Z0=_NNbv&@H6(`bHB@Igt@ghI@c
zl*U&;NMph*gq!`YU((D;uXAEi{}>T?_A^wxGy~aKk5P9rYN}h!*-ueoBA*hw4DFOr
zciPZ8^v@j#d(UsI=5c%~N>l%e$W7+;ycJQ_!+(R9k!HS|Ec90*HCfot5kX%T)t%N-
zi~Jqxa4NIzB;-ca!0JvWei7b)=I>ieG+2$PYbd;x;wr_LQoMggi&;CG;F7fIhG-(%
zJ!c$nrEc$qdPCdkvnu1mRQk}y|2ztlU(w@aFd)D-lsL#-NVQSwulrLY!m_|0v*K-t
zB7y%f8D%CG3s<7iT|s_@7ZVu%+>P|Sc?3OwD#DH8xgHD=<f-VsApaaa9sX=8nv;#Z
z`k}l%#O<|7rBhsro=L%+c2xoT1-LwYZBh#O<!BUXr-(Z|lREpYkzkpMTP0~-Q7W02
zwZh$V@M_pc5wh%Sm%o^4qt8t_^m(klPsMxqW>>+Hq9%@@@^GtBaXR79?>LQ?^WZ#C
z2`ni`a{1lFpInCsiUb$05edblZ^2mnBP=hXEp>8aJojRG7BaJEcKD<{j}yzhTP#U?
z=Aa#XBtim8=Gg?r4Uj`5WN-&1pw{2h8%&)Z;9p{i7uubJoO^Qd2$-{7c$u@ERF>y&
zqN~6wdfjPB!z|)D^aBs!k+_=q&oG%~7!{|m@ca2}v;&KPJ2>;78Umj~@P&9JSqLha
zzlFYP<2&bKzVZaVB-Mc?2YHnu!LA|`O$fbh{3s#N;_-HA4$=p_MZ|rGufc4|OmzUu
z^JPvljA~1&s$+Aa<w()zNx!G<0L@dyGr)f#BOMeS6)ST`QZT9-X)BDf9E^O4EH=;B
zE*o==+8m?Sfptj=P=j*yt%Pm3WkA!^$&z|GbdnQQQMu~aAXl=XRo6Mq&w=2&97(@S
z($~pS2zk2aJAG=JelIfRnTs4-Gueoy6w{_W-;!`D2U;p&H9!}KX!)wyGt%13G>Z>O
zBaXr}qS-H-6;8gFl+j!hB|&HG__QCH?uAZY6+qd0>UH`KS<+@;OtPgV@|*2uh0NaK
zb;wtOjM^yvHpr<LUa2YUt!L-)wNxOQvg7UAl}UBoaAs>tzb)z&!{3Y1&uQu2YF0;6
z-&pJkNPw~TIeP9tMbGFy@$3@M*Ts{I=TY%&5zoVT@~P)d6APo+yaISwqj*6}fd26l
zSTkcVuiyVH03~%8i#~&ZzGlPMWCA!0Gf#IJR{FI;?gP_@en$)RA<KPQ>9elZzErW?
z-z!$}DeP6T*8k_BYkgYiUq~IY)=yyvyM1}}O7uIRM!^y9drD&sLd~O$*hyeu#5%<D
zB|MuR{sPa&<4WTs;8UXSCjiNK>=0hc&P=2=ADrQtvtr8#<-kGZK>Z2~i+YDr(2b==
zcR`DCps{r;k|OD?J&uqOeF)jSt;!F64YPom7yZ+9fQ}L6K;B(=8G8lk_6m~j6~x@z
zCDMtQotu#j_2}HA-lTK8dcDqNby|73nvIwet;T0PM(}dy%>!Xa=e&Wit+N2(1_4tK
zJ>Ho&@F}G;2jTj!uGD5=No4gi+tKUoGxifUO6&p|zC}*Q`Nt@!^HZd-C<VXUGE6z}
zYOGW~YKVB}>-c2srIvNJB1pwv_RV7Hs}lRAC|1y*^It@P6dqcjDCIs;$|7}n{a0bN
zwEnC0YEJ!ETa@VSNVnP}A=G&bfqB<!qf3&BkW{O;I*ahh!r#?-)j-(OIT_(*`<&~w
z3HA5cW@%$e`m=&S$*g^tLCz@<0M`kCCyB^pUPuD`kpR{zjc?QYPNne;dVddtKfN`j
zaX-DcDvf*Ty+UdHHQvTv;)Yn1ge#yte=uO|J&YiKVh)%++R_{)&I_qiSd0WOwwE}M
zKLJhMY%j5@ZER5*pMVy>1mb=`bXK5zVw9e>%7YwwQE9vvGOqVjDG&Y)-L5pEZIaIC
zt1d9l3jE3C<x2EN7|!Ysdg9Sts0z6xi~B92`HDn$#vVI|kHS`EJa!sEBl<X=N~|0e
z#G}+#WRvWC64CQfBGXLJSBXA?#3B7;AUgP28#eff33<>jm|E(KL}PG`1?WOK18iyR
zr@EEK-#D<=?b9-MKLq7qL@AMpXFN*8q(*e^0F2H-_4k1j+Inw(tI~Km%BD8|oIZZL
z3U#LP!ouD_m~3*fC^b0{i;`Lh@J}(6VsVI}X;M5&;!2eyMl~<&Z4!WS0Y`~eMhmOX
z*{Fz-wZUowjBH+3?(n{;&a#?E?5n&i88K>u>i%i|!DBr`8qsAZj-fVnlD&ENu7UOj
zcr8tPJKsdI-m^h@@FMC~8b8KU@3}+S`I1Qgj`G7<7-#jKJJoyip1alQde8Ti=;Qd-
zEqbZmLK{d(>TSv1K-&|`*$o3Y^LH_kih}8`ftlRO=24yNSd>_EospK1t)P)MNSMz5
zMFbXV!)H|iohdPqaK2TlCsdyXsw|yVJM_5R`8Fcji2AR-qupV#6XH@LR3unydzvBM
z4f~1F_TbC*c}(zSLwgMXgM4Bpq**9!s9VzD=qH!e1;$?DRCY2k%qp0&7j#pf$VRk@
zJ}vAuqB{{t3Z*G@GUUh<RahMtFhwyjk)sMzr4_lDBo%wm1?Ew<pEzDWl-uxWJxW(S
zme6Q9$r7u~*=q@WxCI^x)$b=M|BjXmCLRK`hJZRJi82A?y-FLA>=QH+(oZ~6)oG_G
zm7oW8n-SZG)I^@nHz|$JLoI;48x87n8XKNR#<&=^F9+-;eGV0gPPh}0%>uwt*&h7^
zikjIJeH*WM^eCR-1*y{y7<3vkDAAj#<hY}|)uZNEl<988lt+1aVQ<1g!t+y1WES>P
zqW!0sNgW>q8t;8)$CzynZ~LYZ=TGX#rStC(HZCa)yTB3evmPy_-~(OswN&RE!Vcqf
zp@Gi}J#;B+uy|&hmNr=+9n;P-K_62nm1xV3H2SPw#e|IhbXfof`+6|7-a1piP-HwN
z7^H{2zdg+^sM$1pNn(G@e>T6pEQuKCV2I4dULmNrfxpt(oApIA)u1V4mx*V)ZKf|V
zchNeer}=!|H??#5LN6WbNlX_CYfykKg_THOR9^_2FTwuZg0(8r_mh$V#aE#VnGn{e
zeCl;DfP%p?tggB$k@J+TKa!uwd@4m9VSVvf-3M5SiBUWMu?`fM{}^?u#Rg7oj438}
zF(JrR5f9(+cj98FDW)K7zZihT$5@OwgKx%nE3=G6vK4Y@Bde<-Gp$1S)m91meo|RL
zn<`b;MO(K26BC3>4jV6|nK2@IAd(jIpM#El1d*~p8E?Q^LTFiSdXY#}J?38eXq6wU
zILE&{2PF4XZYiYgP2}og_GW_ZL=T`a(o6hRfQ6D1w{88ns)Va232{Fagx$LRq%S0O
zl)0Az+ySZ5pA=~!CT4ui_9ihZH^Qxh#U26>6Z7Hbqn#h2z5ie)Ybiu*0bt+kjg>s@
zjA<Te+x6L%J}EKXCyl?tC*6y`SMYZff1{CJnvdz?E#UyIH1B}!gaNm%H|Bp7#ui@(
z%oNtXQp6YWU}CIctPO>{aix*=UiZ)(*qFTw&sY<UCyANuK8K{sX1gzSn6XuE_vK0L
zzG=hSeU~9x*zTJ}dxI>C@-?(l4s4*jzOJb5O{H-dahv}rm2DF96vkFyo8F5}t^)$F
zZ(9oMi~Bo>vl1%_AO0!k4`R(0WECATr`T9CY<emo<caMP7+pC8BYll5)vw8`??*{r
zQwa1doJQE+frH9%)8A24O!>DxmPlhFq~FmY!A0jT?5Z*B+?Z-mztE>vHrpWqH$Nq7
znQ$bS14=<K=P<2<wbKUBCzDz~Nwd$g_PdY~mJ)PknIrr-mL;(=XMopVX(6vP9zl!D
zG8t8u=>F3%*>!CDalr@dER`@@Y?!6d@*<PA64UCJIO-D{+shmcuo$LBx>vxe+Ey;C
zzAb-8pA`ZV>?nizOJLlY2g_U%w^_#AX+&7PCq<)De2EOb$F4aLln1f;?205wZvaM#
zVFVXXgXYER?xJ1UNedWLbhw#43pHVVJOXQCT7oAT1xqP@drH6g1<S->K{s|^C-D8~
zII-`VG_Cp(PnuTk%;)M~Y9hy;0G87Oi^b`fGFXmJv{=-iJc*G;s){U*MNc7w4PZX$
zFG5NYGosTWBeCdAJRx94bOr)R^%*-w;fF~?jmJo-7}k16tTxu|e7FZm>vqP@h}UDJ
zMb_<%9ulu7Tg2<vB$|&tC^RDTJ7N`%xTwhn&1g*%jMzDVutmMrtSTNQWXCw9mbgHc
zSQk?Rq?y?(K)r~>PMX=bAQTgbqx%Agz--_|=gN^3-U*{nC`=`o*^BWB5aoD5zDc^L
zbCPah$}ndW(fDOKfCnSmYs?O0|98q>)A^t1Kmi5fV)^NK<0K|?>Ztkpg{wAx87u#*
zeqqFx;gPHrpt<9XQ}|ZXmRbrVBf~@9!{b|~w(2b~o%2V>(ripi+vjs*FBxfV+~`j#
zwUV4ks{+SXm<c0&r6KeC5rkopzl66j6a9?+$nen{e9~GIIv0{&3jd(>d9E1#@;j=6
z)uOkr_4gLM5-{%ICcH@ey-Dse{MZBUT1zu282Bo>*21v||3a&=U&8)UQ`x`eDO#(a
z$+2t;o8*GowEI!b(%StdRN6V}iP(KElBg`U#9@D{z*)%O`vf>Iabn-XiXWl4ADbAC
zbxL$JvcOIfTh5KDUbfOny8snu^oxD!YWTy%94p!42i&pJ2V91~3)1fIfdSdg-sO4d
z0#s^?wrun5SjhZ6>?CT{-mI^K=Fel0?4c+GlPClQ3ODjHfx<bfb!|YLTAMfm$~F|;
zzUi(GI2jc0gto%WFHCQ)PbR4%le@x}%Msf$Gn>-kp8?Z8kIzIS{LZ2kPIYA1qR0t$
zn7?WzV-v+FcYYJ4Hb@syr5~l=QXFk8m(jW!<oq3}hoUN{(zpzPWU;St4WBx5kz$$J
zstdZw%J~Xa)f0lN%jHF>w}53gPr_z=9*MvMv}fS8675hU*yDz=>Qxqp`&p8$PzafG
z#m<%=%AZ_k$Zh6-SXSFN%1V}W(ZY$4no;C;s{g~%TEA5qZDWZ>Vk4~|HI(T3pO(1a
zDly^=Z=limT__6dNkqF<O)qXlFWR+|h=Y&CAT5mkLH;f(3SopqcV`3xyoaI#cJoZI
zim;&G0GtxTkTVqo4z&eA!rAH-<PNvS(l(>HhpOr_vsaOh;YYEgH_}4<XGm>}xWc;#
zn?;DgBeLc+Ou7F;1!12zVqb04b$E-(L8Pvlop1dlMR<bP+lzA4QYLl#oVuz6cm(EQ
z;W=YB{ik))y=}SxV~#Y-JE9cTiWGBJ8vh#n6tWyja?=(jex4Nl0ne6Hft8KlkV35y
z+y&dDCbKdpJ6!*f9e$D*QZ(PwG9*?lf;3mNx%oX9!Dm#%Tj>sXK7|7O2c;w@PH!A`
z$}(qT%e{);@wHLrOr+~eoF4r(b2T#R>l_%jYgt>r>5{5}aWNyvNppn~*97@Ca5!n)
zRB&u!64`2fsMa0iy>Oxm@QbJ?bpB*$d`r@}3#0zCM9#0Uq@}4Awna{XqNUUrOuWc%
zslzKgZj_jgN(3Qdj%SMs)!HOMgJ?$SA5m?n;P?V#d2f=I&$4o7cdM>mQ?y*xMg;gx
zgc(g7CW7dRu|;*V=I(Ayq5ilg`3a_A7|!c@Ic8!~S)viH$y!IUBc2WN3Q-Bvj^$c3
z5<sx!+AtAP?XbA>`_KmLmGEEV1Gd_1d=iz5E(t<VUtR&}*5~|vF-8WPHZkV-dpSZz
zp_pr!Gxc~5uY<A@^EYRi-j}!SIA#*7YuofZ0ZDU<FPT}zCJ=W74^VFOBqlYZ^z9Ct
znpJI{sOCq(3^0R-^me(SFPx2e+bIFLTI}*=5Tu69@DqdIKdD`5F%49^IqMZF*38aD
z71(fbhEG!8)PhF}%!TM2><dpIQPFbva~SF(6L|_oSg~2j>p!M007t}T351I#sty)U
z+#Si`84w_Buz4?P3V#KB5SPf|6%DG44C5i97KEp0qBcViqnfK8ixAqFYTieA`GW(w
zAaRLIV{Rh7ntx26`g<b-#gL;{Hz3<k?DQn<ll%HHt7-aNNgEa5Q|P1E;2FVHjLjkQ
z`T-Xxw7Q2{9Y#SISPD$<Tbr+rbgU>ie*R0Z-#Na;r%mD}%<5Jvs_7s90pggwVaNJy
z;Gz5ncB#LFXNdQ_W-sV26M91L>)3K<zv8-CZ&&nBu)9dR+1}I*&}Lh1fJ$0Sh=Bu1
zZIV!tHtTQUYHDH4Y44xZ5%^qP#jpQBOzXUV(rydFEg-4H)}rs&NhB^VDy~OgsRcp)
zBQj;caunT&@|oX7tBL@ERuek?2okS5fdLs%LT$*NCE(OF3x;97gEqE-ocb9DFl2Q!
zgtm63uT#EgNyte@*InzB9Z1=+&_xdqJ!aCwM~?tK*3e@^?B#m2W|4N3p`^dmSjEDp
zr5EJ*DeEctDj!a93cWB2&A~*29n=53!&rXK`>HxJ|5fbYYy!?SjKig2`8l{-`R#sJ
z{y|JM;N@7?!z#|5{daszTz&pedK?9JQ8F;@qU0|0D_iceAI?7tSL#Z>U6e&#kwgbP
zkkbtwSlf+Cu<f@_ncfPo253+zF_re*BqkMOz=e-l@dSF=3tHNe6Mx!NOm-RZ<2n>!
z2^i*I1ua#Wv>X0&z_aSn73?s&*dqlVd-T@)W9p>J$FO7ZOZr;Fjpb*IiZ0<kj-=(t
z)3frtzZVEN)Zu&;5GEyyDoKyR4}t#_Nqfj|4VZ{Qpi+zi1s_y<&#G{Aa&GbPMOY+9
zMu&t)2l!LwN5#q;zBt0;6CDn2Z&SxMOE<QuqarD*i|U-p1COE7rnIv5v>VIdYQtLL
z+vF=8tIkQ-iCW8@Pz=4^uQuJ=>}nca<}1w6IQAlU`d|lyHiM6o3qDTHh2A>nrl2_S
zA+q^%P|?VQl|Hvwh66uk?P7j%C%U{@zVS76a{Yy?)f|yCw>|CZvLrN|l>4FS+vXAI
zH~1Q@M_VFOIwyh-O%sQD3<-Z4nfz%+pMuT$dA}3f(Y)N<c#Ca<Hc{-Aj|5{d<1iXZ
zo-tGXE}|+3jBfS)BafO0JZ&L^nBNGx!%&i(k|jT2v%Ep@)Id7GlWuGz+R=G5+`2DW
z)a`k83dV!1XXu&z6g?+ALC@Kb)3f+dJlE~aJ}h2YFNxQLN5m`jA@Q2FOT4byiPxhK
zrncaPvkrTn6K}_!eR#*Pnmk1DXa@$0c&dc34gYu3$34$Yo-f5ypTaYP)@Z5EAVe%L
z79fULyzOojc5hm0T5GmFJpjT`w=@qL21F6dx9}hS>_d<iZ+bBSNLanucs{{|sq9Nu
zZ%5j$dIA$Db&Ad%>KL78sm^jCQ2QJXENk|S6i>1Swe1^0VH!|z6vhVJ3d~qpZgqg?
zzXJ`{qP%dJwHn(Uw4c1)+4_+yvo*He^{Zd~>O~p~F~0$D{+lmT#%8yz$>m$BosT^*
z0nr20&}O%cv?bbkjJiUE8qVZG$Ol*3*xZhC4DtbUv%|~|qj@h=J~GK)1f2?6ni^AS
zZU9&Mjpv%9p98c#N(mlVtgend_5~7@=MO8-+r5XkjLvWM1!50n(f5dF84tfLw0Q}(
zm*9+g613dxj758q1+@iGGXVyKBgR-iD*K=c=}3jXt{(VYjZ9Vis|CbfrAYwv)gXY_
zQ4v6I3!prr+D<=J)7@%Qhu1Goo8W5RnM%bbM$r5yo02?~go2uOrV+Uka(kl)NYvB=
ziJ(Qrc=R;N`2{d8IC6yuvxg}q);OGU*^kC<_2?JJZgJKx9*$a$VY4ft=wFT9f@+7O
zj$`$od74}ad%Gmf_rA69AldC`VZZbwE$pF`3rQ)z)dl0=BiP1ZJ-dY$-og#)1bxSP
zNgczsgfSnLVGH~D`xwSpJO32GZILW~7K4{qB>)7j@ZQ<NRquK%CdOgGwE<m;>40L*
znbh<k|G`<n?<OE)VVDVMWCQ4WfcB5bU=AtqL#CZZ1^b}qlhbb~9C*-Gk;ZxAT`V0Y
zybkv}y{}K37*C}jNCD~Cih>GjdU1BZa@I@C(fhvEMh*p00h0JY@9QPky)JkP4t`7=
zqP*~?>!A&M*52<x2k*Th{F-zns1|+)7*@OCH45wZaE#_Jpf@pHc?`&iqX9+x9zkQ3
z#(yT{uqtVpS=@!-#!nke{xxk-Yyf0~*(t(n5msJ^!~C*MP!4Ndq{RF@00SGz1&Krf
zl7x`PN^-FpYdVe!k1rrQ)O`+Ple1_!S03m=74>zWqxiQFifLao4{wB9^g%?F=gS~0
zM>_u(!b6Igk78KGX%zF_BQvo$i2dd%>Ll%S;>zYS8{}-d^88%#^8m>@n(H6JN4eBH
z0j1d%dV4m1hFL&aSv{tK$Ix%EF=8gH*LA?R>-5G>76)qa5?U!q{5zOkM$(KDXRO2(
zGaf}bx2|K?&R=KDobU79gq@AE{9S-_z5ubTUu>V?@OfJ|ccbj>v{^6<LJ%vN_+lT5
zs+VQoBJBbzaqyAIfg+76Ibk<ohp|+arK#>CO_g}6Xg2YP5?z6EY1!XzyS@qf0Ycyo
zuOK0K^{@C^(P8ojvDHkzYo|CVWwttu893J<y#^+hB@U&rn!3T0f)?HX1<Az8=m$z;
z84_P?0&WlocJb_!`cw(tn=;==vp-BaJ7}^<vkj)5GB<|@BxD3D3m20zCAX#9AzLA%
zHeAJuNh-{DyURAfZT&N3>rN%fv?<X)A_D19F*sY|SK`=n3hiSh@}3UycJ4WiH(bHN
zbUmqcI2E<H#I??F`i~;nm*C<{G3o5OtmefzxlK(?W9UPt^?{_R4jL<mG)z;|t{nRI
z35>GnumQA32}vG6{NITX#smVXGT-f&W{?OLdm#JQzu|LRVj9_7JPjAE=2mf)a`9Ab
zAy_6`@*nHK5Zl4;M_QX+{4AWn;AI>6ng`K$p?E4K0IPv1nYAu|;3Z1JysS<AUUB&Z
z&@#*(cou0$s4dFTZe<VbvtnZq!)oOs{F}_@DHn%f0h22Bz;l-Xygvx=wvPbJ=czn?
za4`J^1Sw++(os(-O7^h_4k30Gv1ow*3jo*yuOlp`=K1je*G1A%BvDKgg|#5YBM4&7
z6Fcw+#8`T96Shm$F-4CMRvOmRzlU3yc>^y2SSS?R4u@cwoDv##^y~sxs3TZ9P{;%d
zV4{fxRJ6JmKGh2ygURWXjF~(9skC^I_ki6)F#9EEOd#ZJVmWw7$<^jN><83bny&>Y
zLev|G5KaS;mcdAD^#EG;S!iW2dlFE;4^Gs>Ag}%LHh~9<rUs`{k*H`89YP}tZwN9_
z5Nb4>{Qrg)EWdHM7sD`c1JExBvYFoV>hx-(khc<7V#FIC<h0_$S~x^Q-Xqi}81h0S
z`z(%QOf59lZteEL8@Cf<Egd#yUDjAzwgL0B?HFrwc{U|)Sf3nluR1}w+xceXKz4pV
zDF<3R#md&RV)B~jccRiE>scXhtpKePdPzHNO}c{S>_$Md+4Z2J`3~AJd3QY$$aFIX
z`~CFMe8)VB4>GIofqW${KcIdLn~0fokH)b<em8~*vP0#B*Wwcfs_7_=ve2~sD0Cwh
z4X~qPqW%M5l^nSL-&NiFUsQeeSbx>K{=2Hp>_(s@oc@#bn%UH3)&+`=hYRR5kn9dZ
z4t}=DW@k4MKznW507XWFA~^)<B}jO2XA!N;-9#m#*l;v`Co<_-f^MC^gCL=EAEC~D
z;8WB52Ias8vj}~36ULEv*{WTgK1{L~8r$6<UY<ovHi3v~o-iID>W8V7CdN|4i6qAM
z4ebxmQmUl=ftwL8iI;^*g+j63Erc38A%+wZ;C|f;g&~0xDhNPW0h~tJdNR=LCeA_F
z+`OLKFu)Did$N&(XP^abKo7X0_}Qc+i1%iQ04)<N6RtU%hyow&e})9WON1!ABurbj
zSe5(+yGE=FcDHWzM$lQ1Z?>CA%1Iyuqv1qukiSCW1Bc&-h@49tFbOAM`K$%MhYGq;
z(=Mdb8GBlv@Exc~)FVe+e8f?}(3glDZXwD$X&-}Zr%EHufLK``s0(E{f(m10Gpv~1
zip{cOe+QoUHphy6YQ=n3>^&=1YQ<i&V&ztBzZF|mOkGKpJVOZ}R|iHdYfRoAhPD`o
zCJfAjO>5Ar<~s<uzn7}5Uivr6h%|Jr#I~<T-l^66Eav$kuMl+A-Czo(;)D~h21A_*
zQ`$fw6Ok*(FQ;<(B5a<J1c>h2oIp|=g`GTNh0%lGX3!tM2{;A|w$fM&6xeLy#&FBW
zLg$8`qxT*s`p<kP{FI20Bq8#+h)~a(@94z@fxIM8dq{xP(RwifN@|u~OhA%2g_*aT
zWO5IE*-dg3Po<1&m-?_UCn%BE66HNfnNu2R6tx5x!vsx*e~$$I3b+71-N?j8VH#)w
z2u!(M#6@{R?1`9`T<@Vo{xRYha7AVO8L$Pq_Kxt1N(i1+U@-~+tM2Jnl;!>0eF79t
za`&uDxqFzE1tpCq?*5dbmvA>3m(ux<kWSVVOF6@ag?XYYR>Ap^S5b0}94oOE(<En$
z!u;GijRYIYiiCzU!>x6)Op5~OTCvw2;0wtUob>WYcvweLn*2RYH5c0bU(rF-f+I~e
zJ?;Jr(tMPJ0|^`4<^~5H^sJ2edjcqjt{$0)Qv~`U4^)Gz(0`5=KwY!|f-Tvtyx{Mh
z>UY-HodcW0prhZm;p_foQ6+hf2l<u`8iBB-=?pz}zcz*!!uA`N$aE~WIpFqu4VnV?
zo-95=e42t!iI1_GgLA`ZxTinmQW}4NG`2+6JNk^_*djq;ddC;~VR*GW0Rc<))4~;g
z2LDMLdW{_CRVQa6OiuGzWHovkZVzODhQ2)jTTloaCA8|ORvPQ6bQ~a?8!NZrbl8%d
z{GLVLi#U9?eL^*zV&kXaC_#%Te{Z5fKkPxRwAFGijIrd5F`k?;MzdBpU9)32kS*M<
zlV`D$N30zl6+ZY?Rh9fosNJat!B{j>Ohc{B6>^iD7!8eD4O5Y*?yiCAaCS<~NYV+e
zhRHr%y%HyDErVkvwwGnv>kvLO-rTR7pmo&@vJdL!n2n#~q3B!C%!r+T--lM~JvOCr
zmX&ZPC4eH3zMZf!;lp@*Xt+p=5T$WG!r={2V83@`)=~Ac2U1bZXBG-lfSt0eBkU(X
zBsp=58&D1u0S23U?Wx6=&4)aSdmK=~W#JVlCwwu5)X?WQ^p~LYyTw0bl>rj~{NsJV
zan9z#Apbr&%YW{*w@2(R&YC`73g3c4@(;rh-7PqhhQ|>F-4+^^RuM2Fc83FigO{62
zKsg6dy~={YUOskRc7jj<O28b9t{nuDlkIVNY*KhSN~-23iv>*Ly2!btcgsodhiaaF
z(Nrfzump#s%=((j!^xyq;0+K8nAcaC*^fYXVZw?9q@DMn+llsSHX>hA1Z0_%q`Njc
zOeE)5^kMVbq|hXU=vWCIk%UpXI(fk9RTw<1<4v^u?B%~hoHUL1ymCKHgxQDre~Ohj
z^d85?E!F&ORD%QiC617{XH)q;;lk9jDTT%DaafQPuv#zQ^bu7ATt>$hVvAy<Po&l)
zQ`Ku*FQ%YzkMOr)#t!YFqg%9OjU#5@jI<-jUlJea_!hV`L^fQ}WQ@nK%X)Ym(obiW
z9tIf5EK1lz(3lRSMsjd~A6sX1%pMaYPQ&yaAU|(83}~9OpspSw#gHj%|E5y|0NeO4
z0BMnlU|#@v$PWp-o#nJ_3GVAS=aUZ5qZ)f*?VA*a6EWiCUEJaA+xVr>vB7<upy=`6
zK~=->`GOD2F7$Fc8S&#d-jJr7(>HPy^SbCOY;q)zN!e7K+yM^r=h#~t3dIqrFK`n<
zCWLBTQF)H?&_Q-k_@P+0N#J~Z@;EFjpJP9)yfEKg6;xihC#~Q(ZYh#;qTQRvvpOgC
zSG^ZDX0R2q{XOr+jl&k`Ez`a4Y{Y_Htc?20qPHk7(ifJ`L-K^L%WiOp6rg*D1{_>^
z;NUXg%>qvs%rFQj3@McOm7u2O$gv!KdljX@JDk1*#1|Q)^fF&wE1z`!sNP{qPFaTf
z#0ZxdTwg#Zrfdbr#r}<G`Ve<5>=F&}qOo#d(l#A<^XgOJ1`lz$Z!2mWEtukH0>@N`
zI(+e;%#kF%0kCc1td+=iIaw0-kj`l9*ONiM1}sR^L(3Awf~$6`=uBEivRA8$iqzrk
z<aa-C>a9-u``*_!e*WDSr~RP!@FuyaNORz<w6!}i45Y_!lRPR*7HIuqs^%oOKH$_z
zb{PF46zPWuuqA7Z3T%rxjU{W~_pV=%l_;%~SymVo!+=B2WA+Q)ckA-Ld&J4MuhQ4z
z#0D!CpC{1g1@=DyA@7N8e`Ynk*a6$Vw)ltG`_eMvWot>`6Sc*=`r{20Us4QXqV>Iz
z;&Y3C+#iop{OaOZfBb%mPb_}0KmGv4hZp~d;^`>A8F6#-TI_P32pQYg!Yu)ftTa!+
z{uwgL)?fr&xw?NG0)Ol&1iAOjp@)wirFbMw2l&deh}glRfCFAZUw*gSY1d@E#p!L|
zcm_?kSID*A)=jDO8Fa2`GiOs7{QWP{k8Kf8xSW{bCfJvg{t72C>gg9VcPv)3Sz9C}
zl;5gO!Jmx3wfU`DDc=MRNFFc6>2FLjZiC<*AQX4gBeBNZvWlG$Ck^4`(=M~L#I3AN
z=ZZQ<=V@wwITqVLe6Qc^)IUzSk%F-<@xKocdb{b77=3`+yqg}0VF#$yyXleKx(x8q
zXoKPJ2;u&Px(;y0NszV3-=U>rAo$xWa9e^a16By_P?Ufn|H6y1It-12KgUIfHl8g7
z7yZFlxCZI4A1z&LR2+>jT)Pv+P|DR7H{moQ%MuKgP26LDwW#7$-B?y}iWsYUl~FnZ
z&Yh<cAMow45#X>w(w`zbS;{1H%i1b)c}FNQ7L>)=Sn}GzaaLSC^e5^9@$FK?um#wU
zRT`XTjfHCqTKF048dwrX9I+U57-WGxD=v+$5>fc}gsF4yLQYHNlmC*L{dfna`*0e$
zCb{(s5*8dO9s}l79%^N+q(2(!Iw+3C3*c!b_>FDg)t4Z%X0Ud1HbwY0vVlOWC{*E5
z3eo0n4Qw%kNHeLSP<Xjrsc&`JwLIo?7kg5FJXXyvo=mUd#Z%~&UM%^3YSU7AiI}?6
zy#nDMuEtV9?9IWr({HIv<>gpr!CpmYRxzSr7|bE|d>kDyr&zTu400V?93i@~t2qsu
zQlCW}3*oR2#)HpV$S9^0t62TLW|dHtSP<mPkb#{nsh?XMQm>8Js`xTM1D1xmCBdoy
z-*z>4Ma*#qW?WO=7MzSR%zl<E^DmkLBW{O`>C*@~NxvK`uO|k~sUb)^<dW*=e<V4W
zMnQ=t!l$iy3S0)N3R;3jI{O>8sN-Zl2B*tv1_`TQb{M0;-Su;)XfE7y<nR6M6x=jd
zMsw;pW;(nH<mR-d6gU$(n<pyIx4|ENB6*3R4WrC-ItvQxV1=_e&Gb8)Y-Okb)ir*A
z!=Si*L3_IXq6gP!UChvafs!2U3rulz7%fv8JAno+{_v=dIT>17S>o)H#K+<TSy|~|
zC=kT$JA|OiwBaas!I4Bt+5GystJDjG?Pb`c!&HqfdBA3-t-f#y#)GazRzV9~bNsz@
zU7o-9SSOq<M=lbTr>t6l1|8A9q_&_B)#U<587SO5CqrF``|^r$AT|Ktsl14$T4-ce
za~hgwHO|CRs=uX)EIv93VlOk(@oBlUtTTuK7}?X?QzW7oWpH&4M<QBMyAs9Ob&q7)
z`Y)q6<HT|*SY0%MtmEL)L$Cx`6ZS9!Az0NkVLiN7tm*o0I#+GXo{r9iX*eBigO7k6
zccrl9@X7B9R8__5&hcTGmC;7nA!jjaoww;G?C)bOv}pnBY5g=M=1|~Oe?83E?*ObT
z1b2ullG*Kj)j=xY2n;<|0p)w>%(WrTUt>*4ewWE9BqqPRHvlmm_(No#gNRobd_evZ
z+SM>R!?{Uy##0G`SS>NtvOMWMTeV@4lofmE1MY<qC1BMPZ2%DYLs?nHT^Fw+iN)6y
zO;U&ZeCuExzhJ%o#%4c@+TgX3AFn#r;|o;d9u@yN^BwqvfGXDn_|p&|OiOzan_PwU
zc@HMe=Kw{<2Xeve<@?Zfa<an64KvR(D2}xyR>AjOh0R^N-^_lBlDfQSmBx*rAug;L
zM(!9F>Cv6v?hBwUz5vxg@PW1yw$>+*LwF9MzF;+fI$y|j@&kEp_OHE3z@WXsn_)V-
z1cT&0WZgr4WI!*4bewMw`Ew>U9kx%!7N&kjj}V-y>X(;%;`=>pC^)<uSF@sRYR37a
zd&m<Zu?9Cmp|#ns6Z%?jf!1SYA4a&K%d*qa`;drZW(l|!g7cp%@OKq-!8t4az*3Z)
z$c&!VaOoFramws6glqKqcZ}IoLG9}PR*+c2QCZ;*Se7lD0qJJp&c6*VTy#icV=n&$
z)>E+vv_SaXhzrNC#5mlI)<GwsnRPM)D|6*Qsm-Bx_+W^(T71}sD+*G#f-=^?(m#i$
zyQ<E&V&w}T>1LbWO8cBktOV@~+J%;q{#VHtvxzI4k{34Nq7>`8CeG&fBIk9Dr`5ct
zK~6Zm<0YADO5%;!e7Ysik>A=Do8LDO`g$PLn+yr{iY|f>Xin^6u{xLctmgJ!-0T90
zz=0_S+?+ba3Q)xDIRDZBo-%iA9?#>jfepC}D1a!agS&um`A-gQm~YxgqS#fm!mUIf
z1#Y-|$o(QML)T$<^?Jyzf|@d`tAf1nIm+wgD$0mUuu@=y0YN4<)%$P25nPB|*Lg2)
znZXxP?NbJBB0Bz-s2v;WIG+mylbh+CcOl$_c?7iv?r$W|0%qC}n6U`QDx8&7)xn4@
zR^hI!GHRT#SDD!)tH|hv%aszXr7RUPT&DILw#1A5O5yuTlnxY-xX}?3??vT-)p%30
zZu_lhR_9X0t!2}tu0z|P>_D<XS%FQ62zMjaoA7NS7q>xArfE_=?XQ3PN+99B#9u@m
zbhF0mK^!`8XSQh5(aA1^o#gDuP9h}Z-No9@uSNP{)=qExvBW}zS0RP2Q3K4e&SM`O
z`|Q}s%p=;l^JiHXpm4_@zPQeRVn4QVxEF9+<c*3Ku$wcM<m1D5T%K9*0YWlD&hzi%
zAmaNHdzGEQU1+GM_Ml7Br`1EI#4WX0B%&_D%nb~4mM;rbR)#%y4xE{=TpkYLN=SLF
zF%A7irzmD(c?9Sg1!LI;C)_WvKD;Gwmi|>Abl%@KUmcsZIkxJzE|v)=fBimO-}<`n
zGQh?(Pr)ID7pdDR;zlI#?Aix~nBnFzuv8n#!uk0Q+SJ@faB2bS!%b0g!D0T(y(U)A
z;T&@V_`wA$CZ7v3gHvk+44Pr2>?2Wz(<5%fWLKE?<eK;7nD<QQ*-1dm*l-(f75j{a
z^@8JMP&1EV%7ae-jD5*kv1_q<Cial&>k)i6%}+2qfk<?{OE?a?RPvux;>KUvFkOzj
zd*x-7CT^JH&k5#n)*O_v+Y)Y~xo*Q7K<<vy(4Mk)w(vup0x!@*e*kCD6c`Mdi7DVe
zuzAFgu??Uvp8%*e&nACxxVb7n*p22@RkPx?kOjS%G(EWtH(*-^F2iqO(rH<iD!{X$
z&~DQGFh^;_u?2&huoC2T7r=Q!9LK^=UKKGZ8HF%CwUt?Zvx7eS?~*@*c6G#ATa+ri
zU9-vd@=J0zz|2DdLY?=a0KVjPEH!5Gh2pguF6;^Tq~AwiyZ~vIldHIH1dD*Dh%jL!
zW3q_Shm+ZLJfYF~I(i#=52(P+>UQXlQ0EIsO1kwbQM&F^EDHr0nh^tqwh)D2B7?_n
zilAi&`QQE=G)hu@5lxJ9;K%_k0oJMH<2)NCd6<`o@)-0kXC=MmSfHk`cDiQkG`}$q
z6y~3x0xU+5+li9FoOHubIR>^gcpbyJc)-h;taj85W;S(+Ri@{gWqvXhWtv(Cf0>$e
z$lbp%!;Bqs(+)|yc1RbX^k5a#NV3>Jpjg%eryF=Q*T`t}QyBQb7ImkwPZNC^B_zF(
zX9T(9EIyHg$#JkFe-8TyIOC_SA3Sie8c8r`C00{j8cFzr7LXdYIx2CGz~tKqz*{(&
zWQ18k{xfpq06{0AH#WZ!<c#9H1ZDO2H;*II#%JQ$xeYyx{G<64#0HT$euNgO*ceY7
z7y1~}VN77XuWg<l=_ok9f}Fx#n{xSI0VW)4t)jVxIB1AT<b1e;yP&|nq$>(Di9HWr
zfsSP->B2i6qq!$mQ&>m2y&rCJ<(~y}+y7L>SNvLN4Kb7IUjt@^Au7Aq<MG`iZu{ZH
z2pnq44>)mgC1zF|GxQc*KD;q8ux7+CO`gv4T{Ko#v%dU$!4bW!U*Im9JC8WPF|nPt
zQeq*D8N(MD6*w)9sp$!PsEXxY%SOT9ngx4}<vnn*#_-mC(59)aUpa2lznZt%9+`J5
zyV>ErS=JWN_Ex?Am1omf_Ueg5Y;lU?{E5k{_LcT!Xj6f}<gtm|*i9V+Umo2@ekb^d
zRfaq{<banNtCHDD2Yj9E73Yjw9kimtbD0cBDWF9=8AEEV>Cr#788zpWDC|YJ$FPUh
z^t4`dMCO4fZ?5%zxH*M=Xos;&<U)4uJ4kuQ`#w&Lz%TzEhxZ;?^Bxd5U-WDm!(Kb_
z`T2JytH5`$-Jwk;q^?bji{0EI(x0=irB4Fidw?cNk=Y^#T?r^kWQ$~Di3}pcCmQQZ
z>_9=AzOOXaqY@0rG3PNB0<=u~L&(1bPZ>||5?Nc*401J9D1EI>2oMpc)z>K!eDq!w
zWId4pJ{e<0SWvfgUui~8;tB!e0$GPZg&c_gjv992vsk0RI|H+_UL(yYoe9_aE)!P2
zv-rMyo0xoC1|XKT4GhI*zXTBuOFl_z{YbHwJAY4ehpI{}P{enUC0TYxKo(J)Q?)+o
zPc%`NTIC|Oue`(pD0kK0TOw&0`Wi={NYS^#1LF=-92g$o5lI*&2ldDrAOR~9u{q%g
zHfPzy@A-#gi$|QPjFr2w<?`2jkQMWBoRAlw-c*9!?9lI$-9kF{sMI1@eJI^1ruGT@
z;O?ymVf9Ak!{CA4xLLTH_PZ@^cu`O-16q>Q84g3yg;!hkRLbSDa_teq*X_0o`0%0m
z(D0WWy)eqKb)m*1j<Dnr#%mW{2Y3?YVW$p7jx;yB2CAXfCVr+bkxkrxwcTN+5@M{(
zg()+`mF4~RVsHSP4@)__$AvX#!ftOV!DV6>SlgW~LW&z_k`#mg{XMrDKH2a&a2oX{
z?OepcE{Zi*>!*tSUT2tkG>HrbRGDl&kD=FMKan;-2`q;f|CSQ=YW`cTolfk)%-73%
zOugw0wkplou3o$h7v3;b#eKb96b(4y^&A0;q|(}Mk@gyv)|f}9l4nS4sS|gb8}sGZ
zO$f-we22dF=cU4(<fWezzciPXG#~D3ZEQhTH7zN@@vE&4!D0}}&(0s89FQ3<+wWh2
zVdX6dA(kF4EIgd--TX>uv@xxpDeTp6XtZ-|X)jLLEb@LC+g8-eCK(kjtbdgsE(c=x
zl>sG62d=SkaaMWIix5;#>jejNV2^%b-sZH(ybzhoS3A6`Wv#^0Zx=k9#*sAk#1`9x
zg4;z3?lMvrV-u6~Rw%f^kB{!61`g42OJ$U1K-n#IupP2-FDB}){5NeCy=0G3e)uGy
z={N<B)R>N?vBlS7%Ty@Y)vV@REcc>O<AQ>u{538kBpWw7NTb{=<LM2_T6Oc{bZC)L
zq(#yly6M@JTVFSdw8&dS^uyR#>8?`tR>C8`xnfJdp*$J|(n#)?bC)n}^~OrC!yU@T
zVjJ$LMG6d0#)4j>^tztTIUpTYdxdx@G1@zaF24f)0ZVMg&AqWz1-(pjwe~rdVDvzO
z-Y1$=+YR3lC0b8S)_Uo4{|6AqyL4bc>7xPVO$-}qT0gyq4-P0x#DF5ce2dr^P(bf3
zLfLMSQ7Y+M4K~wW!@_5v!isY-=a=kWA|<&cgT6Q8DJMrZkTtDeIj1>vAOx}s<@_d1
zY3fgWLCU#Eko8R>E54!e9Ya3e>xd=Ex?~7h{Vv09l;-qeraP3u-MfVXsF0zO?5U(`
z^wu%@M_m}8!JSo$^b4L~bzP?Zrg`FXy`slVWP$DUSIvU%6Q9vAoh9_%dzcqgIhc3q
z@}8-EneS@D^fouVF}x=?a_>oP2b(|z{}(Xt0p>kzWdchg+-o<OvkN(|P3FwF<lB22
zyO1NBKMo%ib`td@_oFgWXoh+tY|tTgv&*ot5|>_Rs(&#i2qa5f%mtOBe}#Du+bI~2
zZQE5kwSsVd3kSKe_+S=4mY1@k{<aLq^{eck8$o<nH4>kaw)wW?FWyyJU`~A#Uh`JL
zC^X_(4ZV3}Ve|;}X2m&n%LNA;mXCSQmr4GExNpatrWV`RjbtrmH#xjF$=WK&l8~Uf
z%h+2a;JvYJh2Tb`=FHSpO{E6@`V_5zRh+@VKRGio1JYxG?G!_z1wDCepMo4(CV&7s
z`DRCQqR@kSWcGcBajydvvhR~(P#Uo<28GnmnK#J>04fQ<sFag<)mogH+1CoLYyy|o
zO|7rXl(bC2dXSngGQ4b%NqaN4HI>q&0U%j}44QEt&ADPPS*R}Q5R;-4pJ&_vMFtyk
zrZLP|Jc5KCx=`z~A0xR&(sdB)b8L9*UYju&w&ii&2{g`v+?Z>L$%2-yPopGKtA-p~
z;230bvKz@5dvT^1>y%u+_W<l3^e=f2Mls@;H)pmb7U23pUA+On5dz<tAUnwqO(&O)
z-@Zf#i4(X+NvB)D>QYe>n7J$$!|t#Ef3ua=4%>5a07wiT;uz~;TG0K3O2$tJV2_vX
z<wi&2hY;episL$buxb~G@ZaqhD9~<#ldeEiom3dk^8G6S+k*UG9;YhmdV^wDdg$7i
zYy^q7QGAe}CLn77-*<W(mN11dQ4Jo=z_kM~9U9SD@Xs>#7K-OgJc~4!Fa~$Rwt#y=
zF6U1H87y3Xh*#3CI2x7k(E~Vk9snp7+t@me<EoX|EbEe$H0wtN?D6Imc_|+py=d&6
zj^djhyByE@i@0gE{-RBri9zW6G1^nOjL$=fz-T6)`i-i71%jhTI!jOwE`RW-Bj^%d
z%Yt+}P64AEXd&~?XJ{}vyFCWMXKCG~>5h7(aTg*yL6&#lde}D0-LYscFo1b8z|zcF
z=|;?hsF~e?nGj`O19-rRR8?-oQH20f%<NP6&K?ug5(Qv)GCBu2ah-tjzyi?Sh?XMS
z9HsW*V!r5iAj8d>OtiY71;1!Qdm~Y*3>VqQ^{u$;DZ4o^t7-YUri#DQ%{Ta|6WoB5
zxLG;S8sP7q5sguAWHG8U|22CBHi~@S!^#6sqF}&AeMrZ`dk&Zq6H$0jS-0Vpm;#Z+
zcx--IKv>!jfr&Y2#0&%?sklR_61Kw_6;z39&4@0^+?Ey5au8UB3~=lbtqs83eJ;SF
z)RjyE`7FmCBHR@KW1?ynBSx~f7VRYh8Bt;`WoI_N>-(ww67EL?3k{SB9EKFy?mw4x
zNx?^9tJ3#VQ8s1gTZouZD&G|43Onx{_?OH{(IzV|6cij;r}u%>ttBP8Kqkf5OYO6|
zISIJT6lr|gG%SPHc?BhvXqf5|g{CC&RIk7#ECEA&=RJ8tfxQ9`YMF%%j;<Do`jq=G
ze2umI<@nBqH;=NgY`R66#fBTDN@3@4d?+|VEC5ypf4&UvVwMz&jsV9+X(J}dT@~Oi
z53=C$Bf&{5MugCxBwmy91#iTn<%oDIT$_s6!}Qe@UDZ5te*IU&@WTayTJ2Jn&teRm
zFth><`>7BU4v{$McG4;(AIJV;(HTe&fO)7~OG*a2d4a%}AZ&tG-Zo|DjUtVz&KE6#
zK|;BIG0N`r;EN>~5P2nf3=J!yCRHGPut|i6{v_r9R+Gxu!{V#em&ywx=g(iKqgkVM
z(X5n6*2;B8j?bryHm4+C>kOCA*C2SNkJ`8Qf8M@-qM=t%V6c6+iZsGwNc-kd`+WE!
z8nlf-V&7^A$!Ylo)2yZLnPasDjj-({Nc)?jDY)r}+F)<D33;)eXo0=mYQa-bdmCRa
z=ne+M%d@bkiFLt#Ss9B_x%sW)p2z@e4Ftn<G%hK)C-EygjXy~WndnZ|mfs$THO{8Y
z|44vUr+qI0dOzIpTEc1V6Ih&&lvS2sTdlVQTJ-TS&>%4nEEA)w^m7O1UQ$=)%zlP}
zONt<-{v=5uc!5Ob((?8FlqPBG_5A`yy(*GgTO=eDzcw)%Cfejy)<gu2nTdHx>77Ex
z+r+g=xe)r^2ZO8N!1}^*V(pyA-+7+$=YkacLj-k?*razdfk?h!qSY%gODK4wmWO{X
zPPn<koQ7)-a9ZSJ(``KerInZeKokeNC>0|XuNcVV1N(22`Mm(ZQJ2*NaMqCiDU9+M
z!*Ep){R&PjSKN&TXB%-Z8Ou}-EWXyEe`Hf%4)7vUG#K5Py}NWKF4h=LWVJ4`xw?l+
zf$Qz*#Ax1&B9oMHh)QX0(Qh&(3~9y?#uxFkLpqg8m&eFGXqyws$+nH+za1!u+Vt<p
z3G-sxK%2(#9}NHq10x@oY|K%sF>@|$jDp4t7maBT@by!vG1&J_?=DS4W3Hu<x?>6w
zu^D>0gT`DfGs$gel^vGnqMFm{Sbi<)U=^ovM}T{v_J7pCAK<HK;4i5rYraFfgY*j$
zGNyO$V3#gw78UcBTEs20XoQTC*g71?|MMF#H(D_Gc^3R00hwTMkv3e;yLj+XLh4+s
z%q$AYYHm69mA4F2o_BSZ4x8Y>-2wQGBXnZ^mrGc?bvo8MSvz1spgD`Uk!U$&1RXiB
ziRLDk1WeoL$6{zZ(?vgjfdRksQ|J|JABy`ECh`m*He~nmN52(q!R-kxq=%5#(KIn}
zL~My()Fw7f<R<|!B!jiL=kA;iaIxQchU-5gPQZSrtYPQET@3_-e9tiO_aRp&{Z^HZ
zJHTlb-mWRlN|Wqch>H;>;rMA{+(1;m2|oZ);nqGU6zokoKJN)7dKi3EIEij9ciXht
zv8{BCA-qf{#{6gCkKc>mtqAa$FGGaMK#t4K@nbN(oBm8cIMe$S7UyjwVs!oZt(d7|
zb7u36v2AI6Mx7gFOt#8!i!#n&PTXIHyGV1R3^>@om0y9&buceznv`%ftx7WsYkJ68
z{~S5%M*=IvZ_I!|FZ|~vJF-4R!5u?^u^+US9nODKzmT%6BDOV&Lb4ea3U_`R1vJAA
zm;KzPN&FU+$qq-ZTw&O#+%e=Ff|CJ>;X`W~@D#>A8Uzz08Hu~S8w&sUN9<g|BW^3$
zeDDWS+=KJ@svzxwe_1r4kyb#3RaN9WA71+znNrbv@VxF4Ql`pAF@Yqq`}ct17!psV
zq!f@EJ-2-d-LBzxEh@}WWgmXVs9Qe*)^O*ymV5o~I-Ae%yLS^jyf&1^XHYoC{>CSW
zMaZFqcBaJ7AbD{0QyR{S8-5R)eFl}o|Dq<3+(O(~@Q@@qUI8rpFf@<leWElzh=lDW
z)_%r$l)v$YSm`{uSi+of%P9Ush&DTfJ?-4M^g7PABt~Gr2|w`?LQ+OtA{xQo2$vMn
zALoi-m~Whm0>R7YtXnVW*CkLFO;bNc&1^Q&q^imS5H5D_u)|n@dtbATexLU{scQ8K
z{0foM_$;z`D{_?w{|y0C%Z20&&Dpt&zQ4BJpWKci^kI?7NTNTQzcmF_o`V!e;%S6F
zJS-FAa39pi-)sRKso=2>!1=<ZMWAmv04DozN>vs8dX%H8Dv@R(LV%#G#~Sxxe+^nk
zsF9cd2PUF0g@!sqqHC~&(nUH^^o|=R5a~Cl2D*y$vd2Tp+J6RX39$y8jC@|dM``>3
zErhERybREN)Ngz)K(XBinxhZ?z-DtnP*59RErJ3Uc=n_hba%dh+}n%wo{lYr=q9UE
zNAnjagDSo7TKZ!=T~H-1s4|QE+%D-??CRk+dI9(x8jC{;Ek6>v6A|<R6a@NsXpOjc
zKQRr&fnN?f3iknkINBK=n}q6c-%%H^KL6qP?y1PmW4)*>F|MDKC@eYBn%UGK26~-S
zGl-TwzX2rlBrtR0_pr!G^)Di+J$6S2j0<80!7u-pfeRop27#nBXiP?;sZB=^zi}n7
zAr7(_6R7j)KmsR<{*jkNW#yot?{0$VS<-$1guRjcj<CrZ6tWJlryd|on$(z0fQeZ{
z#GL%UL}IEaM9A-3=oFIQINm~jIRZj{bHEhoLVj}w<<~><>k{(o9F*Uje);_sb@7}A
zvkP7}TkuPvgR*;^=>84a4Ul{9rG1P|boI`dV;+7?wu*naOZ0FxRS61_^r9v-4);#E
zY5N&2uGCzxSQS4)W<PLwLM!Md;Sk7!y>sa|*9KaGF6Q$mfW3*gX-Hq_MK4Yyrgnj;
zodHzA?*st-l3xx)@D%p)2KtC<gxqJJBc|xVR~(!A<Ufcb;;}o<40QkWhyFqLPeCF&
zUUWY=@zTB@-A65jP50X#GBh0^|NI6BAud|sn^B*+S>|_(x0A0EZx^o>Z#NH$cMe}d
z@9X(O5%utS;+@BD5bx>y8u6aNFBk8be3E$2;$y@+mn-63$kWAp4mbZdVdyhA`}jEo
z&CR9!jChyx)8f6DpAzo?|ATnn!e1Bf75tERui`I>_Zt43c(3Kph<BJjA>QlxqvE}R
zKP28N-znZ(d82r5<J<5i6rQgKm+`wP_4!5$-Y$Yo6kH*K<Oj|xM39s+Um$`HQSb&4
ze1w8CM39`j_+$}$oPwi8@CgcLir`Zeln~Sp%^0}xQgn(so27YE#mx!O1AoLmInKr6
z*Vh))T?$BfO{8pwKTANQ1o?}U@{K~a<KP~y*G%U5iB*cro4O*I617s?-qcmelucGj
zjyH8pGUYZaCD)s}Hkq>2O7VD8!^xClk+M0@JA1uI3G#eO>Bk1M4dD+9c}&Na7W~x4
z^W9I2X`?aIn(tqUC}u^N3E@Iznw~oF3u^DPqlM#C$AYCAxt@OBJiKYxf-=kv?Mt<@
z@X&POMyy+@81d_RUncfmaw-S2oM7@C!T;0Vxd290UW<AsGbBR@%pgI-dk|0*#3&CF
z0ydEZf)W@AB&3QG$zT#g5|h1oSON(XY?3jR+SaPa(~79Ix3<SVL~XStKodZUAXZU1
z6_itV&TupyBg7h+`>lV^B$Ei%bK85*z2}~RmA&`>e*f!VYyE3s2}W2t*mRDL+r|C9
z-BHe;*vF%45dPr)Anr&THpVEgmMG^A`}nF4xLvr{9lmX$=(*rPy-;UNcrz=pvd2^n
zSL)zXy(+bgPpeXY3}em*(8-p1R3Xtv6xu5|ZyY%94b*Ei^$HB@{&Xygz<DtdNR|Bx
zU*#HVe2GU;&gE_E8LA+eOC;w|J8TKbaD*ED<(~3Q?p?lTe-tiXQn=BF(db8%VEA10
zqjfj*F!LkAhBIjH)zBdUP6W@y^tR*dZX2T-g?7<1ql_su>SZ$vqKpY~r}R<HrfX(;
zv@s0F!7~eNh70}%wqxT?8Hk-Aw7+e{t|KRWyQ21--OY-m>4}Ze^cBgxPX`g{_}Sgj
z;{Nz*KOU0)AzWJ|{oj-ROTOmlKz&%Al>X0?;}_&#p&K`I^QR^C95bfVxkWI_+D`>}
zt>jK%J**<`M(5?Cj?edJXX?3IZ!;XX-nOD`GBoXw3DKcgA;t75cZw>n{P>CB`0p+K
zcAB=$-}-B*tgp>p$pu-PZ65}AingU;cc-aP{CS#uZd=cv$ANvoIBDKk^!U`zi)x%3
zO}h2-qJ1qkU#m*}V0Y?_%kHo$RFtnJ+SeK_Wq7hX)HW*&_EV*V7;VM3zT1~HZlWN`
zKoT$!a07{e3vdAbjBlN4$hhwmPm`y~^EA)XJllD;^X%Z+!LyTRCr|jI_jNVdg@vQp
z+HIYo=I{rl(xt$9;9f}^>G<1FMlUsve79;Ja*=r%*&;MYIBb)C4ZNt7u23h8@9Bhr
zpMU&B7x}i|PcFf;Z_?6_@=99aKKaz@lS$Gi9h8L-5_p@PKNA5D&^XsN?nwPSo9_eF
zdLOFR`$a_3QnpZ-p1%4Z+V`RAh5Cq)+akhI18NxRvkz>(52a_FTXLDI5iv;namw&C
z@GIa&U@veGcnx?Tpsh#J)+2c)@=WBJz%zlTizmXO--_pnfa<p#Jh7_%Ejv$?=tuUA
z)kfNP=x-nqm<)v5m~zts5q+V)scl3*SYa%;UVRsyY&^f(dg~9Wg%*hhYoYxJLPx|(
zyLhoMjaZk#yErH2VR^I5Oc=}*dj)i^)fj9R?+BBm{H^{s0yly{HDz~!Ux|pkc2Z$%
z1RP@FrXY0vJ?72C$q&4u)bxi8Qd?B9Ca7OE?$5#PV6w{Px{`#Vi9)<uL<~64Vi^(j
z{uYI9q^XIkTQmRVvF<Xo_+M{3%rxjjqI;bXkmz3Q4rr0+GWcdg2<-cE5*?hX?^y|a
zqfY`hD*@Qy{@sC_J!XYVj#E8^JW#)$6NdR?h5ES~Q24v-L}0jiRd;IUbd|m@`?%7u
z6(;G$QxmlO`j?$B?<asFdi_+gu!vrk9Xus%V-9;<P?BsUUWAe`&^JHc(VCtp0y2TY
zeAt`P6Y#=GR%|4Dd<7_0j*6g0ai8LLgtLVQ?wh@h^8|OQoLjkV2~~lc!NH-AC`?#X
zU|h*U9a4eO@iBK&tYdZpu4wu|m>#>Dr^J1SBolnyV}9RqJggkQ8*<!YIsQsHJ{WRb
zgJb@VNBN=_2}O@s$$QLY%KZ`Cx62<emqjU~B$z(WWBwA);B@&y$NiHMQgn5k(I+F|
zI8mJ<hBak(E-pc6{WR<^Pw)*Ak2!-5dZT}BHcjN#0x8?2T%?<Xk}*kwAQMDuPZuvE
zw@dl(9O5zOhCDeQbSZ!Ie&K0O3AuB8krRwMKM+9f&4QPNZX(e^a(m;@#?jE0HlaPi
zW+ZISaC3N@s2&Xi)yD|)B3QYRyw`_+s75N(T97zMx>+(SQV0ZRd4+J6-wAV;j}bDG
zv%Io9W*{f53OE^I*<~OQmV|J^>++U~gs?uqU)AONpuecLv!SalJPu)+X(BJ{f_@Sb
zzO^&8k<xE5KP7$i;fRz0N(t@exF<=CJE`V<4f3LJpW4$C*_V3`wrBcn122ur<%VUP
zIaNq$X58;#VsVx&x!8>7HQx#X)yd+Fi7lCizq9=a15F?HhL8a-u~!iV24Y#T^QU!{
zzy%a@KNyVRv@S+2W^M_82|+%>&P54kmL$+nE{9_yh&RjZ#d!=%aOw5)#$eD|pOKzl
zro`tR4>7@@#^heAX)EMxiF)EM$opT5EPsMOt83~$^A}r{yuZuunYhI78Nb9#po4sS
z9bXXlmrD%Xd|2k;BD{-CLiQf4p4jVY!aTfX$$?N4<?e#qS_tYheH+J5#sp=mK7R7r
ztGKn`kN;%@_T%N+!p2{6Z{ZT_-a^JN9p-#lPvqq`UINcau?sDe5S*&13s<cQ{V=h>
z@HW_`44C#^9PeKepR(9t^ix+E_T()7&373PfdQcx5<zy$(J;r}aA*9o#h&H)EAnsV
zhC=XgnA)F!bh*%4PMgox2{FJ0W+`hvSAozyW=uAZJkndnBcE@U`kLxa(bQrQg(0>d
zW6?^fPSE2)<fAw4=kNH<ShYBv(>R)C9OLM|7oMi*QJXFi0yOtBOB^24%Q{IIMghjK
zzr7ECJkUUM1NN;M!~Gh^%nP*Ee0G%)<I7Hr4j}e0$*|!FWfgkly*H7k&|m6qP%q=1
z_oeUxSLDi?&yt{SW+p(3hn&+GJ8M1G+LtRQhd7PJkL8Ms*1k@cF@)g8AQj3!Yq?>c
zCt3Vlio;UG%JAx0$gewJc0L!s@JzE^cQ}9hvac;EFoH{5<fmWL_;O8KLCvSba9?Nh
zwYh!G`%|+Ms)kW$2NydlFE{L|2iA_|)2@vFqJ=tf5!QCxN`EmbmE&cz2;9sCKj%NK
zNU*&L(?_cAXF>-zKgHecr=pD6z7x@U|5~UW$gZvHPc0`w^<R6LnFJT&OlD$KtHz+$
zU>an11p`i85cF8iVrFY$?WJRB(CCI_ao25US9JC2K$r@F#Bi9TUS4RZ?!KMRv9o(o
zPU$Cx$&J{e^&=Q?X!rREbDV+EOBaQpQGbW?%0`C$h0ZJXAAtLYapTDIO5#5%+&Dq}
z!I2;2bK6AzECtpB-Di+5JFiIU;IrLf&wpM~Ww_vZC6vZz<Y@vYfMdX6U>~pxcpd=9
z{X3jjBr|_dDm@aI2+R_f|Ly0MM}H{!s`HA6*9)9i9;YmFq9Me#U-5nn(D(?SG0uBl
zk<ef5yrR+#r`3(sf7y8@l=f1xxCJN#N&y|%2-E@J2k4u>!+AwA^9P^d@AJSu;JCPi
z`{r*suPE$5&KG&P=1Z_&gjTD2wu{9r-#M_eGc`i>i!uiI&P5v|&!lC*8wa(xpP(gC
zDA#L{I2=Uuk-28IymRPqfSIt&#91c}i<OXTz6k>I#RErv3nvcIClH@!{vM)zJ_weD
zu_-L8NU*G<xQC7$Bg`f~d>lC{d0L!!VW10^+~>qmNB~Y8H+F}!P8_d(PpvjzMJQmr
z)F<LB!IdzF`7%cck^aLb_J<@DD#CfB0B$E^bzV@-Vr`q!&`=<s^68_Wa_GZ_v^?aY
zU=VZGXAzm5x{LcyVkUd8JxnNsqtS!3fw-nje@5tui@0AmI$b-*P5O7)s<z9AVj!{a
zusK!aLirXkGmKBs9|=}}+<^)RB1ao<^{^>kX;2B~<|3JfJeWv@IXo~nTtp$}Gjie>
zs8UDG*kid(%i5QCBp~MA;#I186PI-nZ&k7!k8BiLJSuR>h7ArSYHD~<iO|JiNP|OD
zR=9Lm@@Ua+Eq87EAwAZBPGrH*)zP)xEF>B0I<PUu3WRluor4HwG59U@*GT3C4#)*>
z=T6L{zqglekt0JjG5z&|GWb4?+B5+{p^fgTufl_KesA{@I&g7rNq==^SGc5GcM%$N
zDBG2)qExz*Z;jGN_-iD-y8i2BCq)p}2lKcspLg>w-;qwg(()HXrZa3jd!}spuwBVX
zwmX!iwU<Qo&ds@10tJ4pnneT?LI)M|HS1v7YY$x9Bv-SsJ$Cl+xPAV;6Eqk-srxG9
z{LT5_#k!V#{GO}ibh%Xvw5jxHs@yzGY~@?`(yJD$GqsX;X$pypI5DT^o5eVu9#Z@z
zw!tumU}_j8#vZXTB&Vb!;K(WYBw))aIfHo=I@urFFfxYS9PyXWVFQN5U;5Dw%tIz$
zw`nTQR_c;mZr;Y5QwPf3_^KR#GvcZKkFXD~jQGWdi~_bGh!>?#7uoQnunw|OlU~+c
z^L5Ak3zWhaA4B^FhMMboO0k*O2GL)lD9_<$5b>czbCvKcSt+u*gA*=%dH>Q-Bc11h
zzO7jbXN)&5mBf=w2anK6P$YcJZQoWa2#E!v{hFKxxm7Fc)Fc9iC35{|Lp7bIDjrhC
zgMiGf4r2yquH{U7WdMio;XS4Y%Ry{q7#kv#gZ07i`7eo#MMh_o68E*Fd_#nrri^4b
zX+slbsv>+8pmck%oLDU<yTk`c&RTk8mVQAOK~qMQ#2raos*zaqlvJZo>L()8NRJ#Z
z8DReF_eq2zsjEXGs)yS{k}ykS1B!ZrY0f6O65^lslJv3g&wfpDg-&EwF8wrc=hSwm
zPlV&n%%yE_@onOwK?)`GNJ6MQ0drMuBYWCH5dkD)uErh@*k}#GcFl<-;;TN+5vb|b
zctkCv;*zL7f)A;QuO%(81r0)&aUz4EQu;kA!k@7i8RZ)koMaWW`5cC6n@{w!!J$5d
zx}l)4VP4xL=BKi&c^{n_Qi`q@G{vimblcVR53b#<Dz&@nl0LRIeY=p^I1%{g=J)$y
zJ4tny{}tcKG0i7qLLJtU;jl;LnJu8bQak(kB&;UDjom{#=dp=&3s}YXYz3C()*?Ie
zpOr>*X$FUOQFm!A8JKahNSiBdY+x3bJZfD8n{--FLUM4+Mx@{vM<W!B9QJEa7>_ep
zkk)U=K8R(rhU(X_faI*ZO}cn`5t*O}lx^j8|0rt-)o=Axn^DGcQTi!#7hxLTq?|HQ
zB;T6(nrsCeYK0_o%)IO+CP{n#+|;w1ZmvD2c-J{i88bp63RjyKOE!B!D3U{RCs*Zh
z&^%65VM(J34230U4bHS}M@SYS9TEK}c%)2<$h1|T;##zRtjRt@#1T%J=kAhOiw+Z%
z7DpyWVK@6%9K^uVD9LDKj)dR^aZK6$@Lt)l;sj@`QSzBm{TlLG{JKM_^60Zr2w~nr
zr>P-BaV8OjjWm?hQ3$ZCx+lyD%q`~4iNF9xWKi$t&pzBhwN9Dq-o^v9@=abLR#|<P
zZAhQVQAqt{KX8b!o72`jV*h~V{I<6~6`|CSYi!tcFRq-OP_ri!l#8;keBk$FyRh37
zh-vx<nho1V<uSlQEH;(ry7_afSZop_PK$8boQKoq+i)shoyMOs4}aFK<j<xGJnq14
zb2)CC*WtE#b4An68qy4#ciQ16Pbjcq3r`~(syir#2qbbvYtKWddcXwdfk_9bi9C9n
ze)1pT^3siP-~5MsCpR}_o2eh^LneJBm*p>KZqkLal4YCRR9VNhIM|rBqmzzcImvcx
z66fD`zj4}M-A;gyA17cSC-oI$`q?*q&8~)Qv|C#(aSFd|hYbf}FFVB?n3Q?Svt+Td
z#AW4x=9X}?aizE|`r{}3l-H&b6-{_j#STR!lD001vu;K>KT;*^ChCevBwCMFpg{JI
zv``4YsjK1&142Pl%%A#u3rbGso1<_fngd1`+}!pMu@z5Me_5UFxiPYKqFL4_`WXmY
zeWJrZUKzrrMuBcHupOq4Wr12sE*T-*CXh;FA=)Q+BMN(?DJ!kq?%Ww`xlG3e;lz2t
zY?tl;i?gHO_79VwJ_cThq^>FqRUPlqS?IuI+CfSbNkv_1l~7eGaCwRmuOF|ic1ac2
z9ldo$TN~LhX~J01P75nyi&d8=Y@QNZ5e<=6v_R3rM}nN}5ae`^LV&sAD<=;*z=!~`
zvJ0@i!orMuT*5kyXNzJnxfU!+#FTW(syy@yj7XX8#zD_9TWBSg(;KZ25VO;is;-&R
zf(29n3U}agkC`j4sjX{=`D1EkCC@enOA~v{GOLYQKAdPN6+?W+QE4fLMhrW4RG<SI
z@?qI-KY>bH5^K(rm4T}`=ra<6GP2}cRBE9K8^r(O+ZvKpJDL~qNguPmwQZp-8m7V@
zN^KFU8@Q*E7UJswZD=OYtct4KqA&NDKSOfc-#M>@o#)4;YLqtENdFS^3K9&dFBr|M
z*loqE3X2sMmi8hv#7H5<kgna*Z>rqGc_y=ShEbHT^m7S`?4d%B+(-6dYGI-*t5E+<
z^P3gqvBIHjFQNKiDKj-p;Y*MmMAXOK^8{gVhrBn?Un}%9(JqaGPiann?Ll$aX-{n1
z!AnT<v!xN*zo+dH+)yR$d)}fNUUOcJ)Xz$%vH5mur0%L;@p((;IW$raH52Q@7``Z{
z?rO>WyjwZ7y=hrziEYVZVX)-}D^!8a+Bc<5#*3h1xvWqS7I$WL>iwNNvp;P<;TX`|
zOF6ZibFB4T(YJC~mj~?Ev*ln|9sgYVFTcLiEi{YE;!ZWj>X*aK9|va;HulW-D`RH9
zw=O#R&of(j+rwMS%oCi;+oFskQ}@q2q4x)O3<fKs&%WtzzFD};-G{Hxx)V?F$WHWF
z7(*i07&g=2&}`P4G>k5e6yDx`kLvQs@M`+D)vGA+`X6%Dl9YOA?Qrurfg>XqT9E@^
zgWxOT&hX+yo>7=HCb!3BO$p54I3{j@qbN!+nu>Ti*O~vw`5RU!f_JXS+*x#-zFp@m
zr}GGVhgT1=p-TFp#dtAVjM3QdpDoi{l*z?1s=d~(E;Fkn=*i8+oB<M)E&5W?I^M)M
zknOw+hdKDcP%Q}tuai)WoEa!7&-Iumsf3KA>cJ3Ib?Vh+rZWNZ$pO`dl8LcBv_cAA
zc18lYB|rc<0u%wEdTGEup|%_S`L>@ui4LTkvnNApm<q=y*er!iCv8V>#>+b4WIF<}
z^J}=w7L&$J%unXCb|Wy{z3WVlMDNhz3o7S-3)6oqjx)7WX0HTEH<C-Do)>{-=9>q+
zXXtoVPHKfVJMk8bt&h;MII}u~0l79^#`5CdW6Ef!eb|E&Q{UJ$n$yP;^Jd)qhw~ej
zB?c~nN*%0zm%$}MD%|<q*x?^2$-sGY)_qDIsjoQeKH{k^*%_~Mm`JG>VZuS8W+Qtf
zS+Uu?;oSPL<h#s;p3UgxZ3c;@9(LZhh9?&RH`z;Ufi?^GL|RbrQ|i$u#k>L}G`jMH
zn3`(J{6K%B(Gykos(!d}z)Wr!%sjC6=V@s)qG1MJN~uoVlq{jeI#XKPMI;@L^`RBZ
z<X%K$e<C_&9&p~HQ%fuI$-p5?U{jDsR}QoVqzzw}E77mP5v&U`27f1F&0F8zlxE2)
ze=M@fh-;2;q_!ewec2frY%fKQkh6Y#Ck=~JBu;z6vOFXzd7O1mkt`yaC)8Gn>0Fhm
zEI{|uQr0z1gk4W{mj*%4Z*00DBL5ko{4X}2{Dl0wAi#aSmq_r~FBHL|;}P&0k>OU!
zhx64h5vSKwffV0W4JQs2dFBrfQx(B{AK=BGc`U!}S&BFnE6QSvw?`~m^}8j(4$IzQ
z_WzjR?fD!VI8Aa=N;O96$f<JeDN}@@k24)dnpa7nV{o~|y480HWd%qi09M-w5HA7H
z5t)dJA9OeU2(Ddz+nofIxgaM#sfN{v)}n+p872aEFyGb(<(TUTpJ(1Bv9RRP<lWbe
zn*X9W;yA^EqlAv1#u2Gg|1wrNw~{@z1W#o_GFNuVYLs|BsZ*hkg_h`Il0YDiCHm+W
zmS~Y0wwCC%sMd>IWzW@IV2KtfOm4MwFVU~FM5pwL+-yY-+$4mvEEjvjP+5JUm8n(w
zTE>U0(q9W!VAi2soP~_07HUw%Pt_tTYxD^79a6Fw-(PjP4xwLxv3Ycv!%RV}m`xvC
zX`nx*(H@IF+EJ)392Ul)-t@Oj>L>VGb7%C~V}eWde6yYkCcYR2>L5_BFiz*D#3I_*
zY)|v0XvW#xv=Y0=d;t!!=&NUW2H8t2>2H>>rUwQga=@Hd8s$Z+x+rNk0%K7J*cGvn
za#2GFTwHgcx}(hY&AoeJJ>OtvvdouZfGLkWz?5@JX6KrhfDJ0`xz(qU+f2hY)2ykx
zl5dMrs#`m^OO;aljpVNpXHI7j?NBazjFr-P<5NZ{lysyym6ILI!i}auR#r=s8-sHH
zo|F}x&aDr!mLdRfA3dBON<#lrL!uSm7=o9syd*hDuX`F0HkX``(5Ixonj|KOyUg3^
zQc-Q1zi|oXoEJ7t`z@l)r8HbVnV=3@R147(4T%Z?MF>|u+vhb+dmd}f?PMV8SW8Om
zNGeF;<~ukE61hiT7Fejt`7XmU^|R{ev+p#`i$*Qly)%e2TjDu=LV)p<*h6u5gyTBv
zF2X}pxW+%<Fj!P}AZas9RZ`k$Jvv1owwn8%W?{}x!+bkqQCghlz9l!;d?w_cXMXg@
z&=}JPT7tF@L2ahnMB72@q!wG|Y3@>;eRIVAvq#45Tg=WlQSFR|)0f>5G`p(9xM7}|
zFKtPEbWZkN=1qLjD*3c&W=C5QZ78nOyIt7^bEIKqkTQs5B8y0Tx?-c7F3RU`pPOs`
z_?hl<U&@p~CMd0Mfz5AN1#S&Vwsi0NvWloHbK|_KEOMjJm}q8E=E&9JuvOv6IZ8ov
zcoQ8$o#cQM?=kPAi}LePW480inT%^k+4bRRjjowT_3NF_?RV~cwfUrD02;pIjR9GK
zQO@U%q%4cq2SOIu>A-(AYe*|k@#n%-mt4P66m+?M)nmWXqWP-^>As_PEzQPQQFQR8
z8-h3Q39C3Q91oVz2*#A-KL%2bY;8!cmJ9uHA`|<v{z~0`eQ`+GHZb5=o_|mCd#>C8
z$NX`>3!Xc-34zzMQ(s0p^HbkPL0@}t>MK)QkhQHnsYONA8Y3sjLq95yD8o_vXX;;L
z>_rtUVz~Yrx{&>y!BX_$%=h%m(WLsmNbc^@hvIY`rx=`G3p{Y^ZC06YKwy@l-|)Hh
zU=6u>PjJFvP!kJ(Tc+sbM_EIjrY|G=W}4NvvWB>k^nM4`K&TNt=8t0byviN1Lph6=
zm_yLKL?eam;`vUGWXllNQpvgH+$3sPb_yL=Bg|EjmK*vv&mK-$JqW8%=|ASK>2#&P
z_Hr|Y5Dkgu7#^X*C_?v-?p6bh!n7?WmSW!JeSwnSm}M7T5((zV1Sgd@d05#6N@`iq
zIof-m%Wyrh&Os_zmvwFpf)UBIy{<8BeDtovo%NaL&_|tBV$bJ-C;E$apFPY)zG1$1
z&owMVml>CDJKAdL5zE6EYkt$pYmLfF?wDG0`I8N*#DQu4-A7E6KcN`U27=18Fz;s6
zgRIKZJ=&bE;>8osoUL9Ryh=TbC>SSDx$a_ae4Sb3Y{(ciQKVJ&x*C=an(TMl4xLH2
zXX$$5{C?<{&`X7#bw|C!?@WU>(wf=M60Egk4C)t`yyBd`(C=(qFld4VoFf6R4+pHN
zK8Ll6cJ>?zJRuIOK|)?8A%{uGgm6egv3W?S%i_2=V{%GzdHk`#X)(c}lhxAXtow#+
zFHp)}cHUdTEBD@=-@HTIVx!PQ#~t7^T8*<#^hS~|xc9~6%di^At;m{`IHO;U1JyJ&
z?$6LV#Y%45gWjnIu3a5-`VNydN5;meS;L)mKjUK-hMMbbbJA&Cbq9~|S=gw!q$wS}
z<Z(t^y7;u%;xGk;LG3lcOw_zt$NHvB?!ZTuJIo+vtIY)W*7UDg7nZYhgoJ`|`U@?#
zf&SRW>>!$M`UNJWuIMmgl*gmkLk_ZS(?`c%lMZ(&XFK8NP#)0^vSl6vFEG>}Yt=qY
z>WCarV-#iQR(@uObO3d9Zj~Ae<}6f(n;Hky?Oz`=r|lj-I0#^gmZN5;ee)19uN-uf
zbLW7xnioz$Qqpv@afoy00q1WU<dahvrqv*^Tb#kb-RY_O47=@EAgz1AjGqJEU%$BD
z#{P{%{LcENgC^i$Gs0h&&6#v8aM9Ug50ykMQMk~#qpD^cswS=IIHD-)jLMD@Eu?Zl
zXzx^j#tYp#^O##HK)x^gH2Y8oBzw6P^DLtqvNE>|&pEgH8343To6masFPXZZ+i2fw
zw(TOJh6NWV1zH#tgBTU7eP2E-U^0`E%lVvRweM3##v6R|Hc)r2ZWu6UP8uu_SKF^7
z5Ei+b&tX|(bW>KeN_C)b7q?VhC2@*pFT<#gaK20zQb%f_ppm8Xf&=AdHBgp?2g=0N
zzUt06{THYVS>0fh!O|&%MP5GTWr9DpB_rmtxWJV%cw()<Th-`+9pNw^epR)x<&H5y
zNn}p<5E>yvDADh1(g)ek#K;gD6diD^_G>B>y~3*2ri=>?y@k#|fr6r^y=jEkKl3E7
z4M}aqf+KgXac<4$1&vT`xA250AV##H0=5ek@I!)vK3Iwme$0oDmHS)WNy*wIdYTYj
zZRu7LFxIS58JMfP!&x-K4>+HK()5vW=nSz9Me#w3T`4{giqU44ixK<NS-`KgQcF~+
z$)Xx~#$%3oPu5N7C1^%ShRb#_>rd!tunBaOeaO;`@Gg0VSi}FyYeUlc*jfuoTFFEd
zOR8Z4RTBHrnM_v=qLS_KTIyGvYt1|?i!+C4y??`sV=b9MS0Ju6Q)C6T`W3;Z%o85d
ziENh~l0#_RtCgzGELP8JHB9M!#^AHfT3W1T^h?P+q1$V+gEe9y%{FPzuSsRs@Ay-r
z&&$%MWa*cg*GZ8R;SHL@d5gHczoSYe+a|;+l&uAZooROH4pP=g`GeNXPLfFzb`#S1
z2_-JE19Kg4B`^wb`OGw9drEbu!t~n%qeIJiU}$Ld55)5#)skz}?aZlPlQ8z#UJ#-|
zYO^vmzd2P;V*j5ETWQQ}A;NIjCB|%xCEmF;jXrG6JdLv!xSAK@X@Sdl!B-26nk^;Q
zowGGGn&>N2cRRN_tq77S`L(hZ^0u`V19Af$;OpSM*@-NJvG_<B4C7r?o87^iy*8Wb
zMrpq6c67@_sMBrzt2>@@hy5J^v<IIiJ1y|!Q!YK$isdqQoTPDML_TG>d5CVZ8v5tF
zwQ7lkRx1I6-#=R@`m)Md`q#Na+?08k)vz7fn~b?P7;2Kt8t}>IiMVUrKGxYujGZWb
zLanz`MzcgG7IDuLahiX|7e$b)I}hh9p%{<(HOiH54&kp~Ytv~>ArTCn#S8~^$oQ)X
zh^?`%yGTMs6NUtL_ntBL;MA&#6mDP#8v#36b}%i_U$y`ln#i)B;*>S*Pvjco$ClL?
z%=q~elnuXpj0WVh4c6?B5^b?x@W;C;BYJ#|yQV(-^BV8xS@qdyP_7}XGtF%KKWAjn
zLectNCDB|O$s?N`pgU^fn(!runKLO{ZL*IDdN#goZ=z)9FDy|a4b+7tIf&rq{hz40
z&UP~#62@?Yv#|LPJJk&HQ3e)?F*x^tH_b5TT8Z=h%QKll3XntrekU{W1ucz%R_!vl
zu6JTwtI@B2wku%k4*@aLHLf+aS<jd)!%M#cTQ)o{<ty6y;vrvlB!}@s{CO0_`ltZs
z3fJ>dHs*_rgZ{Wh2W%`KXEPa`u}qU^8Nd`Gtzm`f-1-zBi0iySJ$H?3COIw5Sts}8
z<+Vm%m)h*yTBpLCW?Q^x1F!Vd+Cd-yYm=~2?%cW>C+BZ7&rJ<xIqNRtBg?sU36IuH
zGk8uOY8JK)$4P80(iq7HrP*8qcI&NRs5o4XL)iMFv+i5c$~Hy3oMB$wp_-Th?yNKL
zAangr28eU(Pbpw+wfW(1ey17vQuDUsxUj8DIfV^QQ0G0jGyEy5^P3)CLis=cawvai
z-5gx4GVHJ%DF#_>{WkI2`jH<!Izhz8W}oAaF^s~#^M*_X2XtOm#D*kvo)l8G*-}>+
z<t5PsS#I^dD)cT0YpM^@RaIwOUV(>b9w~ZgNut<T7H`U!4Nfz|w82YY^r-kX#J6>(
zRG;4bHiKMr_Jpiv$aIiF9yPwvac%awnv<K8gmQS^5Q443>2~cp8C&!2=C}j(2#tMi
zjAaHm5bPpSUwa%RYp-#*{ngfz;(tXArj2S*S=&8{L(57D#>Sy>ye}&aBu|6{WXYoR
zJy=+9jhe&f&&Pd^I=}K3&D!?hXM~&KKNL|-rI@I}J}9IBm%CT4Pr(h2lA`RU!W}#z
zTt1O71J@X3uEEEm16dpYC#BMwiUd{3p3PQWl4fnzvSl_Q9@M}hNeE;-!hE}nWGGc1
zPd%s4GDneKLvjGcS1HB`9XaviNE~IJ5)rQKQ@w;(FbQa{p*Dyv{NvkHXAi;5a-v(C
z`r^gH3Wfzd%G^(xROzgOnu~kNc%v|Y{{$u`D4$wu6mDT|WDAsPz{x$PmVRmi?cZF+
z-U3yHJ4XL3ya%Jx{3B1Os@RU`W_KkhwTO`EP<`_mS~KR8U+7dTIE{Ja&Tt#Gon$nl
zE(dWJp-%nLFGR6dIAy<_TXIXDnE(n>ay2-K8OIy5nAx_qmLyOgtQ6Fj%*-=qe@HKi
z0nCq$syuW4!}7)5RiQ;?m+>J6id0FQbux>KbU4=#b?)3Fg%G{}A@pSk=NYO@J@Gx(
z+{gD5$inzGt&2vIBM=9%&Ys$We)D#=;$X>?T(d~*H3&8|nSsg$L4-o()4BCDnT9d8
zE_0<UD}u4Lw;fd;UFHK1Sw-$AMSfUDn)r(v5hd^Sk`)Y2*Ymsk6l$eaD9LZJB+_ZC
z?#wseq9VdWMx##Wq_ehmu!z%RL@#$oFo~*F_DyBDl?uh~G*>`&P_=OS)^ylwt2<5*
zvwCk}v{^^0RD(Mo4Ce-R%T811{Z?J%>mVhkZSqsZUab`AH#ms$5NI#mLjx`}s<cDr
zd(bT?x#j~c4Ean`t;tA{$e7DliznxUyYchy8+U-d7c;x*N+iTJseQy>ob@d<%w|L(
zocFxQ+iwIN$`Lbg(^wA>sk1CDaCHq1dn;88aoAtv)vqavty0V_rw}n1A$&%RTW^fp
zY)}2T(vF=bG5SC~B*4=@Q8ksK&3H(1Umvsi=+-mqUO_!8b(bJ>RT_kck`^w4=oz2-
zwmQq2dD6<s{fq(TOjQ^`MAUW8j=)Q)pKZQtBiUBnNhi3h<-*+j`^bGNgVvX9{sEGR
zNO&hvNz2S>)<X=Yal0`ZAdBD?=G#SKJjZ;G*RVweNW@0_IHN=HbIvdd$%?KtCDDXl
zS-puTv{HE}Vwupja?ML6W68l~ZcsT0fl8=k*}`^H<U@)jw_TZWQdA3@6ACGl0(xdK
zv6O82hzlWrpNr9j5G_^2VwJ3Rizru3uw+-GLsw+ulN!^ZTID%+Zm>hOs(rtPvK;BG
z{Y=ms-NO?H{RW<b%v>f<@R!l@1ap~PGv8k0k3-q__{PCC@7C5Fh^ikPxV*RPmYM_6
z0kfvSzBw?k$ERj&%~qlI8?ow$vto~Q!31rW=wT=8P}xDGS$oy?u<(xFOYiHeWgsP#
zT)aFG=O0)ID^^KfcN36{h|5_lk9ol<i^Xs#!VJ1=)5TyRo4{4=Mm$HcD9|-JJ&<fh
zkv<f^_enN#g)O(Tku&Sh7?;YX7>2Erhw1%VG`GJQ^J0PAl8jr?Yx*E!U4=K2it(Ud
zQ6rhrtZtLI1dW*3;fTHQ-7(GY#w6b|7=sK8vsi6UF!k;QP1I`7T{{)D%r}j9f6JY_
z`axh=-H>^}`P?qy;<rl2GrJD5de^xKlln23Oy<F+EPK<&BrJD#Zc35s&LNx|Ji}&J
zXm_K>er7j3=la1cXR(2P^}~G5U@)^Y9R^W~(Yf&ei6pNG>XS)n>Z@{y@SU?&+x_PP
zwi4TIm{g4?h9h`GI^_u<CDQ?3teJ-(%{L@AWgch0dr;Ksu;h1GD-v@Vd?KD%8=f^m
z;~-ZoK9U+x<NkT(4r1pAmLrJ72_nawwuDKdgr0<*Fp4!2$;P1$QjoiH>ccL{tvDS(
zC7i=<#ERSNqK5joFl%3Dof%|KBvEU5qQ@ea%d`kN0xVuIHgfZRyPgfKsk;4%Cssd!
zRZy@kcG~O{Xfb=dB)TDUpTCpV$~J|+y5e-hioLf6Tpsh<?=bFK?P5~WABz$q<20L1
zgK^Njk^zL6F8vdO>o_n_hSP(E;qsV|s#j?^8BAB(5Hf@{N#z(eFM>tMXu;~1uk&K#
zE;Rzpm%)M=;(^<h1j!5clYZyCd5BydPFZnUI5nru$8oe_LALrZ21JRzsDzD_MOjK(
zk00E|rj4;t{uou#?P7|O!p$-N?LHWDp|9zbIyggai<?WN4itPete-Y-G=orT;ji9@
zLZ=ymGJHhw=e8|l=poY$b}_LL$-0_PXX|5f%|!A;LiZHb1)@|=P1CS_a;kCA%$JSh
zxHn`U3rtF09;IJZvp#yJae2*p+iYVjBMKEb-&RqNfxq_i50rAjaJMzrB+u3l!Dye9
ziMZoyHmr2-3XD;W@iY-=yLLglF9DNcS7U9=rn>O${@GT2SY*Q<WH6{6fu7s|*TK2<
zT3P#Nn0GR%^BYE+f1!axn_2WK8jB`q6;Wudt(Y3NX71&$7WkD1)-24lgPvS-^RHD$
z_24>}7pOi8US|%YNHQuI9Dx}gPKACg9BY2xSRbtn$9iuY9oSBsmKgV3c(wEn=%-nK
zD|%o2NhvE{vveJc2sn-K3I^M)_Ob0-oNJyT-AUD_7&*4H{_58PGyIvmsB7>#GLE9O
zM_%Yt+6~?L-bud7E~=~mV~m!R6?=_4{MCo0O}Rex{k}23X2mR8`5ssCbIoY$sMFI9
zV=R9en4=k(1bGJ`JxbOSr0X_SY1>&AMP{IxnuM;$(R1rZhlZsNjrRzXB)?&li~var
z?B}%klDLWDf^4)nO#Q>nX4L#{frSueKHj{6e&Bw?L>`d{`ZHFsWS3ZmQoc`R>p!Zt
z)MWNo*@Q0+(@KUAHQ#)n2!1ZmKjktmg>5tXOlEwvo@l;@bE{CFH1qfBRZ%~VD0^FK
zYxkW_5R7B$+uR~XI@m1DA|0`t2h;L9#E9HeM)1wN?ybHta2K0&yD%+>v34#tOPGE6
z`4T2CtnhJRUgKcr&fU(Poo6zxgN->hy>T#X%%RSme-YWd)|AY6<Q>vM0lNYNQ&yn%
zUR-P#5K5nU)Yx-dWQHOQ5Jo1y$g%9Mk}!8IeeMr47nESfX>;2=StXRpPm!JqVOg!O
zss1JtXWbeChf1w%MT>HGxYweE6iHzp10k|K23P|lvUm(HB!wrCOfHOAC+sN2t35LB
zOh)u5<f*#!IgOW4DXvp=1(w6XCDf~{2e47@U+w>B9syRTR=6tT`Fqj2nANt5guo2m
zFRo1DZ{oTuaTy*M?|e>p@X=?|N4fNYq|h*m3`rtjb3S)K(tr~W*Ak!p*pjtM&|QE`
z1g;w|3YQ_Trwmq5RfH^6ge+BrELDUoRfH^6gsiVr1gXj)W9({XO@BJWxitVf8QE40
zLOB<V*u~}OEb%~M+|m&GzUoKm-f$<4BQ9%Yue(_y!71{a^buyY_Xq#|XDDPs%>2Ws
z#?1K7`D%?yj@5<1AMJ1LLKc%*@PGU7yMNKNXMh&qIPd`w1JXJYm<B8WRsu!9-9SC?
zFz__+B5(jW4s-yHF5&^nKrT=M+zs3V+z<Q!*a;j0jsd5DGl2bbjG6(Xfr&seun_n<
zPy*Z!JPqsx{seRYgCIwZ1g-=!fTchQPzP)SegOOo_$_c4I0bY7age!&1CxR40S|CH
zPzG!S?gbtLegW(T4g>E39l%IX`-wm@a3j$7_kLoU_KWm1ZQ4y~+M(s#*}g5UJIHUI
zPSYM7*7F_qSY1$D>MeBZ<?cJYy4$<HSa+`~FZ8-sSC+4FS5%g-@>W$%;b7krZdIkX
zK=(%axhGU<{MY7`8>NNrvT{ksyGmSfD<~6()x~9nZqEk2sJu*h8hXL)rCx%Nv^H*R
zh4Ps~G%44(vEA{?E4*bY)KyihDvK-hDHR(epUO-M>aj|vX=}79ZIxE8Rcc=TP0<Rq
zQvT7GTA603_bVh>ZDN^GT57!tV<JYH(52a8w3uj@Ju@@2pZumLX&x2Wo$Og2>(H)C
zO3L#<8gjb@-_RT@i&pZ}wDlG1`8fyy(bwVN;ozTqYEO+#*R)Fkeo@gjd%u`iNB_71
z@dF1rU4t(gk}&k*OA?0-A2D*&=rQiGmyR1h;j+soUUB85$yZIeI_a8gr%szb<GSRO
znW?j8U;nkV^c&`6WX_$JHUGw&7Gy76<XOBVXDJptm*;=|=37?WdfUo^+gBBOSKm=o
zTykgWnzHhWyDF=6W9_>28}9zb#_CO*6`47+OuE!lUR<VoD=E`WTBf!{Tgcx9+EndY
zS}cRN1**Im-riy7mR8NJ^m;X(IbJ=tpwv+B^CI5UOH0dFN#shSOfO#Jb$cr-%PZZQ
zHjvI;x?oXGj^!esTF(51^CCXAj78b$^B4BGESZrsb=ttV^fGrrMMY`xssg>3AyZUP
z<z7?3uq?n`*S%{hbQ!Xx<pm7gBCmUnJDhiE@$Hobl^fi})VZ?KyGk$JFeT1Y>Mf}9
zGO)|^f>p#MMnvkDSGlW<ii+||e7pr~+^Z@4n(|67Y4Ey6m0*f0Jmr`2O&u6_l{>ws
z7zSx)=geOaF>~~y;wpDRRh4(m?WG&sg+^s@*&XgOl3FXppd!U(#d>i;Y4P1E`M9ML
zo;e~F_7c;5yKx8K?hWNeWn@{WxaaF`g03mA(%q%ScX~-(s#EE$GD>xK`D*v7g3?mS
zjFyrzUA3xwO@*4`6R%!XT6u+gwNbW8wW*rn1wDl-tI{itRXUaDzw*o|EzK?{E>m@v
zdS5H`R@1wz+_<C2T~$%Aij{)k41fZrb3}thw%0X%+N-<nUaRw#EVbHOFQU-pWvjeX
zzIuB|K2o+M$zu*FN%?v*C=B^un=JlDnOb!iIXxlVMc#r6tF)wZ?R8&L$92UK5mmqS
z#G7%!cvX7gm&BVc@hS{P+uGtv-6$yS=^*Jzm4TFtIdOruzpcDXmhGz<II?=Hg|)j}
z*Q7|io_eeGlzC89PInc0*A}nx_Jj?!k#~Is^M*}9TBc`as&>9cwU0rLp)hM0cEx%T
zdqSa%f;;<$zi_*RA{7?s1r%YR)#VY>Qce0w?_GwsN(v*Rd`W15p#xdT))X_L7<AI#
zGTe<aqe>cZUBTaR%G35qstwOO?!9I7T6x(TZ<$UVB&=$~^M);`yu*-yRjR=yteQ`&
zS;TaiuobdCcdtZ}ge-4fHG(xQyLeS)c~$vp-JM&kYB^`pr0(`uU@dwqPg)%FVak*#
z+AQ|&J1SYt$_iMKjj}t-%GZ@$PalSwFjLm(v2k&1q7rPTTO#x0<g^R2zWR;gT^RfF
zdm!SyiFdUb;*JiC?svpDyWh7(yu<A4cIU1@_xpDu-eYQN?y0G*VMDgvQ*+OjnuLD+
z*patx-AaLyl4?9P^_oMQczLoXuZI1WP1)nACwuqAn)(`IX>7|yMMVxr?D~p|brlu8
z_G7&NzyG<lzW*kIA6ftU`ke1O3ry+D{?%z;{MS2tt=97|O8aX6B2(C+_56#5xcycB
zh2y*bzwdwT3;pj#!{h(q5fD||{SSfXuk;J|pggxk_56#D`fC5e@y|D=|6^`{Z3akA
z3H%G^C|^DAE)ntm5B&Ou|7x}E3FXpy-mSN&D47H`wOf33TkrX1eM6)F-llKex9!{a
zf9Jd3d*J&IKJ@TEJo1k}_~E15AKUTx6Hor=sUQE3pFI83pZ(J_KmWxqfA#Fn=bnGz
z*S~r3rQiN;SM%;Ydw<{3x^Mr1mk<8o&?|?Jyn6JtKfeCPu{Ym(`}jZq>75fN-+k}Y
zzx?@qv+Z94r~mDP58FTb_m4Y1Idiu2)4zPy#pTGq`9O5x1J74F5dCM@|35qbzq$SY
z+JW@K{^~&bpI!f~teI=p%&Zd9gjUFJvOAlfTV6Ks)3UR#E-bv77k-{>O-lzj6LXGJ
zM`vwe`P%OHMVywzImcVUk<<#1Zrov1>6&(<QL56o5nNf)O0TFa7MetMLFK9<o^!po
zR~j5t#qY*~GWAM6lD<Z|lBPylk`7QtybY3u#Fw}dN6RVDjmkniB)!UF^|rLgsH_UP
z<#`LsyrGY!pwZ%-U0$YqbBxflK$o~0@if9~gp)8D{u+n;5RD~|qiOlN99<oH#C=(n
zw{p?#C7cuH_Z*Ui;(_0Sf+{_oGv-=I4i!d)a<jgzWVCE(N(Fa#Zzx}%t}V;STr&0A
zDH#hOKaeL`QvwP?c_<b&wAzO%Q*#=CcAz<E6&i;&qN!*xX*hm!7A;(~Z0UGy3TIyV
z4%3sS+^&+reNCZqzlFRuaH?3dq`X`*;Fo1R{+IsNT$HXIhC^v1_TlT;X^TN)A3A?h
zkaeNtX&N+m^$dT%0qstH;qQHY{9hc`+y7vM|Bol6X)git3&+1V!hhEEG%XE?^zWPh
zdoz3cAC8DG@qV7#+dndY@lTy?`OAAO@8NRv&1cv3R=5lKfBdxz`;SUb(^3HWT`2xl
z^LqRDE$3%9_V({vzB?Cwx&Kc+J#~9A;{8~k_9|b}6Yd)k?|t)|p5Hsa$aLQRdYbkj
zAir>ZBmJ+sIZe9;i1gppryTXS_V$nL*F@;USBGfC;q?2K?~0NO$CrF(miG4V8~^$Z
zz5OHem-q{7zuf=oExrBw_UHKT_4e<Z{!8Ega{r~<d;9k-|I1JG_U}6{zx^Z2U*q?O
zCwuz5Z#fqHtamzn{fl<@_U~KI0SD5wrJs^X=r>3MojVc!>izt0p32|GQ&|!<&s*lL
zgt#=vqLj_iD@!xiLc4)ag`Y0mhdDx04|5>O?0E&n`rPu$94I-ZUTbI6zNgJmypm8b
zw#R?6K}3&8G^?PjuoMj96G=6@ywE81&V^XJ5Sk64-_kOLVn3%6QZdB99CllX;qZc@
z7kCTSdcWZQm!4Ftg!43Ql0B!?3odbKG&x8?(hCbA7K8uvi;85TR7l)8<!jbZq6Nie
zWZy1jwbFsHBXz%C(#X*ZEk}505=Y9rbVG$#n`QYHK*g*Oq##}U9hg(8msadkf$Qu`
z!_>R(7W^M7e*=<zSs3Zivh2&sic|{~X0Bfal11&wPBAgY*eTrwy<d->UzOp7hJJ^)
z(nEEn>)w|f1UFHnFHL(gIt%)yVs2=UsdtN!af>R6N2;LxK6<|NfDkslh4af`eF+6m
z)0!jQ!9K$7ITAO0jz`lHq%{_0X3P5tN(1MlxKNE5FdyxD`_j@X0$BW%S@IR)qI^x>
zyE!eh<x3T@LwX~k^goMeuceCoIv?ET`}REAT8$y?O!NZihau7+qv_X_ImC15+au{^
zg*g?)WmY%e6eSsE_E0u+bm3l9rE9w+&o6pt3oZ~NPph-%6&HHv6cto1EzcH8@eLbv
zueSUA=`dO!SN&kk8ci#(=UOyz)dKmp#fG<XgU4H`xH7N_RC$>_CDPVQi&xzl8mB*r
zXq(Ugqj7T7_*7`$Qn*y<Rchq&raf$1qL(f!TL+S>{aBS?iP!3mTf-#?^-i5iIkYIy
zvkydkGkwAIZ-|;(YE%_T+BX=hS9>d&X@8DhFekg9!fHo)VvMc3EtZyt8%Q%FL(vv#
z)_jt-m-$7!IlWy7(<b>ZP|O!=%4zS*IFa1D*?m7zHOeWzo6==yb4tsryrBtvuQggi
z>ruM)a71ku8G41G%jkWeSExKKMrK~bDzG86%1Nf!ErdI}rlO$I+g;n--Y%5-n3OSM
z9OV{N77Jr0UArlB$->M9oCgX^IV_dgmcUk!bT#ddR-D2`tF7<Lq%A_7EAtph04cpH
zgwBAy-GGlqoBj9i|LzvpB?|HQ$<v}xh05y+JtH0nS_#&3!JqgG{P*v_Ti~m<z`{SL
z{pRPxewXpD<I>dFDt#B-`T)nMV2ubY{4f4woL&rs$D}RvZs(Z@^aBP0$f0Qcfmk3O
zaD<-XCf`y7@e`h0*iX`xxbj3Rhsr~yi?|I2E((F<Jr)r6>41EvhrZ{8zFFW^oFyUm
zoY0eHTBV=QQ}SjxR_Uza=>}MEkw-%21CX*xJ)}G}fRwp5^xVQz{C$A<*8x%<xd3<t
z@Pp9zcAiqc#{tRjM}UNT4v;z>0>u9fK>QPF6ltGuoAKJcHblus#4r3Eeullm-+iBb
z{ri6ZweT1652y2A@9DbW&#J5Yg1`S7ZE<0ygjK%_6UF~))L&|G!66XZ$uBqr-2Zjj
zfSUY2J`{?Ef`>)h9gnkNt=zI<%h*uoJo%3Gvi%9`S^L8iUGkQ;sYX4YB7F0Xw|2NK
z?=SqVMfO#GX`$z{Uom`oDEv;szw+3r$A)YF@|gM9%~oO&f4kG)v|Ysz-BF9*y7eu$
zcH3JeZ(SP^(t52udhAappr>84$%<L}Zx-!tPAFt}4gW&KztLga@bq3O{H@<o&c0<8
zd)47zQ6Nog|1eFf_$W=QADON_Nd6LDp3>KX=g3d?)=o1`;TQ*b%AWlwPua^IJY^Ce
ze?Lv_#ZU7T9HXA+5T3X26r5%}&tW{f{+y-_=ed{X2%h)y6kMT@=V+c8Jjd`n@h@qb
zo99zJ$MSsURGP91=Hj`YZ;j^$9_{a?X?OEH!BYm?ah^e*2YDWXzWY^x;iK><NmuF=
zT9h<tpA!21!H?6l?*iL^dx3hO4yXav0~J6Ka0}o8vVd7YGB6ED0wx0!f$@MF7zrc-
z34jZT2kb!Sztbmx2}t-8JdXi~fxW<sz%#((z@xw;z&2nbPyzI}_w>2+=@jadL7(4y
z#b1Zbp`VPADB?+6d4_+|PVRo+k#0QiPsT~)ucpF^-~N%s&+_Cfjr9Hxzk4$Nw)lss
zmkZ@sGN!|sN4^W6LqL8q7E^(*12QhY4?GLJ27C+*reTtRg@9a?3CEd<Up}x7cmVhn
sa1{7=KrVY;4P*nQ!2j#Nzb3L0-REZu{lfJw?Z8eMa0{>$=sSM?C)~1m4*&oF

literal 0
HcmV?d00001

diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/cli-64.exe b/vendor/setuptools-39.0.1/build/lib/setuptools/cli-64.exe
new file mode 100644
index 0000000000000000000000000000000000000000..675e6bf3743f3d3011c238657e7128ee9960ef7f
GIT binary patch
literal 74752
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

literal 0
HcmV?d00001

diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/cli.exe b/vendor/setuptools-39.0.1/build/lib/setuptools/cli.exe
new file mode 100644
index 0000000000000000000000000000000000000000..b1487b7819e7286577a043c7726fbe0ca1543083
GIT binary patch
literal 65536
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

literal 0
HcmV?d00001

diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/__init__.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/__init__.py
new file mode 100644
index 00000000..fe619e2e
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/__init__.py
@@ -0,0 +1,18 @@
+__all__ = [
+    'alias', 'bdist_egg', 'bdist_rpm', 'build_ext', 'build_py', 'develop',
+    'easy_install', 'egg_info', 'install', 'install_lib', 'rotate', 'saveopts',
+    'sdist', 'setopt', 'test', 'install_egg_info', 'install_scripts',
+    'register', 'bdist_wininst', 'upload_docs', 'upload', 'build_clib',
+    'dist_info',
+]
+
+from distutils.command.bdist import bdist
+import sys
+
+from setuptools.command import install_scripts
+
+if 'egg' not in bdist.format_commands:
+    bdist.format_command['egg'] = ('bdist_egg', "Python .egg file")
+    bdist.format_commands.append('egg')
+
+del bdist, sys
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/alias.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/alias.py
new file mode 100644
index 00000000..4532b1cc
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/alias.py
@@ -0,0 +1,80 @@
+from distutils.errors import DistutilsOptionError
+
+from setuptools.extern.six.moves import map
+
+from setuptools.command.setopt import edit_config, option_base, config_file
+
+
+def shquote(arg):
+    """Quote an argument for later parsing by shlex.split()"""
+    for c in '"', "'", "\\", "#":
+        if c in arg:
+            return repr(arg)
+    if arg.split() != [arg]:
+        return repr(arg)
+    return arg
+
+
+class alias(option_base):
+    """Define a shortcut that invokes one or more commands"""
+
+    description = "define a shortcut to invoke one or more commands"
+    command_consumes_arguments = True
+
+    user_options = [
+        ('remove', 'r', 'remove (unset) the alias'),
+    ] + option_base.user_options
+
+    boolean_options = option_base.boolean_options + ['remove']
+
+    def initialize_options(self):
+        option_base.initialize_options(self)
+        self.args = None
+        self.remove = None
+
+    def finalize_options(self):
+        option_base.finalize_options(self)
+        if self.remove and len(self.args) != 1:
+            raise DistutilsOptionError(
+                "Must specify exactly one argument (the alias name) when "
+                "using --remove"
+            )
+
+    def run(self):
+        aliases = self.distribution.get_option_dict('aliases')
+
+        if not self.args:
+            print("Command Aliases")
+            print("---------------")
+            for alias in aliases:
+                print("setup.py alias", format_alias(alias, aliases))
+            return
+
+        elif len(self.args) == 1:
+            alias, = self.args
+            if self.remove:
+                command = None
+            elif alias in aliases:
+                print("setup.py alias", format_alias(alias, aliases))
+                return
+            else:
+                print("No alias definition found for %r" % alias)
+                return
+        else:
+            alias = self.args[0]
+            command = ' '.join(map(shquote, self.args[1:]))
+
+        edit_config(self.filename, {'aliases': {alias: command}}, self.dry_run)
+
+
+def format_alias(name, aliases):
+    source, command = aliases[name]
+    if source == config_file('global'):
+        source = '--global-config '
+    elif source == config_file('user'):
+        source = '--user-config '
+    elif source == config_file('local'):
+        source = ''
+    else:
+        source = '--filename=%r' % source
+    return source + name + ' ' + command
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/bdist_egg.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/bdist_egg.py
new file mode 100644
index 00000000..423b8187
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/bdist_egg.py
@@ -0,0 +1,502 @@
+"""setuptools.command.bdist_egg
+
+Build .egg distributions"""
+
+from distutils.errors import DistutilsSetupError
+from distutils.dir_util import remove_tree, mkpath
+from distutils import log
+from types import CodeType
+import sys
+import os
+import re
+import textwrap
+import marshal
+
+from setuptools.extern import six
+
+from pkg_resources import get_build_platform, Distribution, ensure_directory
+from pkg_resources import EntryPoint
+from setuptools.extension import Library
+from setuptools import Command
+
+try:
+    # Python 2.7 or >=3.2
+    from sysconfig import get_path, get_python_version
+
+    def _get_purelib():
+        return get_path("purelib")
+except ImportError:
+    from distutils.sysconfig import get_python_lib, get_python_version
+
+    def _get_purelib():
+        return get_python_lib(False)
+
+
+def strip_module(filename):
+    if '.' in filename:
+        filename = os.path.splitext(filename)[0]
+    if filename.endswith('module'):
+        filename = filename[:-6]
+    return filename
+
+
+def sorted_walk(dir):
+    """Do os.walk in a reproducible way,
+    independent of indeterministic filesystem readdir order
+    """
+    for base, dirs, files in os.walk(dir):
+        dirs.sort()
+        files.sort()
+        yield base, dirs, files
+
+
+def write_stub(resource, pyfile):
+    _stub_template = textwrap.dedent("""
+        def __bootstrap__():
+            global __bootstrap__, __loader__, __file__
+            import sys, pkg_resources, imp
+            __file__ = pkg_resources.resource_filename(__name__, %r)
+            __loader__ = None; del __bootstrap__, __loader__
+            imp.load_dynamic(__name__,__file__)
+        __bootstrap__()
+        """).lstrip()
+    with open(pyfile, 'w') as f:
+        f.write(_stub_template % resource)
+
+
+class bdist_egg(Command):
+    description = "create an \"egg\" distribution"
+
+    user_options = [
+        ('bdist-dir=', 'b',
+         "temporary directory for creating the distribution"),
+        ('plat-name=', 'p', "platform name to embed in generated filenames "
+                            "(default: %s)" % get_build_platform()),
+        ('exclude-source-files', None,
+         "remove all .py files from the generated egg"),
+        ('keep-temp', 'k',
+         "keep the pseudo-installation tree around after " +
+         "creating the distribution archive"),
+        ('dist-dir=', 'd',
+         "directory to put final built distributions in"),
+        ('skip-build', None,
+         "skip rebuilding everything (for testing/debugging)"),
+    ]
+
+    boolean_options = [
+        'keep-temp', 'skip-build', 'exclude-source-files'
+    ]
+
+    def initialize_options(self):
+        self.bdist_dir = None
+        self.plat_name = None
+        self.keep_temp = 0
+        self.dist_dir = None
+        self.skip_build = 0
+        self.egg_output = None
+        self.exclude_source_files = None
+
+    def finalize_options(self):
+        ei_cmd = self.ei_cmd = self.get_finalized_command("egg_info")
+        self.egg_info = ei_cmd.egg_info
+
+        if self.bdist_dir is None:
+            bdist_base = self.get_finalized_command('bdist').bdist_base
+            self.bdist_dir = os.path.join(bdist_base, 'egg')
+
+        if self.plat_name is None:
+            self.plat_name = get_build_platform()
+
+        self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
+
+        if self.egg_output is None:
+
+            # Compute filename of the output egg
+            basename = Distribution(
+                None, None, ei_cmd.egg_name, ei_cmd.egg_version,
+                get_python_version(),
+                self.distribution.has_ext_modules() and self.plat_name
+            ).egg_name()
+
+            self.egg_output = os.path.join(self.dist_dir, basename + '.egg')
+
+    def do_install_data(self):
+        # Hack for packages that install data to install's --install-lib
+        self.get_finalized_command('install').install_lib = self.bdist_dir
+
+        site_packages = os.path.normcase(os.path.realpath(_get_purelib()))
+        old, self.distribution.data_files = self.distribution.data_files, []
+
+        for item in old:
+            if isinstance(item, tuple) and len(item) == 2:
+                if os.path.isabs(item[0]):
+                    realpath = os.path.realpath(item[0])
+                    normalized = os.path.normcase(realpath)
+                    if normalized == site_packages or normalized.startswith(
+                        site_packages + os.sep
+                    ):
+                        item = realpath[len(site_packages) + 1:], item[1]
+                        # XXX else: raise ???
+            self.distribution.data_files.append(item)
+
+        try:
+            log.info("installing package data to %s", self.bdist_dir)
+            self.call_command('install_data', force=0, root=None)
+        finally:
+            self.distribution.data_files = old
+
+    def get_outputs(self):
+        return [self.egg_output]
+
+    def call_command(self, cmdname, **kw):
+        """Invoke reinitialized command `cmdname` with keyword args"""
+        for dirname in INSTALL_DIRECTORY_ATTRS:
+            kw.setdefault(dirname, self.bdist_dir)
+        kw.setdefault('skip_build', self.skip_build)
+        kw.setdefault('dry_run', self.dry_run)
+        cmd = self.reinitialize_command(cmdname, **kw)
+        self.run_command(cmdname)
+        return cmd
+
+    def run(self):
+        # Generate metadata first
+        self.run_command("egg_info")
+        # We run install_lib before install_data, because some data hacks
+        # pull their data path from the install_lib command.
+        log.info("installing library code to %s", self.bdist_dir)
+        instcmd = self.get_finalized_command('install')
+        old_root = instcmd.root
+        instcmd.root = None
+        if self.distribution.has_c_libraries() and not self.skip_build:
+            self.run_command('build_clib')
+        cmd = self.call_command('install_lib', warn_dir=0)
+        instcmd.root = old_root
+
+        all_outputs, ext_outputs = self.get_ext_outputs()
+        self.stubs = []
+        to_compile = []
+        for (p, ext_name) in enumerate(ext_outputs):
+            filename, ext = os.path.splitext(ext_name)
+            pyfile = os.path.join(self.bdist_dir, strip_module(filename) +
+                                  '.py')
+            self.stubs.append(pyfile)
+            log.info("creating stub loader for %s", ext_name)
+            if not self.dry_run:
+                write_stub(os.path.basename(ext_name), pyfile)
+            to_compile.append(pyfile)
+            ext_outputs[p] = ext_name.replace(os.sep, '/')
+
+        if to_compile:
+            cmd.byte_compile(to_compile)
+        if self.distribution.data_files:
+            self.do_install_data()
+
+        # Make the EGG-INFO directory
+        archive_root = self.bdist_dir
+        egg_info = os.path.join(archive_root, 'EGG-INFO')
+        self.mkpath(egg_info)
+        if self.distribution.scripts:
+            script_dir = os.path.join(egg_info, 'scripts')
+            log.info("installing scripts to %s", script_dir)
+            self.call_command('install_scripts', install_dir=script_dir,
+                              no_ep=1)
+
+        self.copy_metadata_to(egg_info)
+        native_libs = os.path.join(egg_info, "native_libs.txt")
+        if all_outputs:
+            log.info("writing %s", native_libs)
+            if not self.dry_run:
+                ensure_directory(native_libs)
+                libs_file = open(native_libs, 'wt')
+                libs_file.write('\n'.join(all_outputs))
+                libs_file.write('\n')
+                libs_file.close()
+        elif os.path.isfile(native_libs):
+            log.info("removing %s", native_libs)
+            if not self.dry_run:
+                os.unlink(native_libs)
+
+        write_safety_flag(
+            os.path.join(archive_root, 'EGG-INFO'), self.zip_safe()
+        )
+
+        if os.path.exists(os.path.join(self.egg_info, 'depends.txt')):
+            log.warn(
+                "WARNING: 'depends.txt' will not be used by setuptools 0.6!\n"
+                "Use the install_requires/extras_require setup() args instead."
+            )
+
+        if self.exclude_source_files:
+            self.zap_pyfiles()
+
+        # Make the archive
+        make_zipfile(self.egg_output, archive_root, verbose=self.verbose,
+                     dry_run=self.dry_run, mode=self.gen_header())
+        if not self.keep_temp:
+            remove_tree(self.bdist_dir, dry_run=self.dry_run)
+
+        # Add to 'Distribution.dist_files' so that the "upload" command works
+        getattr(self.distribution, 'dist_files', []).append(
+            ('bdist_egg', get_python_version(), self.egg_output))
+
+    def zap_pyfiles(self):
+        log.info("Removing .py files from temporary directory")
+        for base, dirs, files in walk_egg(self.bdist_dir):
+            for name in files:
+                path = os.path.join(base, name)
+
+                if name.endswith('.py'):
+                    log.debug("Deleting %s", path)
+                    os.unlink(path)
+
+                if base.endswith('__pycache__'):
+                    path_old = path
+
+                    pattern = r'(?P<name>.+)\.(?P<magic>[^.]+)\.pyc'
+                    m = re.match(pattern, name)
+                    path_new = os.path.join(
+                        base, os.pardir, m.group('name') + '.pyc')
+                    log.info(
+                        "Renaming file from [%s] to [%s]"
+                        % (path_old, path_new))
+                    try:
+                        os.remove(path_new)
+                    except OSError:
+                        pass
+                    os.rename(path_old, path_new)
+
+    def zip_safe(self):
+        safe = getattr(self.distribution, 'zip_safe', None)
+        if safe is not None:
+            return safe
+        log.warn("zip_safe flag not set; analyzing archive contents...")
+        return analyze_egg(self.bdist_dir, self.stubs)
+
+    def gen_header(self):
+        epm = EntryPoint.parse_map(self.distribution.entry_points or '')
+        ep = epm.get('setuptools.installation', {}).get('eggsecutable')
+        if ep is None:
+            return 'w'  # not an eggsecutable, do it the usual way.
+
+        if not ep.attrs or ep.extras:
+            raise DistutilsSetupError(
+                "eggsecutable entry point (%r) cannot have 'extras' "
+                "or refer to a module" % (ep,)
+            )
+
+        pyver = sys.version[:3]
+        pkg = ep.module_name
+        full = '.'.join(ep.attrs)
+        base = ep.attrs[0]
+        basename = os.path.basename(self.egg_output)
+
+        header = (
+            "#!/bin/sh\n"
+            'if [ `basename $0` = "%(basename)s" ]\n'
+            'then exec python%(pyver)s -c "'
+            "import sys, os; sys.path.insert(0, os.path.abspath('$0')); "
+            "from %(pkg)s import %(base)s; sys.exit(%(full)s())"
+            '" "$@"\n'
+            'else\n'
+            '  echo $0 is not the correct name for this egg file.\n'
+            '  echo Please rename it back to %(basename)s and try again.\n'
+            '  exec false\n'
+            'fi\n'
+        ) % locals()
+
+        if not self.dry_run:
+            mkpath(os.path.dirname(self.egg_output), dry_run=self.dry_run)
+            f = open(self.egg_output, 'w')
+            f.write(header)
+            f.close()
+        return 'a'
+
+    def copy_metadata_to(self, target_dir):
+        "Copy metadata (egg info) to the target_dir"
+        # normalize the path (so that a forward-slash in egg_info will
+        # match using startswith below)
+        norm_egg_info = os.path.normpath(self.egg_info)
+        prefix = os.path.join(norm_egg_info, '')
+        for path in self.ei_cmd.filelist.files:
+            if path.startswith(prefix):
+                target = os.path.join(target_dir, path[len(prefix):])
+                ensure_directory(target)
+                self.copy_file(path, target)
+
+    def get_ext_outputs(self):
+        """Get a list of relative paths to C extensions in the output distro"""
+
+        all_outputs = []
+        ext_outputs = []
+
+        paths = {self.bdist_dir: ''}
+        for base, dirs, files in sorted_walk(self.bdist_dir):
+            for filename in files:
+                if os.path.splitext(filename)[1].lower() in NATIVE_EXTENSIONS:
+                    all_outputs.append(paths[base] + filename)
+            for filename in dirs:
+                paths[os.path.join(base, filename)] = (paths[base] +
+                                                       filename + '/')
+
+        if self.distribution.has_ext_modules():
+            build_cmd = self.get_finalized_command('build_ext')
+            for ext in build_cmd.extensions:
+                if isinstance(ext, Library):
+                    continue
+                fullname = build_cmd.get_ext_fullname(ext.name)
+                filename = build_cmd.get_ext_filename(fullname)
+                if not os.path.basename(filename).startswith('dl-'):
+                    if os.path.exists(os.path.join(self.bdist_dir, filename)):
+                        ext_outputs.append(filename)
+
+        return all_outputs, ext_outputs
+
+
+NATIVE_EXTENSIONS = dict.fromkeys('.dll .so .dylib .pyd'.split())
+
+
+def walk_egg(egg_dir):
+    """Walk an unpacked egg's contents, skipping the metadata directory"""
+    walker = sorted_walk(egg_dir)
+    base, dirs, files = next(walker)
+    if 'EGG-INFO' in dirs:
+        dirs.remove('EGG-INFO')
+    yield base, dirs, files
+    for bdf in walker:
+        yield bdf
+
+
+def analyze_egg(egg_dir, stubs):
+    # check for existing flag in EGG-INFO
+    for flag, fn in safety_flags.items():
+        if os.path.exists(os.path.join(egg_dir, 'EGG-INFO', fn)):
+            return flag
+    if not can_scan():
+        return False
+    safe = True
+    for base, dirs, files in walk_egg(egg_dir):
+        for name in files:
+            if name.endswith('.py') or name.endswith('.pyw'):
+                continue
+            elif name.endswith('.pyc') or name.endswith('.pyo'):
+                # always scan, even if we already know we're not safe
+                safe = scan_module(egg_dir, base, name, stubs) and safe
+    return safe
+
+
+def write_safety_flag(egg_dir, safe):
+    # Write or remove zip safety flag file(s)
+    for flag, fn in safety_flags.items():
+        fn = os.path.join(egg_dir, fn)
+        if os.path.exists(fn):
+            if safe is None or bool(safe) != flag:
+                os.unlink(fn)
+        elif safe is not None and bool(safe) == flag:
+            f = open(fn, 'wt')
+            f.write('\n')
+            f.close()
+
+
+safety_flags = {
+    True: 'zip-safe',
+    False: 'not-zip-safe',
+}
+
+
+def scan_module(egg_dir, base, name, stubs):
+    """Check whether module possibly uses unsafe-for-zipfile stuff"""
+
+    filename = os.path.join(base, name)
+    if filename[:-1] in stubs:
+        return True  # Extension module
+    pkg = base[len(egg_dir) + 1:].replace(os.sep, '.')
+    module = pkg + (pkg and '.' or '') + os.path.splitext(name)[0]
+    if sys.version_info < (3, 3):
+        skip = 8  # skip magic & date
+    elif sys.version_info < (3, 7):
+        skip = 12  # skip magic & date & file size
+    else:
+        skip = 16  # skip magic & reserved? & date & file size
+    f = open(filename, 'rb')
+    f.read(skip)
+    code = marshal.load(f)
+    f.close()
+    safe = True
+    symbols = dict.fromkeys(iter_symbols(code))
+    for bad in ['__file__', '__path__']:
+        if bad in symbols:
+            log.warn("%s: module references %s", module, bad)
+            safe = False
+    if 'inspect' in symbols:
+        for bad in [
+            'getsource', 'getabsfile', 'getsourcefile', 'getfile'
+            'getsourcelines', 'findsource', 'getcomments', 'getframeinfo',
+            'getinnerframes', 'getouterframes', 'stack', 'trace'
+        ]:
+            if bad in symbols:
+                log.warn("%s: module MAY be using inspect.%s", module, bad)
+                safe = False
+    return safe
+
+
+def iter_symbols(code):
+    """Yield names and strings used by `code` and its nested code objects"""
+    for name in code.co_names:
+        yield name
+    for const in code.co_consts:
+        if isinstance(const, six.string_types):
+            yield const
+        elif isinstance(const, CodeType):
+            for name in iter_symbols(const):
+                yield name
+
+
+def can_scan():
+    if not sys.platform.startswith('java') and sys.platform != 'cli':
+        # CPython, PyPy, etc.
+        return True
+    log.warn("Unable to analyze compiled code on this platform.")
+    log.warn("Please ask the author to include a 'zip_safe'"
+             " setting (either True or False) in the package's setup.py")
+
+
+# Attribute names of options for commands that might need to be convinced to
+# install to the egg build directory
+
+INSTALL_DIRECTORY_ATTRS = [
+    'install_lib', 'install_dir', 'install_data', 'install_base'
+]
+
+
+def make_zipfile(zip_filename, base_dir, verbose=0, dry_run=0, compress=True,
+                 mode='w'):
+    """Create a zip file from all the files under 'base_dir'.  The output
+    zip file will be named 'base_dir' + ".zip".  Uses either the "zipfile"
+    Python module (if available) or the InfoZIP "zip" utility (if installed
+    and found on the default search path).  If neither tool is available,
+    raises DistutilsExecError.  Returns the name of the output zip file.
+    """
+    import zipfile
+
+    mkpath(os.path.dirname(zip_filename), dry_run=dry_run)
+    log.info("creating '%s' and adding '%s' to it", zip_filename, base_dir)
+
+    def visit(z, dirname, names):
+        for name in names:
+            path = os.path.normpath(os.path.join(dirname, name))
+            if os.path.isfile(path):
+                p = path[len(base_dir) + 1:]
+                if not dry_run:
+                    z.write(path, p)
+                log.debug("adding '%s'", p)
+
+    compression = zipfile.ZIP_DEFLATED if compress else zipfile.ZIP_STORED
+    if not dry_run:
+        z = zipfile.ZipFile(zip_filename, mode, compression=compression)
+        for dirname, dirs, files in sorted_walk(base_dir):
+            visit(z, dirname, files)
+        z.close()
+    else:
+        for dirname, dirs, files in sorted_walk(base_dir):
+            visit(None, dirname, files)
+    return zip_filename
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/bdist_rpm.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/bdist_rpm.py
new file mode 100644
index 00000000..70730927
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/bdist_rpm.py
@@ -0,0 +1,43 @@
+import distutils.command.bdist_rpm as orig
+
+
+class bdist_rpm(orig.bdist_rpm):
+    """
+    Override the default bdist_rpm behavior to do the following:
+
+    1. Run egg_info to ensure the name and version are properly calculated.
+    2. Always run 'install' using --single-version-externally-managed to
+       disable eggs in RPM distributions.
+    3. Replace dash with underscore in the version numbers for better RPM
+       compatibility.
+    """
+
+    def run(self):
+        # ensure distro name is up-to-date
+        self.run_command('egg_info')
+
+        orig.bdist_rpm.run(self)
+
+    def _make_spec_file(self):
+        version = self.distribution.get_version()
+        rpmversion = version.replace('-', '_')
+        spec = orig.bdist_rpm._make_spec_file(self)
+        line23 = '%define version ' + version
+        line24 = '%define version ' + rpmversion
+        spec = [
+            line.replace(
+                "Source0: %{name}-%{version}.tar",
+                "Source0: %{name}-%{unmangled_version}.tar"
+            ).replace(
+                "setup.py install ",
+                "setup.py install --single-version-externally-managed "
+            ).replace(
+                "%setup",
+                "%setup -n %{name}-%{unmangled_version}"
+            ).replace(line23, line24)
+            for line in spec
+        ]
+        insert_loc = spec.index(line24) + 1
+        unmangled_version = "%define unmangled_version " + version
+        spec.insert(insert_loc, unmangled_version)
+        return spec
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/bdist_wininst.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/bdist_wininst.py
new file mode 100644
index 00000000..073de97b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/bdist_wininst.py
@@ -0,0 +1,21 @@
+import distutils.command.bdist_wininst as orig
+
+
+class bdist_wininst(orig.bdist_wininst):
+    def reinitialize_command(self, command, reinit_subcommands=0):
+        """
+        Supplement reinitialize_command to work around
+        http://bugs.python.org/issue20819
+        """
+        cmd = self.distribution.reinitialize_command(
+            command, reinit_subcommands)
+        if command in ('install', 'install_lib'):
+            cmd.install_lib = None
+        return cmd
+
+    def run(self):
+        self._is_running = True
+        try:
+            orig.bdist_wininst.run(self)
+        finally:
+            self._is_running = False
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/build_clib.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/build_clib.py
new file mode 100644
index 00000000..09caff6f
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/build_clib.py
@@ -0,0 +1,98 @@
+import distutils.command.build_clib as orig
+from distutils.errors import DistutilsSetupError
+from distutils import log
+from setuptools.dep_util import newer_pairwise_group
+
+
+class build_clib(orig.build_clib):
+    """
+    Override the default build_clib behaviour to do the following:
+
+    1. Implement a rudimentary timestamp-based dependency system
+       so 'compile()' doesn't run every time.
+    2. Add more keys to the 'build_info' dictionary:
+        * obj_deps - specify dependencies for each object compiled.
+                     this should be a dictionary mapping a key
+                     with the source filename to a list of
+                     dependencies. Use an empty string for global
+                     dependencies.
+        * cflags   - specify a list of additional flags to pass to
+                     the compiler.
+    """
+
+    def build_libraries(self, libraries):
+        for (lib_name, build_info) in libraries:
+            sources = build_info.get('sources')
+            if sources is None or not isinstance(sources, (list, tuple)):
+                raise DistutilsSetupError(
+                       "in 'libraries' option (library '%s'), "
+                       "'sources' must be present and must be "
+                       "a list of source filenames" % lib_name)
+            sources = list(sources)
+
+            log.info("building '%s' library", lib_name)
+
+            # Make sure everything is the correct type.
+            # obj_deps should be a dictionary of keys as sources
+            # and a list/tuple of files that are its dependencies.
+            obj_deps = build_info.get('obj_deps', dict())
+            if not isinstance(obj_deps, dict):
+                raise DistutilsSetupError(
+                       "in 'libraries' option (library '%s'), "
+                       "'obj_deps' must be a dictionary of "
+                       "type 'source: list'" % lib_name)
+            dependencies = []
+
+            # Get the global dependencies that are specified by the '' key.
+            # These will go into every source's dependency list.
+            global_deps = obj_deps.get('', list())
+            if not isinstance(global_deps, (list, tuple)):
+                raise DistutilsSetupError(
+                       "in 'libraries' option (library '%s'), "
+                       "'obj_deps' must be a dictionary of "
+                       "type 'source: list'" % lib_name)
+
+            # Build the list to be used by newer_pairwise_group
+            # each source will be auto-added to its dependencies.
+            for source in sources:
+                src_deps = [source]
+                src_deps.extend(global_deps)
+                extra_deps = obj_deps.get(source, list())
+                if not isinstance(extra_deps, (list, tuple)):
+                    raise DistutilsSetupError(
+                           "in 'libraries' option (library '%s'), "
+                           "'obj_deps' must be a dictionary of "
+                           "type 'source: list'" % lib_name)
+                src_deps.extend(extra_deps)
+                dependencies.append(src_deps)
+
+            expected_objects = self.compiler.object_filenames(
+                    sources,
+                    output_dir=self.build_temp
+                    )
+
+            if newer_pairwise_group(dependencies, expected_objects) != ([], []):
+                # First, compile the source code to object files in the library
+                # directory.  (This should probably change to putting object
+                # files in a temporary build directory.)
+                macros = build_info.get('macros')
+                include_dirs = build_info.get('include_dirs')
+                cflags = build_info.get('cflags')
+                objects = self.compiler.compile(
+                        sources,
+                        output_dir=self.build_temp,
+                        macros=macros,
+                        include_dirs=include_dirs,
+                        extra_postargs=cflags,
+                        debug=self.debug
+                        )
+
+            # Now "link" the object files together into a static library.
+            # (On Unix at least, this isn't really linking -- it just
+            # builds an archive.  Whatever.)
+            self.compiler.create_static_lib(
+                    expected_objects,
+                    lib_name,
+                    output_dir=self.build_clib,
+                    debug=self.debug
+                    )
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/build_ext.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/build_ext.py
new file mode 100644
index 00000000..ea97b37b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/build_ext.py
@@ -0,0 +1,331 @@
+import os
+import sys
+import itertools
+import imp
+from distutils.command.build_ext import build_ext as _du_build_ext
+from distutils.file_util import copy_file
+from distutils.ccompiler import new_compiler
+from distutils.sysconfig import customize_compiler, get_config_var
+from distutils.errors import DistutilsError
+from distutils import log
+
+from setuptools.extension import Library
+from setuptools.extern import six
+
+try:
+    # Attempt to use Cython for building extensions, if available
+    from Cython.Distutils.build_ext import build_ext as _build_ext
+    # Additionally, assert that the compiler module will load
+    # also. Ref #1229.
+    __import__('Cython.Compiler.Main')
+except ImportError:
+    _build_ext = _du_build_ext
+
+# make sure _config_vars is initialized
+get_config_var("LDSHARED")
+from distutils.sysconfig import _config_vars as _CONFIG_VARS
+
+
+def _customize_compiler_for_shlib(compiler):
+    if sys.platform == "darwin":
+        # building .dylib requires additional compiler flags on OSX; here we
+        # temporarily substitute the pyconfig.h variables so that distutils'
+        # 'customize_compiler' uses them before we build the shared libraries.
+        tmp = _CONFIG_VARS.copy()
+        try:
+            # XXX Help!  I don't have any idea whether these are right...
+            _CONFIG_VARS['LDSHARED'] = (
+                "gcc -Wl,-x -dynamiclib -undefined dynamic_lookup")
+            _CONFIG_VARS['CCSHARED'] = " -dynamiclib"
+            _CONFIG_VARS['SO'] = ".dylib"
+            customize_compiler(compiler)
+        finally:
+            _CONFIG_VARS.clear()
+            _CONFIG_VARS.update(tmp)
+    else:
+        customize_compiler(compiler)
+
+
+have_rtld = False
+use_stubs = False
+libtype = 'shared'
+
+if sys.platform == "darwin":
+    use_stubs = True
+elif os.name != 'nt':
+    try:
+        import dl
+        use_stubs = have_rtld = hasattr(dl, 'RTLD_NOW')
+    except ImportError:
+        pass
+
+if_dl = lambda s: s if have_rtld else ''
+
+
+def get_abi3_suffix():
+    """Return the file extension for an abi3-compliant Extension()"""
+    for suffix, _, _ in (s for s in imp.get_suffixes() if s[2] == imp.C_EXTENSION):
+        if '.abi3' in suffix:  # Unix
+            return suffix
+        elif suffix == '.pyd':  # Windows
+            return suffix
+
+
+class build_ext(_build_ext):
+    def run(self):
+        """Build extensions in build directory, then copy if --inplace"""
+        old_inplace, self.inplace = self.inplace, 0
+        _build_ext.run(self)
+        self.inplace = old_inplace
+        if old_inplace:
+            self.copy_extensions_to_source()
+
+    def copy_extensions_to_source(self):
+        build_py = self.get_finalized_command('build_py')
+        for ext in self.extensions:
+            fullname = self.get_ext_fullname(ext.name)
+            filename = self.get_ext_filename(fullname)
+            modpath = fullname.split('.')
+            package = '.'.join(modpath[:-1])
+            package_dir = build_py.get_package_dir(package)
+            dest_filename = os.path.join(package_dir,
+                                         os.path.basename(filename))
+            src_filename = os.path.join(self.build_lib, filename)
+
+            # Always copy, even if source is older than destination, to ensure
+            # that the right extensions for the current Python/platform are
+            # used.
+            copy_file(
+                src_filename, dest_filename, verbose=self.verbose,
+                dry_run=self.dry_run
+            )
+            if ext._needs_stub:
+                self.write_stub(package_dir or os.curdir, ext, True)
+
+    def get_ext_filename(self, fullname):
+        filename = _build_ext.get_ext_filename(self, fullname)
+        if fullname in self.ext_map:
+            ext = self.ext_map[fullname]
+            use_abi3 = (
+                six.PY3
+                and getattr(ext, 'py_limited_api')
+                and get_abi3_suffix()
+            )
+            if use_abi3:
+                so_ext = _get_config_var_837('EXT_SUFFIX')
+                filename = filename[:-len(so_ext)]
+                filename = filename + get_abi3_suffix()
+            if isinstance(ext, Library):
+                fn, ext = os.path.splitext(filename)
+                return self.shlib_compiler.library_filename(fn, libtype)
+            elif use_stubs and ext._links_to_dynamic:
+                d, fn = os.path.split(filename)
+                return os.path.join(d, 'dl-' + fn)
+        return filename
+
+    def initialize_options(self):
+        _build_ext.initialize_options(self)
+        self.shlib_compiler = None
+        self.shlibs = []
+        self.ext_map = {}
+
+    def finalize_options(self):
+        _build_ext.finalize_options(self)
+        self.extensions = self.extensions or []
+        self.check_extensions_list(self.extensions)
+        self.shlibs = [ext for ext in self.extensions
+                       if isinstance(ext, Library)]
+        if self.shlibs:
+            self.setup_shlib_compiler()
+        for ext in self.extensions:
+            ext._full_name = self.get_ext_fullname(ext.name)
+        for ext in self.extensions:
+            fullname = ext._full_name
+            self.ext_map[fullname] = ext
+
+            # distutils 3.1 will also ask for module names
+            # XXX what to do with conflicts?
+            self.ext_map[fullname.split('.')[-1]] = ext
+
+            ltd = self.shlibs and self.links_to_dynamic(ext) or False
+            ns = ltd and use_stubs and not isinstance(ext, Library)
+            ext._links_to_dynamic = ltd
+            ext._needs_stub = ns
+            filename = ext._file_name = self.get_ext_filename(fullname)
+            libdir = os.path.dirname(os.path.join(self.build_lib, filename))
+            if ltd and libdir not in ext.library_dirs:
+                ext.library_dirs.append(libdir)
+            if ltd and use_stubs and os.curdir not in ext.runtime_library_dirs:
+                ext.runtime_library_dirs.append(os.curdir)
+
+    def setup_shlib_compiler(self):
+        compiler = self.shlib_compiler = new_compiler(
+            compiler=self.compiler, dry_run=self.dry_run, force=self.force
+        )
+        _customize_compiler_for_shlib(compiler)
+
+        if self.include_dirs is not None:
+            compiler.set_include_dirs(self.include_dirs)
+        if self.define is not None:
+            # 'define' option is a list of (name,value) tuples
+            for (name, value) in self.define:
+                compiler.define_macro(name, value)
+        if self.undef is not None:
+            for macro in self.undef:
+                compiler.undefine_macro(macro)
+        if self.libraries is not None:
+            compiler.set_libraries(self.libraries)
+        if self.library_dirs is not None:
+            compiler.set_library_dirs(self.library_dirs)
+        if self.rpath is not None:
+            compiler.set_runtime_library_dirs(self.rpath)
+        if self.link_objects is not None:
+            compiler.set_link_objects(self.link_objects)
+
+        # hack so distutils' build_extension() builds a library instead
+        compiler.link_shared_object = link_shared_object.__get__(compiler)
+
+    def get_export_symbols(self, ext):
+        if isinstance(ext, Library):
+            return ext.export_symbols
+        return _build_ext.get_export_symbols(self, ext)
+
+    def build_extension(self, ext):
+        ext._convert_pyx_sources_to_lang()
+        _compiler = self.compiler
+        try:
+            if isinstance(ext, Library):
+                self.compiler = self.shlib_compiler
+            _build_ext.build_extension(self, ext)
+            if ext._needs_stub:
+                cmd = self.get_finalized_command('build_py').build_lib
+                self.write_stub(cmd, ext)
+        finally:
+            self.compiler = _compiler
+
+    def links_to_dynamic(self, ext):
+        """Return true if 'ext' links to a dynamic lib in the same package"""
+        # XXX this should check to ensure the lib is actually being built
+        # XXX as dynamic, and not just using a locally-found version or a
+        # XXX static-compiled version
+        libnames = dict.fromkeys([lib._full_name for lib in self.shlibs])
+        pkg = '.'.join(ext._full_name.split('.')[:-1] + [''])
+        return any(pkg + libname in libnames for libname in ext.libraries)
+
+    def get_outputs(self):
+        return _build_ext.get_outputs(self) + self.__get_stubs_outputs()
+
+    def __get_stubs_outputs(self):
+        # assemble the base name for each extension that needs a stub
+        ns_ext_bases = (
+            os.path.join(self.build_lib, *ext._full_name.split('.'))
+            for ext in self.extensions
+            if ext._needs_stub
+        )
+        # pair each base with the extension
+        pairs = itertools.product(ns_ext_bases, self.__get_output_extensions())
+        return list(base + fnext for base, fnext in pairs)
+
+    def __get_output_extensions(self):
+        yield '.py'
+        yield '.pyc'
+        if self.get_finalized_command('build_py').optimize:
+            yield '.pyo'
+
+    def write_stub(self, output_dir, ext, compile=False):
+        log.info("writing stub loader for %s to %s", ext._full_name,
+                 output_dir)
+        stub_file = (os.path.join(output_dir, *ext._full_name.split('.')) +
+                     '.py')
+        if compile and os.path.exists(stub_file):
+            raise DistutilsError(stub_file + " already exists! Please delete.")
+        if not self.dry_run:
+            f = open(stub_file, 'w')
+            f.write(
+                '\n'.join([
+                    "def __bootstrap__():",
+                    "   global __bootstrap__, __file__, __loader__",
+                    "   import sys, os, pkg_resources, imp" + if_dl(", dl"),
+                    "   __file__ = pkg_resources.resource_filename"
+                    "(__name__,%r)"
+                    % os.path.basename(ext._file_name),
+                    "   del __bootstrap__",
+                    "   if '__loader__' in globals():",
+                    "       del __loader__",
+                    if_dl("   old_flags = sys.getdlopenflags()"),
+                    "   old_dir = os.getcwd()",
+                    "   try:",
+                    "     os.chdir(os.path.dirname(__file__))",
+                    if_dl("     sys.setdlopenflags(dl.RTLD_NOW)"),
+                    "     imp.load_dynamic(__name__,__file__)",
+                    "   finally:",
+                    if_dl("     sys.setdlopenflags(old_flags)"),
+                    "     os.chdir(old_dir)",
+                    "__bootstrap__()",
+                    ""  # terminal \n
+                ])
+            )
+            f.close()
+        if compile:
+            from distutils.util import byte_compile
+
+            byte_compile([stub_file], optimize=0,
+                         force=True, dry_run=self.dry_run)
+            optimize = self.get_finalized_command('install_lib').optimize
+            if optimize > 0:
+                byte_compile([stub_file], optimize=optimize,
+                             force=True, dry_run=self.dry_run)
+            if os.path.exists(stub_file) and not self.dry_run:
+                os.unlink(stub_file)
+
+
+if use_stubs or os.name == 'nt':
+    # Build shared libraries
+    #
+    def link_shared_object(
+            self, objects, output_libname, output_dir=None, libraries=None,
+            library_dirs=None, runtime_library_dirs=None, export_symbols=None,
+            debug=0, extra_preargs=None, extra_postargs=None, build_temp=None,
+            target_lang=None):
+        self.link(
+            self.SHARED_LIBRARY, objects, output_libname,
+            output_dir, libraries, library_dirs, runtime_library_dirs,
+            export_symbols, debug, extra_preargs, extra_postargs,
+            build_temp, target_lang
+        )
+else:
+    # Build static libraries everywhere else
+    libtype = 'static'
+
+    def link_shared_object(
+            self, objects, output_libname, output_dir=None, libraries=None,
+            library_dirs=None, runtime_library_dirs=None, export_symbols=None,
+            debug=0, extra_preargs=None, extra_postargs=None, build_temp=None,
+            target_lang=None):
+        # XXX we need to either disallow these attrs on Library instances,
+        # or warn/abort here if set, or something...
+        # libraries=None, library_dirs=None, runtime_library_dirs=None,
+        # export_symbols=None, extra_preargs=None, extra_postargs=None,
+        # build_temp=None
+
+        assert output_dir is None  # distutils build_ext doesn't pass this
+        output_dir, filename = os.path.split(output_libname)
+        basename, ext = os.path.splitext(filename)
+        if self.library_filename("x").startswith('lib'):
+            # strip 'lib' prefix; this is kludgy if some platform uses
+            # a different prefix
+            basename = basename[3:]
+
+        self.create_static_lib(
+            objects, basename, output_dir, debug, target_lang
+        )
+
+
+def _get_config_var_837(name):
+    """
+    In https://github.com/pypa/setuptools/pull/837, we discovered
+    Python 3.3.0 exposes the extension suffix under the name 'SO'.
+    """
+    if sys.version_info < (3, 3, 1):
+        name = 'SO'
+    return get_config_var(name)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/build_py.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/build_py.py
new file mode 100644
index 00000000..b0314fd4
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/build_py.py
@@ -0,0 +1,270 @@
+from glob import glob
+from distutils.util import convert_path
+import distutils.command.build_py as orig
+import os
+import fnmatch
+import textwrap
+import io
+import distutils.errors
+import itertools
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import map, filter, filterfalse
+
+try:
+    from setuptools.lib2to3_ex import Mixin2to3
+except ImportError:
+
+    class Mixin2to3:
+        def run_2to3(self, files, doctests=True):
+            "do nothing"
+
+
+class build_py(orig.build_py, Mixin2to3):
+    """Enhanced 'build_py' command that includes data files with packages
+
+    The data files are specified via a 'package_data' argument to 'setup()'.
+    See 'setuptools.dist.Distribution' for more details.
+
+    Also, this version of the 'build_py' command allows you to specify both
+    'py_modules' and 'packages' in the same setup operation.
+    """
+
+    def finalize_options(self):
+        orig.build_py.finalize_options(self)
+        self.package_data = self.distribution.package_data
+        self.exclude_package_data = (self.distribution.exclude_package_data or
+                                     {})
+        if 'data_files' in self.__dict__:
+            del self.__dict__['data_files']
+        self.__updated_files = []
+        self.__doctests_2to3 = []
+
+    def run(self):
+        """Build modules, packages, and copy data files to build directory"""
+        if not self.py_modules and not self.packages:
+            return
+
+        if self.py_modules:
+            self.build_modules()
+
+        if self.packages:
+            self.build_packages()
+            self.build_package_data()
+
+        self.run_2to3(self.__updated_files, False)
+        self.run_2to3(self.__updated_files, True)
+        self.run_2to3(self.__doctests_2to3, True)
+
+        # Only compile actual .py files, using our base class' idea of what our
+        # output files are.
+        self.byte_compile(orig.build_py.get_outputs(self, include_bytecode=0))
+
+    def __getattr__(self, attr):
+        "lazily compute data files"
+        if attr == 'data_files':
+            self.data_files = self._get_data_files()
+            return self.data_files
+        return orig.build_py.__getattr__(self, attr)
+
+    def build_module(self, module, module_file, package):
+        if six.PY2 and isinstance(package, six.string_types):
+            # avoid errors on Python 2 when unicode is passed (#190)
+            package = package.split('.')
+        outfile, copied = orig.build_py.build_module(self, module, module_file,
+                                                     package)
+        if copied:
+            self.__updated_files.append(outfile)
+        return outfile, copied
+
+    def _get_data_files(self):
+        """Generate list of '(package,src_dir,build_dir,filenames)' tuples"""
+        self.analyze_manifest()
+        return list(map(self._get_pkg_data_files, self.packages or ()))
+
+    def _get_pkg_data_files(self, package):
+        # Locate package source directory
+        src_dir = self.get_package_dir(package)
+
+        # Compute package build directory
+        build_dir = os.path.join(*([self.build_lib] + package.split('.')))
+
+        # Strip directory from globbed filenames
+        filenames = [
+            os.path.relpath(file, src_dir)
+            for file in self.find_data_files(package, src_dir)
+        ]
+        return package, src_dir, build_dir, filenames
+
+    def find_data_files(self, package, src_dir):
+        """Return filenames for package's data files in 'src_dir'"""
+        patterns = self._get_platform_patterns(
+            self.package_data,
+            package,
+            src_dir,
+        )
+        globs_expanded = map(glob, patterns)
+        # flatten the expanded globs into an iterable of matches
+        globs_matches = itertools.chain.from_iterable(globs_expanded)
+        glob_files = filter(os.path.isfile, globs_matches)
+        files = itertools.chain(
+            self.manifest_files.get(package, []),
+            glob_files,
+        )
+        return self.exclude_data_files(package, src_dir, files)
+
+    def build_package_data(self):
+        """Copy data files into build directory"""
+        for package, src_dir, build_dir, filenames in self.data_files:
+            for filename in filenames:
+                target = os.path.join(build_dir, filename)
+                self.mkpath(os.path.dirname(target))
+                srcfile = os.path.join(src_dir, filename)
+                outf, copied = self.copy_file(srcfile, target)
+                srcfile = os.path.abspath(srcfile)
+                if (copied and
+                        srcfile in self.distribution.convert_2to3_doctests):
+                    self.__doctests_2to3.append(outf)
+
+    def analyze_manifest(self):
+        self.manifest_files = mf = {}
+        if not self.distribution.include_package_data:
+            return
+        src_dirs = {}
+        for package in self.packages or ():
+            # Locate package source directory
+            src_dirs[assert_relative(self.get_package_dir(package))] = package
+
+        self.run_command('egg_info')
+        ei_cmd = self.get_finalized_command('egg_info')
+        for path in ei_cmd.filelist.files:
+            d, f = os.path.split(assert_relative(path))
+            prev = None
+            oldf = f
+            while d and d != prev and d not in src_dirs:
+                prev = d
+                d, df = os.path.split(d)
+                f = os.path.join(df, f)
+            if d in src_dirs:
+                if path.endswith('.py') and f == oldf:
+                    continue  # it's a module, not data
+                mf.setdefault(src_dirs[d], []).append(path)
+
+    def get_data_files(self):
+        pass  # Lazily compute data files in _get_data_files() function.
+
+    def check_package(self, package, package_dir):
+        """Check namespace packages' __init__ for declare_namespace"""
+        try:
+            return self.packages_checked[package]
+        except KeyError:
+            pass
+
+        init_py = orig.build_py.check_package(self, package, package_dir)
+        self.packages_checked[package] = init_py
+
+        if not init_py or not self.distribution.namespace_packages:
+            return init_py
+
+        for pkg in self.distribution.namespace_packages:
+            if pkg == package or pkg.startswith(package + '.'):
+                break
+        else:
+            return init_py
+
+        with io.open(init_py, 'rb') as f:
+            contents = f.read()
+        if b'declare_namespace' not in contents:
+            raise distutils.errors.DistutilsError(
+                "Namespace package problem: %s is a namespace package, but "
+                "its\n__init__.py does not call declare_namespace()! Please "
+                'fix it.\n(See the setuptools manual under '
+                '"Namespace Packages" for details.)\n"' % (package,)
+            )
+        return init_py
+
+    def initialize_options(self):
+        self.packages_checked = {}
+        orig.build_py.initialize_options(self)
+
+    def get_package_dir(self, package):
+        res = orig.build_py.get_package_dir(self, package)
+        if self.distribution.src_root is not None:
+            return os.path.join(self.distribution.src_root, res)
+        return res
+
+    def exclude_data_files(self, package, src_dir, files):
+        """Filter filenames for package's data files in 'src_dir'"""
+        files = list(files)
+        patterns = self._get_platform_patterns(
+            self.exclude_package_data,
+            package,
+            src_dir,
+        )
+        match_groups = (
+            fnmatch.filter(files, pattern)
+            for pattern in patterns
+        )
+        # flatten the groups of matches into an iterable of matches
+        matches = itertools.chain.from_iterable(match_groups)
+        bad = set(matches)
+        keepers = (
+            fn
+            for fn in files
+            if fn not in bad
+        )
+        # ditch dupes
+        return list(_unique_everseen(keepers))
+
+    @staticmethod
+    def _get_platform_patterns(spec, package, src_dir):
+        """
+        yield platform-specific path patterns (suitable for glob
+        or fn_match) from a glob-based spec (such as
+        self.package_data or self.exclude_package_data)
+        matching package in src_dir.
+        """
+        raw_patterns = itertools.chain(
+            spec.get('', []),
+            spec.get(package, []),
+        )
+        return (
+            # Each pattern has to be converted to a platform-specific path
+            os.path.join(src_dir, convert_path(pattern))
+            for pattern in raw_patterns
+        )
+
+
+# from Python docs
+def _unique_everseen(iterable, key=None):
+    "List unique elements, preserving order. Remember all elements ever seen."
+    # unique_everseen('AAAABBBCCDAABBB') --> A B C D
+    # unique_everseen('ABBCcAD', str.lower) --> A B C D
+    seen = set()
+    seen_add = seen.add
+    if key is None:
+        for element in filterfalse(seen.__contains__, iterable):
+            seen_add(element)
+            yield element
+    else:
+        for element in iterable:
+            k = key(element)
+            if k not in seen:
+                seen_add(k)
+                yield element
+
+
+def assert_relative(path):
+    if not os.path.isabs(path):
+        return path
+    from distutils.errors import DistutilsSetupError
+
+    msg = textwrap.dedent("""
+        Error: setup script specifies an absolute path:
+
+            %s
+
+        setup() arguments must *always* be /-separated paths relative to the
+        setup.py directory, *never* absolute paths.
+        """).lstrip() % path
+    raise DistutilsSetupError(msg)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/develop.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/develop.py
new file mode 100644
index 00000000..959c932a
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/develop.py
@@ -0,0 +1,216 @@
+from distutils.util import convert_path
+from distutils import log
+from distutils.errors import DistutilsError, DistutilsOptionError
+import os
+import glob
+import io
+
+from setuptools.extern import six
+
+from pkg_resources import Distribution, PathMetadata, normalize_path
+from setuptools.command.easy_install import easy_install
+from setuptools import namespaces
+import setuptools
+
+
+class develop(namespaces.DevelopInstaller, easy_install):
+    """Set up package for development"""
+
+    description = "install package in 'development mode'"
+
+    user_options = easy_install.user_options + [
+        ("uninstall", "u", "Uninstall this source package"),
+        ("egg-path=", None, "Set the path to be used in the .egg-link file"),
+    ]
+
+    boolean_options = easy_install.boolean_options + ['uninstall']
+
+    command_consumes_arguments = False  # override base
+
+    def run(self):
+        if self.uninstall:
+            self.multi_version = True
+            self.uninstall_link()
+            self.uninstall_namespaces()
+        else:
+            self.install_for_development()
+        self.warn_deprecated_options()
+
+    def initialize_options(self):
+        self.uninstall = None
+        self.egg_path = None
+        easy_install.initialize_options(self)
+        self.setup_path = None
+        self.always_copy_from = '.'  # always copy eggs installed in curdir
+
+    def finalize_options(self):
+        ei = self.get_finalized_command("egg_info")
+        if ei.broken_egg_info:
+            template = "Please rename %r to %r before using 'develop'"
+            args = ei.egg_info, ei.broken_egg_info
+            raise DistutilsError(template % args)
+        self.args = [ei.egg_name]
+
+        easy_install.finalize_options(self)
+        self.expand_basedirs()
+        self.expand_dirs()
+        # pick up setup-dir .egg files only: no .egg-info
+        self.package_index.scan(glob.glob('*.egg'))
+
+        egg_link_fn = ei.egg_name + '.egg-link'
+        self.egg_link = os.path.join(self.install_dir, egg_link_fn)
+        self.egg_base = ei.egg_base
+        if self.egg_path is None:
+            self.egg_path = os.path.abspath(ei.egg_base)
+
+        target = normalize_path(self.egg_base)
+        egg_path = normalize_path(os.path.join(self.install_dir,
+                                               self.egg_path))
+        if egg_path != target:
+            raise DistutilsOptionError(
+                "--egg-path must be a relative path from the install"
+                " directory to " + target
+            )
+
+        # Make a distribution for the package's source
+        self.dist = Distribution(
+            target,
+            PathMetadata(target, os.path.abspath(ei.egg_info)),
+            project_name=ei.egg_name
+        )
+
+        self.setup_path = self._resolve_setup_path(
+            self.egg_base,
+            self.install_dir,
+            self.egg_path,
+        )
+
+    @staticmethod
+    def _resolve_setup_path(egg_base, install_dir, egg_path):
+        """
+        Generate a path from egg_base back to '.' where the
+        setup script resides and ensure that path points to the
+        setup path from $install_dir/$egg_path.
+        """
+        path_to_setup = egg_base.replace(os.sep, '/').rstrip('/')
+        if path_to_setup != os.curdir:
+            path_to_setup = '../' * (path_to_setup.count('/') + 1)
+        resolved = normalize_path(
+            os.path.join(install_dir, egg_path, path_to_setup)
+        )
+        if resolved != normalize_path(os.curdir):
+            raise DistutilsOptionError(
+                "Can't get a consistent path to setup script from"
+                " installation directory", resolved, normalize_path(os.curdir))
+        return path_to_setup
+
+    def install_for_development(self):
+        if six.PY3 and getattr(self.distribution, 'use_2to3', False):
+            # If we run 2to3 we can not do this inplace:
+
+            # Ensure metadata is up-to-date
+            self.reinitialize_command('build_py', inplace=0)
+            self.run_command('build_py')
+            bpy_cmd = self.get_finalized_command("build_py")
+            build_path = normalize_path(bpy_cmd.build_lib)
+
+            # Build extensions
+            self.reinitialize_command('egg_info', egg_base=build_path)
+            self.run_command('egg_info')
+
+            self.reinitialize_command('build_ext', inplace=0)
+            self.run_command('build_ext')
+
+            # Fixup egg-link and easy-install.pth
+            ei_cmd = self.get_finalized_command("egg_info")
+            self.egg_path = build_path
+            self.dist.location = build_path
+            # XXX
+            self.dist._provider = PathMetadata(build_path, ei_cmd.egg_info)
+        else:
+            # Without 2to3 inplace works fine:
+            self.run_command('egg_info')
+
+            # Build extensions in-place
+            self.reinitialize_command('build_ext', inplace=1)
+            self.run_command('build_ext')
+
+        self.install_site_py()  # ensure that target dir is site-safe
+        if setuptools.bootstrap_install_from:
+            self.easy_install(setuptools.bootstrap_install_from)
+            setuptools.bootstrap_install_from = None
+
+        self.install_namespaces()
+
+        # create an .egg-link in the installation dir, pointing to our egg
+        log.info("Creating %s (link to %s)", self.egg_link, self.egg_base)
+        if not self.dry_run:
+            with open(self.egg_link, "w") as f:
+                f.write(self.egg_path + "\n" + self.setup_path)
+        # postprocess the installed distro, fixing up .pth, installing scripts,
+        # and handling requirements
+        self.process_distribution(None, self.dist, not self.no_deps)
+
+    def uninstall_link(self):
+        if os.path.exists(self.egg_link):
+            log.info("Removing %s (link to %s)", self.egg_link, self.egg_base)
+            egg_link_file = open(self.egg_link)
+            contents = [line.rstrip() for line in egg_link_file]
+            egg_link_file.close()
+            if contents not in ([self.egg_path],
+                                [self.egg_path, self.setup_path]):
+                log.warn("Link points to %s: uninstall aborted", contents)
+                return
+            if not self.dry_run:
+                os.unlink(self.egg_link)
+        if not self.dry_run:
+            self.update_pth(self.dist)  # remove any .pth link to us
+        if self.distribution.scripts:
+            # XXX should also check for entry point scripts!
+            log.warn("Note: you must uninstall or replace scripts manually!")
+
+    def install_egg_scripts(self, dist):
+        if dist is not self.dist:
+            # Installing a dependency, so fall back to normal behavior
+            return easy_install.install_egg_scripts(self, dist)
+
+        # create wrapper scripts in the script dir, pointing to dist.scripts
+
+        # new-style...
+        self.install_wrapper_scripts(dist)
+
+        # ...and old-style
+        for script_name in self.distribution.scripts or []:
+            script_path = os.path.abspath(convert_path(script_name))
+            script_name = os.path.basename(script_path)
+            with io.open(script_path) as strm:
+                script_text = strm.read()
+            self.install_script(dist, script_name, script_text, script_path)
+
+    def install_wrapper_scripts(self, dist):
+        dist = VersionlessRequirement(dist)
+        return easy_install.install_wrapper_scripts(self, dist)
+
+
+class VersionlessRequirement(object):
+    """
+    Adapt a pkg_resources.Distribution to simply return the project
+    name as the 'requirement' so that scripts will work across
+    multiple versions.
+
+    >>> dist = Distribution(project_name='foo', version='1.0')
+    >>> str(dist.as_requirement())
+    'foo==1.0'
+    >>> adapted_dist = VersionlessRequirement(dist)
+    >>> str(adapted_dist.as_requirement())
+    'foo'
+    """
+
+    def __init__(self, dist):
+        self.__dist = dist
+
+    def __getattr__(self, name):
+        return getattr(self.__dist, name)
+
+    def as_requirement(self):
+        return self.project_name
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/dist_info.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/dist_info.py
new file mode 100644
index 00000000..c45258fa
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/dist_info.py
@@ -0,0 +1,36 @@
+"""
+Create a dist_info directory
+As defined in the wheel specification
+"""
+
+import os
+
+from distutils.core import Command
+from distutils import log
+
+
+class dist_info(Command):
+
+    description = 'create a .dist-info directory'
+
+    user_options = [
+        ('egg-base=', 'e', "directory containing .egg-info directories"
+                           " (default: top of the source tree)"),
+    ]
+
+    def initialize_options(self):
+        self.egg_base = None
+
+    def finalize_options(self):
+        pass
+
+    def run(self):
+        egg_info = self.get_finalized_command('egg_info')
+        egg_info.egg_base = self.egg_base
+        egg_info.finalize_options()
+        egg_info.run()
+        dist_info_dir = egg_info.egg_info[:-len('.egg-info')] + '.dist-info'
+        log.info("creating '{}'".format(os.path.abspath(dist_info_dir)))
+
+        bdist_wheel = self.get_finalized_command('bdist_wheel')
+        bdist_wheel.egg2dist(egg_info.egg_info, dist_info_dir)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/easy_install.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/easy_install.py
new file mode 100644
index 00000000..a6f61436
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/easy_install.py
@@ -0,0 +1,2334 @@
+#!/usr/bin/env python
+"""
+Easy Install
+------------
+
+A tool for doing automatic download/extract/build of distutils-based Python
+packages.  For detailed documentation, see the accompanying EasyInstall.txt
+file, or visit the `EasyInstall home page`__.
+
+__ https://setuptools.readthedocs.io/en/latest/easy_install.html
+
+"""
+
+from glob import glob
+from distutils.util import get_platform
+from distutils.util import convert_path, subst_vars
+from distutils.errors import (
+    DistutilsArgError, DistutilsOptionError,
+    DistutilsError, DistutilsPlatformError,
+)
+from distutils.command.install import INSTALL_SCHEMES, SCHEME_KEYS
+from distutils import log, dir_util
+from distutils.command.build_scripts import first_line_re
+from distutils.spawn import find_executable
+import sys
+import os
+import zipimport
+import shutil
+import tempfile
+import zipfile
+import re
+import stat
+import random
+import textwrap
+import warnings
+import site
+import struct
+import contextlib
+import subprocess
+import shlex
+import io
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import configparser, map
+
+from setuptools import Command
+from setuptools.sandbox import run_setup
+from setuptools.py31compat import get_path, get_config_vars
+from setuptools.py27compat import rmtree_safe
+from setuptools.command import setopt
+from setuptools.archive_util import unpack_archive
+from setuptools.package_index import (
+    PackageIndex, parse_requirement_arg, URL_SCHEME,
+)
+from setuptools.command import bdist_egg, egg_info
+from setuptools.wheel import Wheel
+from pkg_resources import (
+    yield_lines, normalize_path, resource_string, ensure_directory,
+    get_distribution, find_distributions, Environment, Requirement,
+    Distribution, PathMetadata, EggMetadata, WorkingSet, DistributionNotFound,
+    VersionConflict, DEVELOP_DIST,
+)
+import pkg_resources.py31compat
+
+# Turn on PEP440Warnings
+warnings.filterwarnings("default", category=pkg_resources.PEP440Warning)
+
+__all__ = [
+    'samefile', 'easy_install', 'PthDistributions', 'extract_wininst_cfg',
+    'main', 'get_exe_prefixes',
+]
+
+
+def is_64bit():
+    return struct.calcsize("P") == 8
+
+
+def samefile(p1, p2):
+    """
+    Determine if two paths reference the same file.
+
+    Augments os.path.samefile to work on Windows and
+    suppresses errors if the path doesn't exist.
+    """
+    both_exist = os.path.exists(p1) and os.path.exists(p2)
+    use_samefile = hasattr(os.path, 'samefile') and both_exist
+    if use_samefile:
+        return os.path.samefile(p1, p2)
+    norm_p1 = os.path.normpath(os.path.normcase(p1))
+    norm_p2 = os.path.normpath(os.path.normcase(p2))
+    return norm_p1 == norm_p2
+
+
+if six.PY2:
+
+    def _to_ascii(s):
+        return s
+
+    def isascii(s):
+        try:
+            six.text_type(s, 'ascii')
+            return True
+        except UnicodeError:
+            return False
+else:
+
+    def _to_ascii(s):
+        return s.encode('ascii')
+
+    def isascii(s):
+        try:
+            s.encode('ascii')
+            return True
+        except UnicodeError:
+            return False
+
+
+_one_liner = lambda text: textwrap.dedent(text).strip().replace('\n', '; ')
+
+
+class easy_install(Command):
+    """Manage a download/build/install process"""
+    description = "Find/get/install Python packages"
+    command_consumes_arguments = True
+
+    user_options = [
+        ('prefix=', None, "installation prefix"),
+        ("zip-ok", "z", "install package as a zipfile"),
+        ("multi-version", "m", "make apps have to require() a version"),
+        ("upgrade", "U", "force upgrade (searches PyPI for latest versions)"),
+        ("install-dir=", "d", "install package to DIR"),
+        ("script-dir=", "s", "install scripts to DIR"),
+        ("exclude-scripts", "x", "Don't install scripts"),
+        ("always-copy", "a", "Copy all needed packages to install dir"),
+        ("index-url=", "i", "base URL of Python Package Index"),
+        ("find-links=", "f", "additional URL(s) to search for packages"),
+        ("build-directory=", "b",
+         "download/extract/build in DIR; keep the results"),
+        ('optimize=', 'O',
+         "also compile with optimization: -O1 for \"python -O\", "
+         "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
+        ('record=', None,
+         "filename in which to record list of installed files"),
+        ('always-unzip', 'Z', "don't install as a zipfile, no matter what"),
+        ('site-dirs=', 'S', "list of directories where .pth files work"),
+        ('editable', 'e', "Install specified packages in editable form"),
+        ('no-deps', 'N', "don't install dependencies"),
+        ('allow-hosts=', 'H', "pattern(s) that hostnames must match"),
+        ('local-snapshots-ok', 'l',
+         "allow building eggs from local checkouts"),
+        ('version', None, "print version information and exit"),
+        ('no-find-links', None,
+         "Don't load find-links defined in packages being installed")
+    ]
+    boolean_options = [
+        'zip-ok', 'multi-version', 'exclude-scripts', 'upgrade', 'always-copy',
+        'editable',
+        'no-deps', 'local-snapshots-ok', 'version'
+    ]
+
+    if site.ENABLE_USER_SITE:
+        help_msg = "install in user site-package '%s'" % site.USER_SITE
+        user_options.append(('user', None, help_msg))
+        boolean_options.append('user')
+
+    negative_opt = {'always-unzip': 'zip-ok'}
+    create_index = PackageIndex
+
+    def initialize_options(self):
+        # the --user option seems to be an opt-in one,
+        # so the default should be False.
+        self.user = 0
+        self.zip_ok = self.local_snapshots_ok = None
+        self.install_dir = self.script_dir = self.exclude_scripts = None
+        self.index_url = None
+        self.find_links = None
+        self.build_directory = None
+        self.args = None
+        self.optimize = self.record = None
+        self.upgrade = self.always_copy = self.multi_version = None
+        self.editable = self.no_deps = self.allow_hosts = None
+        self.root = self.prefix = self.no_report = None
+        self.version = None
+        self.install_purelib = None  # for pure module distributions
+        self.install_platlib = None  # non-pure (dists w/ extensions)
+        self.install_headers = None  # for C/C++ headers
+        self.install_lib = None  # set to either purelib or platlib
+        self.install_scripts = None
+        self.install_data = None
+        self.install_base = None
+        self.install_platbase = None
+        if site.ENABLE_USER_SITE:
+            self.install_userbase = site.USER_BASE
+            self.install_usersite = site.USER_SITE
+        else:
+            self.install_userbase = None
+            self.install_usersite = None
+        self.no_find_links = None
+
+        # Options not specifiable via command line
+        self.package_index = None
+        self.pth_file = self.always_copy_from = None
+        self.site_dirs = None
+        self.installed_projects = {}
+        self.sitepy_installed = False
+        # Always read easy_install options, even if we are subclassed, or have
+        # an independent instance created.  This ensures that defaults will
+        # always come from the standard configuration file(s)' "easy_install"
+        # section, even if this is a "develop" or "install" command, or some
+        # other embedding.
+        self._dry_run = None
+        self.verbose = self.distribution.verbose
+        self.distribution._set_command_options(
+            self, self.distribution.get_option_dict('easy_install')
+        )
+
+    def delete_blockers(self, blockers):
+        extant_blockers = (
+            filename for filename in blockers
+            if os.path.exists(filename) or os.path.islink(filename)
+        )
+        list(map(self._delete_path, extant_blockers))
+
+    def _delete_path(self, path):
+        log.info("Deleting %s", path)
+        if self.dry_run:
+            return
+
+        is_tree = os.path.isdir(path) and not os.path.islink(path)
+        remover = rmtree if is_tree else os.unlink
+        remover(path)
+
+    @staticmethod
+    def _render_version():
+        """
+        Render the Setuptools version and installation details, then exit.
+        """
+        ver = sys.version[:3]
+        dist = get_distribution('setuptools')
+        tmpl = 'setuptools {dist.version} from {dist.location} (Python {ver})'
+        print(tmpl.format(**locals()))
+        raise SystemExit()
+
+    def finalize_options(self):
+        self.version and self._render_version()
+
+        py_version = sys.version.split()[0]
+        prefix, exec_prefix = get_config_vars('prefix', 'exec_prefix')
+
+        self.config_vars = {
+            'dist_name': self.distribution.get_name(),
+            'dist_version': self.distribution.get_version(),
+            'dist_fullname': self.distribution.get_fullname(),
+            'py_version': py_version,
+            'py_version_short': py_version[0:3],
+            'py_version_nodot': py_version[0] + py_version[2],
+            'sys_prefix': prefix,
+            'prefix': prefix,
+            'sys_exec_prefix': exec_prefix,
+            'exec_prefix': exec_prefix,
+            # Only python 3.2+ has abiflags
+            'abiflags': getattr(sys, 'abiflags', ''),
+        }
+
+        if site.ENABLE_USER_SITE:
+            self.config_vars['userbase'] = self.install_userbase
+            self.config_vars['usersite'] = self.install_usersite
+
+        self._fix_install_dir_for_user_site()
+
+        self.expand_basedirs()
+        self.expand_dirs()
+
+        self._expand(
+            'install_dir', 'script_dir', 'build_directory',
+            'site_dirs',
+        )
+        # If a non-default installation directory was specified, default the
+        # script directory to match it.
+        if self.script_dir is None:
+            self.script_dir = self.install_dir
+
+        if self.no_find_links is None:
+            self.no_find_links = False
+
+        # Let install_dir get set by install_lib command, which in turn
+        # gets its info from the install command, and takes into account
+        # --prefix and --home and all that other crud.
+        self.set_undefined_options(
+            'install_lib', ('install_dir', 'install_dir')
+        )
+        # Likewise, set default script_dir from 'install_scripts.install_dir'
+        self.set_undefined_options(
+            'install_scripts', ('install_dir', 'script_dir')
+        )
+
+        if self.user and self.install_purelib:
+            self.install_dir = self.install_purelib
+            self.script_dir = self.install_scripts
+        # default --record from the install command
+        self.set_undefined_options('install', ('record', 'record'))
+        # Should this be moved to the if statement below? It's not used
+        # elsewhere
+        normpath = map(normalize_path, sys.path)
+        self.all_site_dirs = get_site_dirs()
+        if self.site_dirs is not None:
+            site_dirs = [
+                os.path.expanduser(s.strip()) for s in
+                self.site_dirs.split(',')
+            ]
+            for d in site_dirs:
+                if not os.path.isdir(d):
+                    log.warn("%s (in --site-dirs) does not exist", d)
+                elif normalize_path(d) not in normpath:
+                    raise DistutilsOptionError(
+                        d + " (in --site-dirs) is not on sys.path"
+                    )
+                else:
+                    self.all_site_dirs.append(normalize_path(d))
+        if not self.editable:
+            self.check_site_dir()
+        self.index_url = self.index_url or "https://pypi.python.org/simple"
+        self.shadow_path = self.all_site_dirs[:]
+        for path_item in self.install_dir, normalize_path(self.script_dir):
+            if path_item not in self.shadow_path:
+                self.shadow_path.insert(0, path_item)
+
+        if self.allow_hosts is not None:
+            hosts = [s.strip() for s in self.allow_hosts.split(',')]
+        else:
+            hosts = ['*']
+        if self.package_index is None:
+            self.package_index = self.create_index(
+                self.index_url, search_path=self.shadow_path, hosts=hosts,
+            )
+        self.local_index = Environment(self.shadow_path + sys.path)
+
+        if self.find_links is not None:
+            if isinstance(self.find_links, six.string_types):
+                self.find_links = self.find_links.split()
+        else:
+            self.find_links = []
+        if self.local_snapshots_ok:
+            self.package_index.scan_egg_links(self.shadow_path + sys.path)
+        if not self.no_find_links:
+            self.package_index.add_find_links(self.find_links)
+        self.set_undefined_options('install_lib', ('optimize', 'optimize'))
+        if not isinstance(self.optimize, int):
+            try:
+                self.optimize = int(self.optimize)
+                if not (0 <= self.optimize <= 2):
+                    raise ValueError
+            except ValueError:
+                raise DistutilsOptionError("--optimize must be 0, 1, or 2")
+
+        if self.editable and not self.build_directory:
+            raise DistutilsArgError(
+                "Must specify a build directory (-b) when using --editable"
+            )
+        if not self.args:
+            raise DistutilsArgError(
+                "No urls, filenames, or requirements specified (see --help)")
+
+        self.outputs = []
+
+    def _fix_install_dir_for_user_site(self):
+        """
+        Fix the install_dir if "--user" was used.
+        """
+        if not self.user or not site.ENABLE_USER_SITE:
+            return
+
+        self.create_home_path()
+        if self.install_userbase is None:
+            msg = "User base directory is not specified"
+            raise DistutilsPlatformError(msg)
+        self.install_base = self.install_platbase = self.install_userbase
+        scheme_name = os.name.replace('posix', 'unix') + '_user'
+        self.select_scheme(scheme_name)
+
+    def _expand_attrs(self, attrs):
+        for attr in attrs:
+            val = getattr(self, attr)
+            if val is not None:
+                if os.name == 'posix' or os.name == 'nt':
+                    val = os.path.expanduser(val)
+                val = subst_vars(val, self.config_vars)
+                setattr(self, attr, val)
+
+    def expand_basedirs(self):
+        """Calls `os.path.expanduser` on install_base, install_platbase and
+        root."""
+        self._expand_attrs(['install_base', 'install_platbase', 'root'])
+
+    def expand_dirs(self):
+        """Calls `os.path.expanduser` on install dirs."""
+        dirs = [
+            'install_purelib',
+            'install_platlib',
+            'install_lib',
+            'install_headers',
+            'install_scripts',
+            'install_data',
+        ]
+        self._expand_attrs(dirs)
+
+    def run(self):
+        if self.verbose != self.distribution.verbose:
+            log.set_verbosity(self.verbose)
+        try:
+            for spec in self.args:
+                self.easy_install(spec, not self.no_deps)
+            if self.record:
+                outputs = self.outputs
+                if self.root:  # strip any package prefix
+                    root_len = len(self.root)
+                    for counter in range(len(outputs)):
+                        outputs[counter] = outputs[counter][root_len:]
+                from distutils import file_util
+
+                self.execute(
+                    file_util.write_file, (self.record, outputs),
+                    "writing list of installed files to '%s'" %
+                    self.record
+                )
+            self.warn_deprecated_options()
+        finally:
+            log.set_verbosity(self.distribution.verbose)
+
+    def pseudo_tempname(self):
+        """Return a pseudo-tempname base in the install directory.
+        This code is intentionally naive; if a malicious party can write to
+        the target directory you're already in deep doodoo.
+        """
+        try:
+            pid = os.getpid()
+        except Exception:
+            pid = random.randint(0, sys.maxsize)
+        return os.path.join(self.install_dir, "test-easy-install-%s" % pid)
+
+    def warn_deprecated_options(self):
+        pass
+
+    def check_site_dir(self):
+        """Verify that self.install_dir is .pth-capable dir, if needed"""
+
+        instdir = normalize_path(self.install_dir)
+        pth_file = os.path.join(instdir, 'easy-install.pth')
+
+        # Is it a configured, PYTHONPATH, implicit, or explicit site dir?
+        is_site_dir = instdir in self.all_site_dirs
+
+        if not is_site_dir and not self.multi_version:
+            # No?  Then directly test whether it does .pth file processing
+            is_site_dir = self.check_pth_processing()
+        else:
+            # make sure we can write to target dir
+            testfile = self.pseudo_tempname() + '.write-test'
+            test_exists = os.path.exists(testfile)
+            try:
+                if test_exists:
+                    os.unlink(testfile)
+                open(testfile, 'w').close()
+                os.unlink(testfile)
+            except (OSError, IOError):
+                self.cant_write_to_target()
+
+        if not is_site_dir and not self.multi_version:
+            # Can't install non-multi to non-site dir
+            raise DistutilsError(self.no_default_version_msg())
+
+        if is_site_dir:
+            if self.pth_file is None:
+                self.pth_file = PthDistributions(pth_file, self.all_site_dirs)
+        else:
+            self.pth_file = None
+
+        if instdir not in map(normalize_path, _pythonpath()):
+            # only PYTHONPATH dirs need a site.py, so pretend it's there
+            self.sitepy_installed = True
+        elif self.multi_version and not os.path.exists(pth_file):
+            self.sitepy_installed = True  # don't need site.py in this case
+            self.pth_file = None  # and don't create a .pth file
+        self.install_dir = instdir
+
+    __cant_write_msg = textwrap.dedent("""
+        can't create or remove files in install directory
+
+        The following error occurred while trying to add or remove files in the
+        installation directory:
+
+            %s
+
+        The installation directory you specified (via --install-dir, --prefix, or
+        the distutils default setting) was:
+
+            %s
+        """).lstrip()
+
+    __not_exists_id = textwrap.dedent("""
+        This directory does not currently exist.  Please create it and try again, or
+        choose a different installation directory (using the -d or --install-dir
+        option).
+        """).lstrip()
+
+    __access_msg = textwrap.dedent("""
+        Perhaps your account does not have write access to this directory?  If the
+        installation directory is a system-owned directory, you may need to sign in
+        as the administrator or "root" account.  If you do not have administrative
+        access to this machine, you may wish to choose a different installation
+        directory, preferably one that is listed in your PYTHONPATH environment
+        variable.
+
+        For information on other options, you may wish to consult the
+        documentation at:
+
+          https://setuptools.readthedocs.io/en/latest/easy_install.html
+
+        Please make the appropriate changes for your system and try again.
+        """).lstrip()
+
+    def cant_write_to_target(self):
+        msg = self.__cant_write_msg % (sys.exc_info()[1], self.install_dir,)
+
+        if not os.path.exists(self.install_dir):
+            msg += '\n' + self.__not_exists_id
+        else:
+            msg += '\n' + self.__access_msg
+        raise DistutilsError(msg)
+
+    def check_pth_processing(self):
+        """Empirically verify whether .pth files are supported in inst. dir"""
+        instdir = self.install_dir
+        log.info("Checking .pth file support in %s", instdir)
+        pth_file = self.pseudo_tempname() + ".pth"
+        ok_file = pth_file + '.ok'
+        ok_exists = os.path.exists(ok_file)
+        tmpl = _one_liner("""
+            import os
+            f = open({ok_file!r}, 'w')
+            f.write('OK')
+            f.close()
+            """) + '\n'
+        try:
+            if ok_exists:
+                os.unlink(ok_file)
+            dirname = os.path.dirname(ok_file)
+            pkg_resources.py31compat.makedirs(dirname, exist_ok=True)
+            f = open(pth_file, 'w')
+        except (OSError, IOError):
+            self.cant_write_to_target()
+        else:
+            try:
+                f.write(tmpl.format(**locals()))
+                f.close()
+                f = None
+                executable = sys.executable
+                if os.name == 'nt':
+                    dirname, basename = os.path.split(executable)
+                    alt = os.path.join(dirname, 'pythonw.exe')
+                    use_alt = (
+                        basename.lower() == 'python.exe' and
+                        os.path.exists(alt)
+                    )
+                    if use_alt:
+                        # use pythonw.exe to avoid opening a console window
+                        executable = alt
+
+                from distutils.spawn import spawn
+
+                spawn([executable, '-E', '-c', 'pass'], 0)
+
+                if os.path.exists(ok_file):
+                    log.info(
+                        "TEST PASSED: %s appears to support .pth files",
+                        instdir
+                    )
+                    return True
+            finally:
+                if f:
+                    f.close()
+                if os.path.exists(ok_file):
+                    os.unlink(ok_file)
+                if os.path.exists(pth_file):
+                    os.unlink(pth_file)
+        if not self.multi_version:
+            log.warn("TEST FAILED: %s does NOT support .pth files", instdir)
+        return False
+
+    def install_egg_scripts(self, dist):
+        """Write all the scripts for `dist`, unless scripts are excluded"""
+        if not self.exclude_scripts and dist.metadata_isdir('scripts'):
+            for script_name in dist.metadata_listdir('scripts'):
+                if dist.metadata_isdir('scripts/' + script_name):
+                    # The "script" is a directory, likely a Python 3
+                    # __pycache__ directory, so skip it.
+                    continue
+                self.install_script(
+                    dist, script_name,
+                    dist.get_metadata('scripts/' + script_name)
+                )
+        self.install_wrapper_scripts(dist)
+
+    def add_output(self, path):
+        if os.path.isdir(path):
+            for base, dirs, files in os.walk(path):
+                for filename in files:
+                    self.outputs.append(os.path.join(base, filename))
+        else:
+            self.outputs.append(path)
+
+    def not_editable(self, spec):
+        if self.editable:
+            raise DistutilsArgError(
+                "Invalid argument %r: you can't use filenames or URLs "
+                "with --editable (except via the --find-links option)."
+                % (spec,)
+            )
+
+    def check_editable(self, spec):
+        if not self.editable:
+            return
+
+        if os.path.exists(os.path.join(self.build_directory, spec.key)):
+            raise DistutilsArgError(
+                "%r already exists in %s; can't do a checkout there" %
+                (spec.key, self.build_directory)
+            )
+
+    @contextlib.contextmanager
+    def _tmpdir(self):
+        tmpdir = tempfile.mkdtemp(prefix=six.u("easy_install-"))
+        try:
+            # cast to str as workaround for #709 and #710 and #712
+            yield str(tmpdir)
+        finally:
+            os.path.exists(tmpdir) and rmtree(rmtree_safe(tmpdir))
+
+    def easy_install(self, spec, deps=False):
+        if not self.editable:
+            self.install_site_py()
+
+        with self._tmpdir() as tmpdir:
+            if not isinstance(spec, Requirement):
+                if URL_SCHEME(spec):
+                    # It's a url, download it to tmpdir and process
+                    self.not_editable(spec)
+                    dl = self.package_index.download(spec, tmpdir)
+                    return self.install_item(None, dl, tmpdir, deps, True)
+
+                elif os.path.exists(spec):
+                    # Existing file or directory, just process it directly
+                    self.not_editable(spec)
+                    return self.install_item(None, spec, tmpdir, deps, True)
+                else:
+                    spec = parse_requirement_arg(spec)
+
+            self.check_editable(spec)
+            dist = self.package_index.fetch_distribution(
+                spec, tmpdir, self.upgrade, self.editable,
+                not self.always_copy, self.local_index
+            )
+            if dist is None:
+                msg = "Could not find suitable distribution for %r" % spec
+                if self.always_copy:
+                    msg += " (--always-copy skips system and development eggs)"
+                raise DistutilsError(msg)
+            elif dist.precedence == DEVELOP_DIST:
+                # .egg-info dists don't need installing, just process deps
+                self.process_distribution(spec, dist, deps, "Using")
+                return dist
+            else:
+                return self.install_item(spec, dist.location, tmpdir, deps)
+
+    def install_item(self, spec, download, tmpdir, deps, install_needed=False):
+
+        # Installation is also needed if file in tmpdir or is not an egg
+        install_needed = install_needed or self.always_copy
+        install_needed = install_needed or os.path.dirname(download) == tmpdir
+        install_needed = install_needed or not download.endswith('.egg')
+        install_needed = install_needed or (
+            self.always_copy_from is not None and
+            os.path.dirname(normalize_path(download)) ==
+            normalize_path(self.always_copy_from)
+        )
+
+        if spec and not install_needed:
+            # at this point, we know it's a local .egg, we just don't know if
+            # it's already installed.
+            for dist in self.local_index[spec.project_name]:
+                if dist.location == download:
+                    break
+            else:
+                install_needed = True  # it's not in the local index
+
+        log.info("Processing %s", os.path.basename(download))
+
+        if install_needed:
+            dists = self.install_eggs(spec, download, tmpdir)
+            for dist in dists:
+                self.process_distribution(spec, dist, deps)
+        else:
+            dists = [self.egg_distribution(download)]
+            self.process_distribution(spec, dists[0], deps, "Using")
+
+        if spec is not None:
+            for dist in dists:
+                if dist in spec:
+                    return dist
+
+    def select_scheme(self, name):
+        """Sets the install directories by applying the install schemes."""
+        # it's the caller's problem if they supply a bad name!
+        scheme = INSTALL_SCHEMES[name]
+        for key in SCHEME_KEYS:
+            attrname = 'install_' + key
+            if getattr(self, attrname) is None:
+                setattr(self, attrname, scheme[key])
+
+    def process_distribution(self, requirement, dist, deps=True, *info):
+        self.update_pth(dist)
+        self.package_index.add(dist)
+        if dist in self.local_index[dist.key]:
+            self.local_index.remove(dist)
+        self.local_index.add(dist)
+        self.install_egg_scripts(dist)
+        self.installed_projects[dist.key] = dist
+        log.info(self.installation_report(requirement, dist, *info))
+        if (dist.has_metadata('dependency_links.txt') and
+                not self.no_find_links):
+            self.package_index.add_find_links(
+                dist.get_metadata_lines('dependency_links.txt')
+            )
+        if not deps and not self.always_copy:
+            return
+        elif requirement is not None and dist.key != requirement.key:
+            log.warn("Skipping dependencies for %s", dist)
+            return  # XXX this is not the distribution we were looking for
+        elif requirement is None or dist not in requirement:
+            # if we wound up with a different version, resolve what we've got
+            distreq = dist.as_requirement()
+            requirement = Requirement(str(distreq))
+        log.info("Processing dependencies for %s", requirement)
+        try:
+            distros = WorkingSet([]).resolve(
+                [requirement], self.local_index, self.easy_install
+            )
+        except DistributionNotFound as e:
+            raise DistutilsError(str(e))
+        except VersionConflict as e:
+            raise DistutilsError(e.report())
+        if self.always_copy or self.always_copy_from:
+            # Force all the relevant distros to be copied or activated
+            for dist in distros:
+                if dist.key not in self.installed_projects:
+                    self.easy_install(dist.as_requirement())
+        log.info("Finished processing dependencies for %s", requirement)
+
+    def should_unzip(self, dist):
+        if self.zip_ok is not None:
+            return not self.zip_ok
+        if dist.has_metadata('not-zip-safe'):
+            return True
+        if not dist.has_metadata('zip-safe'):
+            return True
+        return False
+
+    def maybe_move(self, spec, dist_filename, setup_base):
+        dst = os.path.join(self.build_directory, spec.key)
+        if os.path.exists(dst):
+            msg = (
+                "%r already exists in %s; build directory %s will not be kept"
+            )
+            log.warn(msg, spec.key, self.build_directory, setup_base)
+            return setup_base
+        if os.path.isdir(dist_filename):
+            setup_base = dist_filename
+        else:
+            if os.path.dirname(dist_filename) == setup_base:
+                os.unlink(dist_filename)  # get it out of the tmp dir
+            contents = os.listdir(setup_base)
+            if len(contents) == 1:
+                dist_filename = os.path.join(setup_base, contents[0])
+                if os.path.isdir(dist_filename):
+                    # if the only thing there is a directory, move it instead
+                    setup_base = dist_filename
+        ensure_directory(dst)
+        shutil.move(setup_base, dst)
+        return dst
+
+    def install_wrapper_scripts(self, dist):
+        if self.exclude_scripts:
+            return
+        for args in ScriptWriter.best().get_args(dist):
+            self.write_script(*args)
+
+    def install_script(self, dist, script_name, script_text, dev_path=None):
+        """Generate a legacy script wrapper and install it"""
+        spec = str(dist.as_requirement())
+        is_script = is_python_script(script_text, script_name)
+
+        if is_script:
+            body = self._load_template(dev_path) % locals()
+            script_text = ScriptWriter.get_header(script_text) + body
+        self.write_script(script_name, _to_ascii(script_text), 'b')
+
+    @staticmethod
+    def _load_template(dev_path):
+        """
+        There are a couple of template scripts in the package. This
+        function loads one of them and prepares it for use.
+        """
+        # See https://github.com/pypa/setuptools/issues/134 for info
+        # on script file naming and downstream issues with SVR4
+        name = 'script.tmpl'
+        if dev_path:
+            name = name.replace('.tmpl', ' (dev).tmpl')
+
+        raw_bytes = resource_string('setuptools', name)
+        return raw_bytes.decode('utf-8')
+
+    def write_script(self, script_name, contents, mode="t", blockers=()):
+        """Write an executable file to the scripts directory"""
+        self.delete_blockers(  # clean up old .py/.pyw w/o a script
+            [os.path.join(self.script_dir, x) for x in blockers]
+        )
+        log.info("Installing %s script to %s", script_name, self.script_dir)
+        target = os.path.join(self.script_dir, script_name)
+        self.add_output(target)
+
+        if self.dry_run:
+            return
+
+        mask = current_umask()
+        ensure_directory(target)
+        if os.path.exists(target):
+            os.unlink(target)
+        with open(target, "w" + mode) as f:
+            f.write(contents)
+        chmod(target, 0o777 - mask)
+
+    def install_eggs(self, spec, dist_filename, tmpdir):
+        # .egg dirs or files are already built, so just return them
+        if dist_filename.lower().endswith('.egg'):
+            return [self.install_egg(dist_filename, tmpdir)]
+        elif dist_filename.lower().endswith('.exe'):
+            return [self.install_exe(dist_filename, tmpdir)]
+        elif dist_filename.lower().endswith('.whl'):
+            return [self.install_wheel(dist_filename, tmpdir)]
+
+        # Anything else, try to extract and build
+        setup_base = tmpdir
+        if os.path.isfile(dist_filename) and not dist_filename.endswith('.py'):
+            unpack_archive(dist_filename, tmpdir, self.unpack_progress)
+        elif os.path.isdir(dist_filename):
+            setup_base = os.path.abspath(dist_filename)
+
+        if (setup_base.startswith(tmpdir)  # something we downloaded
+                and self.build_directory and spec is not None):
+            setup_base = self.maybe_move(spec, dist_filename, setup_base)
+
+        # Find the setup.py file
+        setup_script = os.path.join(setup_base, 'setup.py')
+
+        if not os.path.exists(setup_script):
+            setups = glob(os.path.join(setup_base, '*', 'setup.py'))
+            if not setups:
+                raise DistutilsError(
+                    "Couldn't find a setup script in %s" %
+                    os.path.abspath(dist_filename)
+                )
+            if len(setups) > 1:
+                raise DistutilsError(
+                    "Multiple setup scripts in %s" %
+                    os.path.abspath(dist_filename)
+                )
+            setup_script = setups[0]
+
+        # Now run it, and return the result
+        if self.editable:
+            log.info(self.report_editable(spec, setup_script))
+            return []
+        else:
+            return self.build_and_install(setup_script, setup_base)
+
+    def egg_distribution(self, egg_path):
+        if os.path.isdir(egg_path):
+            metadata = PathMetadata(egg_path, os.path.join(egg_path,
+                                                           'EGG-INFO'))
+        else:
+            metadata = EggMetadata(zipimport.zipimporter(egg_path))
+        return Distribution.from_filename(egg_path, metadata=metadata)
+
+    def install_egg(self, egg_path, tmpdir):
+        destination = os.path.join(
+            self.install_dir,
+            os.path.basename(egg_path),
+        )
+        destination = os.path.abspath(destination)
+        if not self.dry_run:
+            ensure_directory(destination)
+
+        dist = self.egg_distribution(egg_path)
+        if not samefile(egg_path, destination):
+            if os.path.isdir(destination) and not os.path.islink(destination):
+                dir_util.remove_tree(destination, dry_run=self.dry_run)
+            elif os.path.exists(destination):
+                self.execute(
+                    os.unlink,
+                    (destination,),
+                    "Removing " + destination,
+                )
+            try:
+                new_dist_is_zipped = False
+                if os.path.isdir(egg_path):
+                    if egg_path.startswith(tmpdir):
+                        f, m = shutil.move, "Moving"
+                    else:
+                        f, m = shutil.copytree, "Copying"
+                elif self.should_unzip(dist):
+                    self.mkpath(destination)
+                    f, m = self.unpack_and_compile, "Extracting"
+                else:
+                    new_dist_is_zipped = True
+                    if egg_path.startswith(tmpdir):
+                        f, m = shutil.move, "Moving"
+                    else:
+                        f, m = shutil.copy2, "Copying"
+                self.execute(
+                    f,
+                    (egg_path, destination),
+                    (m + " %s to %s") % (
+                        os.path.basename(egg_path),
+                        os.path.dirname(destination)
+                    ),
+                )
+                update_dist_caches(
+                    destination,
+                    fix_zipimporter_caches=new_dist_is_zipped,
+                )
+            except Exception:
+                update_dist_caches(destination, fix_zipimporter_caches=False)
+                raise
+
+        self.add_output(destination)
+        return self.egg_distribution(destination)
+
+    def install_exe(self, dist_filename, tmpdir):
+        # See if it's valid, get data
+        cfg = extract_wininst_cfg(dist_filename)
+        if cfg is None:
+            raise DistutilsError(
+                "%s is not a valid distutils Windows .exe" % dist_filename
+            )
+        # Create a dummy distribution object until we build the real distro
+        dist = Distribution(
+            None,
+            project_name=cfg.get('metadata', 'name'),
+            version=cfg.get('metadata', 'version'), platform=get_platform(),
+        )
+
+        # Convert the .exe to an unpacked egg
+        egg_path = os.path.join(tmpdir, dist.egg_name() + '.egg')
+        dist.location = egg_path
+        egg_tmp = egg_path + '.tmp'
+        _egg_info = os.path.join(egg_tmp, 'EGG-INFO')
+        pkg_inf = os.path.join(_egg_info, 'PKG-INFO')
+        ensure_directory(pkg_inf)  # make sure EGG-INFO dir exists
+        dist._provider = PathMetadata(egg_tmp, _egg_info)  # XXX
+        self.exe_to_egg(dist_filename, egg_tmp)
+
+        # Write EGG-INFO/PKG-INFO
+        if not os.path.exists(pkg_inf):
+            f = open(pkg_inf, 'w')
+            f.write('Metadata-Version: 1.0\n')
+            for k, v in cfg.items('metadata'):
+                if k != 'target_version':
+                    f.write('%s: %s\n' % (k.replace('_', '-').title(), v))
+            f.close()
+        script_dir = os.path.join(_egg_info, 'scripts')
+        # delete entry-point scripts to avoid duping
+        self.delete_blockers([
+            os.path.join(script_dir, args[0])
+            for args in ScriptWriter.get_args(dist)
+        ])
+        # Build .egg file from tmpdir
+        bdist_egg.make_zipfile(
+            egg_path, egg_tmp, verbose=self.verbose, dry_run=self.dry_run,
+        )
+        # install the .egg
+        return self.install_egg(egg_path, tmpdir)
+
+    def exe_to_egg(self, dist_filename, egg_tmp):
+        """Extract a bdist_wininst to the directories an egg would use"""
+        # Check for .pth file and set up prefix translations
+        prefixes = get_exe_prefixes(dist_filename)
+        to_compile = []
+        native_libs = []
+        top_level = {}
+
+        def process(src, dst):
+            s = src.lower()
+            for old, new in prefixes:
+                if s.startswith(old):
+                    src = new + src[len(old):]
+                    parts = src.split('/')
+                    dst = os.path.join(egg_tmp, *parts)
+                    dl = dst.lower()
+                    if dl.endswith('.pyd') or dl.endswith('.dll'):
+                        parts[-1] = bdist_egg.strip_module(parts[-1])
+                        top_level[os.path.splitext(parts[0])[0]] = 1
+                        native_libs.append(src)
+                    elif dl.endswith('.py') and old != 'SCRIPTS/':
+                        top_level[os.path.splitext(parts[0])[0]] = 1
+                        to_compile.append(dst)
+                    return dst
+            if not src.endswith('.pth'):
+                log.warn("WARNING: can't process %s", src)
+            return None
+
+        # extract, tracking .pyd/.dll->native_libs and .py -> to_compile
+        unpack_archive(dist_filename, egg_tmp, process)
+        stubs = []
+        for res in native_libs:
+            if res.lower().endswith('.pyd'):  # create stubs for .pyd's
+                parts = res.split('/')
+                resource = parts[-1]
+                parts[-1] = bdist_egg.strip_module(parts[-1]) + '.py'
+                pyfile = os.path.join(egg_tmp, *parts)
+                to_compile.append(pyfile)
+                stubs.append(pyfile)
+                bdist_egg.write_stub(resource, pyfile)
+        self.byte_compile(to_compile)  # compile .py's
+        bdist_egg.write_safety_flag(
+            os.path.join(egg_tmp, 'EGG-INFO'),
+            bdist_egg.analyze_egg(egg_tmp, stubs))  # write zip-safety flag
+
+        for name in 'top_level', 'native_libs':
+            if locals()[name]:
+                txt = os.path.join(egg_tmp, 'EGG-INFO', name + '.txt')
+                if not os.path.exists(txt):
+                    f = open(txt, 'w')
+                    f.write('\n'.join(locals()[name]) + '\n')
+                    f.close()
+
+    def install_wheel(self, wheel_path, tmpdir):
+        wheel = Wheel(wheel_path)
+        assert wheel.is_compatible()
+        destination = os.path.join(self.install_dir, wheel.egg_name())
+        destination = os.path.abspath(destination)
+        if not self.dry_run:
+            ensure_directory(destination)
+        if os.path.isdir(destination) and not os.path.islink(destination):
+            dir_util.remove_tree(destination, dry_run=self.dry_run)
+        elif os.path.exists(destination):
+            self.execute(
+                os.unlink,
+                (destination,),
+                "Removing " + destination,
+            )
+        try:
+            self.execute(
+                wheel.install_as_egg,
+                (destination,),
+                ("Installing %s to %s") % (
+                    os.path.basename(wheel_path),
+                    os.path.dirname(destination)
+                ),
+            )
+        finally:
+            update_dist_caches(destination, fix_zipimporter_caches=False)
+        self.add_output(destination)
+        return self.egg_distribution(destination)
+
+    __mv_warning = textwrap.dedent("""
+        Because this distribution was installed --multi-version, before you can
+        import modules from this package in an application, you will need to
+        'import pkg_resources' and then use a 'require()' call similar to one of
+        these examples, in order to select the desired version:
+
+            pkg_resources.require("%(name)s")  # latest installed version
+            pkg_resources.require("%(name)s==%(version)s")  # this exact version
+            pkg_resources.require("%(name)s>=%(version)s")  # this version or higher
+        """).lstrip()
+
+    __id_warning = textwrap.dedent("""
+        Note also that the installation directory must be on sys.path at runtime for
+        this to work.  (e.g. by being the application's script directory, by being on
+        PYTHONPATH, or by being added to sys.path by your code.)
+        """)
+
+    def installation_report(self, req, dist, what="Installed"):
+        """Helpful installation message for display to package users"""
+        msg = "\n%(what)s %(eggloc)s%(extras)s"
+        if self.multi_version and not self.no_report:
+            msg += '\n' + self.__mv_warning
+            if self.install_dir not in map(normalize_path, sys.path):
+                msg += '\n' + self.__id_warning
+
+        eggloc = dist.location
+        name = dist.project_name
+        version = dist.version
+        extras = ''  # TODO: self.report_extras(req, dist)
+        return msg % locals()
+
+    __editable_msg = textwrap.dedent("""
+        Extracted editable version of %(spec)s to %(dirname)s
+
+        If it uses setuptools in its setup script, you can activate it in
+        "development" mode by going to that directory and running::
+
+            %(python)s setup.py develop
+
+        See the setuptools documentation for the "develop" command for more info.
+        """).lstrip()
+
+    def report_editable(self, spec, setup_script):
+        dirname = os.path.dirname(setup_script)
+        python = sys.executable
+        return '\n' + self.__editable_msg % locals()
+
+    def run_setup(self, setup_script, setup_base, args):
+        sys.modules.setdefault('distutils.command.bdist_egg', bdist_egg)
+        sys.modules.setdefault('distutils.command.egg_info', egg_info)
+
+        args = list(args)
+        if self.verbose > 2:
+            v = 'v' * (self.verbose - 1)
+            args.insert(0, '-' + v)
+        elif self.verbose < 2:
+            args.insert(0, '-q')
+        if self.dry_run:
+            args.insert(0, '-n')
+        log.info(
+            "Running %s %s", setup_script[len(setup_base) + 1:], ' '.join(args)
+        )
+        try:
+            run_setup(setup_script, args)
+        except SystemExit as v:
+            raise DistutilsError("Setup script exited with %s" % (v.args[0],))
+
+    def build_and_install(self, setup_script, setup_base):
+        args = ['bdist_egg', '--dist-dir']
+
+        dist_dir = tempfile.mkdtemp(
+            prefix='egg-dist-tmp-', dir=os.path.dirname(setup_script)
+        )
+        try:
+            self._set_fetcher_options(os.path.dirname(setup_script))
+            args.append(dist_dir)
+
+            self.run_setup(setup_script, setup_base, args)
+            all_eggs = Environment([dist_dir])
+            eggs = []
+            for key in all_eggs:
+                for dist in all_eggs[key]:
+                    eggs.append(self.install_egg(dist.location, setup_base))
+            if not eggs and not self.dry_run:
+                log.warn("No eggs found in %s (setup script problem?)",
+                         dist_dir)
+            return eggs
+        finally:
+            rmtree(dist_dir)
+            log.set_verbosity(self.verbose)  # restore our log verbosity
+
+    def _set_fetcher_options(self, base):
+        """
+        When easy_install is about to run bdist_egg on a source dist, that
+        source dist might have 'setup_requires' directives, requiring
+        additional fetching. Ensure the fetcher options given to easy_install
+        are available to that command as well.
+        """
+        # find the fetch options from easy_install and write them out
+        # to the setup.cfg file.
+        ei_opts = self.distribution.get_option_dict('easy_install').copy()
+        fetch_directives = (
+            'find_links', 'site_dirs', 'index_url', 'optimize',
+            'site_dirs', 'allow_hosts',
+        )
+        fetch_options = {}
+        for key, val in ei_opts.items():
+            if key not in fetch_directives:
+                continue
+            fetch_options[key.replace('_', '-')] = val[1]
+        # create a settings dictionary suitable for `edit_config`
+        settings = dict(easy_install=fetch_options)
+        cfg_filename = os.path.join(base, 'setup.cfg')
+        setopt.edit_config(cfg_filename, settings)
+
+    def update_pth(self, dist):
+        if self.pth_file is None:
+            return
+
+        for d in self.pth_file[dist.key]:  # drop old entries
+            if self.multi_version or d.location != dist.location:
+                log.info("Removing %s from easy-install.pth file", d)
+                self.pth_file.remove(d)
+                if d.location in self.shadow_path:
+                    self.shadow_path.remove(d.location)
+
+        if not self.multi_version:
+            if dist.location in self.pth_file.paths:
+                log.info(
+                    "%s is already the active version in easy-install.pth",
+                    dist,
+                )
+            else:
+                log.info("Adding %s to easy-install.pth file", dist)
+                self.pth_file.add(dist)  # add new entry
+                if dist.location not in self.shadow_path:
+                    self.shadow_path.append(dist.location)
+
+        if not self.dry_run:
+
+            self.pth_file.save()
+
+            if dist.key == 'setuptools':
+                # Ensure that setuptools itself never becomes unavailable!
+                # XXX should this check for latest version?
+                filename = os.path.join(self.install_dir, 'setuptools.pth')
+                if os.path.islink(filename):
+                    os.unlink(filename)
+                f = open(filename, 'wt')
+                f.write(self.pth_file.make_relative(dist.location) + '\n')
+                f.close()
+
+    def unpack_progress(self, src, dst):
+        # Progress filter for unpacking
+        log.debug("Unpacking %s to %s", src, dst)
+        return dst  # only unpack-and-compile skips files for dry run
+
+    def unpack_and_compile(self, egg_path, destination):
+        to_compile = []
+        to_chmod = []
+
+        def pf(src, dst):
+            if dst.endswith('.py') and not src.startswith('EGG-INFO/'):
+                to_compile.append(dst)
+            elif dst.endswith('.dll') or dst.endswith('.so'):
+                to_chmod.append(dst)
+            self.unpack_progress(src, dst)
+            return not self.dry_run and dst or None
+
+        unpack_archive(egg_path, destination, pf)
+        self.byte_compile(to_compile)
+        if not self.dry_run:
+            for f in to_chmod:
+                mode = ((os.stat(f)[stat.ST_MODE]) | 0o555) & 0o7755
+                chmod(f, mode)
+
+    def byte_compile(self, to_compile):
+        if sys.dont_write_bytecode:
+            return
+
+        from distutils.util import byte_compile
+
+        try:
+            # try to make the byte compile messages quieter
+            log.set_verbosity(self.verbose - 1)
+
+            byte_compile(to_compile, optimize=0, force=1, dry_run=self.dry_run)
+            if self.optimize:
+                byte_compile(
+                    to_compile, optimize=self.optimize, force=1,
+                    dry_run=self.dry_run,
+                )
+        finally:
+            log.set_verbosity(self.verbose)  # restore original verbosity
+
+    __no_default_msg = textwrap.dedent("""
+        bad install directory or PYTHONPATH
+
+        You are attempting to install a package to a directory that is not
+        on PYTHONPATH and which Python does not read ".pth" files from.  The
+        installation directory you specified (via --install-dir, --prefix, or
+        the distutils default setting) was:
+
+            %s
+
+        and your PYTHONPATH environment variable currently contains:
+
+            %r
+
+        Here are some of your options for correcting the problem:
+
+        * You can choose a different installation directory, i.e., one that is
+          on PYTHONPATH or supports .pth files
+
+        * You can add the installation directory to the PYTHONPATH environment
+          variable.  (It must then also be on PYTHONPATH whenever you run
+          Python and want to use the package(s) you are installing.)
+
+        * You can set up the installation directory to support ".pth" files by
+          using one of the approaches described here:
+
+          https://setuptools.readthedocs.io/en/latest/easy_install.html#custom-installation-locations
+
+
+        Please make the appropriate changes for your system and try again.""").lstrip()
+
+    def no_default_version_msg(self):
+        template = self.__no_default_msg
+        return template % (self.install_dir, os.environ.get('PYTHONPATH', ''))
+
+    def install_site_py(self):
+        """Make sure there's a site.py in the target dir, if needed"""
+
+        if self.sitepy_installed:
+            return  # already did it, or don't need to
+
+        sitepy = os.path.join(self.install_dir, "site.py")
+        source = resource_string("setuptools", "site-patch.py")
+        source = source.decode('utf-8')
+        current = ""
+
+        if os.path.exists(sitepy):
+            log.debug("Checking existing site.py in %s", self.install_dir)
+            with io.open(sitepy) as strm:
+                current = strm.read()
+
+            if not current.startswith('def __boot():'):
+                raise DistutilsError(
+                    "%s is not a setuptools-generated site.py; please"
+                    " remove it." % sitepy
+                )
+
+        if current != source:
+            log.info("Creating %s", sitepy)
+            if not self.dry_run:
+                ensure_directory(sitepy)
+                with io.open(sitepy, 'w', encoding='utf-8') as strm:
+                    strm.write(source)
+            self.byte_compile([sitepy])
+
+        self.sitepy_installed = True
+
+    def create_home_path(self):
+        """Create directories under ~."""
+        if not self.user:
+            return
+        home = convert_path(os.path.expanduser("~"))
+        for name, path in six.iteritems(self.config_vars):
+            if path.startswith(home) and not os.path.isdir(path):
+                self.debug_print("os.makedirs('%s', 0o700)" % path)
+                os.makedirs(path, 0o700)
+
+    INSTALL_SCHEMES = dict(
+        posix=dict(
+            install_dir='$base/lib/python$py_version_short/site-packages',
+            script_dir='$base/bin',
+        ),
+    )
+
+    DEFAULT_SCHEME = dict(
+        install_dir='$base/Lib/site-packages',
+        script_dir='$base/Scripts',
+    )
+
+    def _expand(self, *attrs):
+        config_vars = self.get_finalized_command('install').config_vars
+
+        if self.prefix:
+            # Set default install_dir/scripts from --prefix
+            config_vars = config_vars.copy()
+            config_vars['base'] = self.prefix
+            scheme = self.INSTALL_SCHEMES.get(os.name, self.DEFAULT_SCHEME)
+            for attr, val in scheme.items():
+                if getattr(self, attr, None) is None:
+                    setattr(self, attr, val)
+
+        from distutils.util import subst_vars
+
+        for attr in attrs:
+            val = getattr(self, attr)
+            if val is not None:
+                val = subst_vars(val, config_vars)
+                if os.name == 'posix':
+                    val = os.path.expanduser(val)
+                setattr(self, attr, val)
+
+
+def _pythonpath():
+    items = os.environ.get('PYTHONPATH', '').split(os.pathsep)
+    return filter(None, items)
+
+
+def get_site_dirs():
+    """
+    Return a list of 'site' dirs
+    """
+
+    sitedirs = []
+
+    # start with PYTHONPATH
+    sitedirs.extend(_pythonpath())
+
+    prefixes = [sys.prefix]
+    if sys.exec_prefix != sys.prefix:
+        prefixes.append(sys.exec_prefix)
+    for prefix in prefixes:
+        if prefix:
+            if sys.platform in ('os2emx', 'riscos'):
+                sitedirs.append(os.path.join(prefix, "Lib", "site-packages"))
+            elif os.sep == '/':
+                sitedirs.extend([
+                    os.path.join(
+                        prefix,
+                        "lib",
+                        "python" + sys.version[:3],
+                        "site-packages",
+                    ),
+                    os.path.join(prefix, "lib", "site-python"),
+                ])
+            else:
+                sitedirs.extend([
+                    prefix,
+                    os.path.join(prefix, "lib", "site-packages"),
+                ])
+            if sys.platform == 'darwin':
+                # for framework builds *only* we add the standard Apple
+                # locations. Currently only per-user, but /Library and
+                # /Network/Library could be added too
+                if 'Python.framework' in prefix:
+                    home = os.environ.get('HOME')
+                    if home:
+                        home_sp = os.path.join(
+                            home,
+                            'Library',
+                            'Python',
+                            sys.version[:3],
+                            'site-packages',
+                        )
+                        sitedirs.append(home_sp)
+    lib_paths = get_path('purelib'), get_path('platlib')
+    for site_lib in lib_paths:
+        if site_lib not in sitedirs:
+            sitedirs.append(site_lib)
+
+    if site.ENABLE_USER_SITE:
+        sitedirs.append(site.USER_SITE)
+
+    try:
+        sitedirs.extend(site.getsitepackages())
+    except AttributeError:
+        pass
+
+    sitedirs = list(map(normalize_path, sitedirs))
+
+    return sitedirs
+
+
+def expand_paths(inputs):
+    """Yield sys.path directories that might contain "old-style" packages"""
+
+    seen = {}
+
+    for dirname in inputs:
+        dirname = normalize_path(dirname)
+        if dirname in seen:
+            continue
+
+        seen[dirname] = 1
+        if not os.path.isdir(dirname):
+            continue
+
+        files = os.listdir(dirname)
+        yield dirname, files
+
+        for name in files:
+            if not name.endswith('.pth'):
+                # We only care about the .pth files
+                continue
+            if name in ('easy-install.pth', 'setuptools.pth'):
+                # Ignore .pth files that we control
+                continue
+
+            # Read the .pth file
+            f = open(os.path.join(dirname, name))
+            lines = list(yield_lines(f))
+            f.close()
+
+            # Yield existing non-dupe, non-import directory lines from it
+            for line in lines:
+                if not line.startswith("import"):
+                    line = normalize_path(line.rstrip())
+                    if line not in seen:
+                        seen[line] = 1
+                        if not os.path.isdir(line):
+                            continue
+                        yield line, os.listdir(line)
+
+
+def extract_wininst_cfg(dist_filename):
+    """Extract configuration data from a bdist_wininst .exe
+
+    Returns a configparser.RawConfigParser, or None
+    """
+    f = open(dist_filename, 'rb')
+    try:
+        endrec = zipfile._EndRecData(f)
+        if endrec is None:
+            return None
+
+        prepended = (endrec[9] - endrec[5]) - endrec[6]
+        if prepended < 12:  # no wininst data here
+            return None
+        f.seek(prepended - 12)
+
+        tag, cfglen, bmlen = struct.unpack("<iii", f.read(12))
+        if tag not in (0x1234567A, 0x1234567B):
+            return None  # not a valid tag
+
+        f.seek(prepended - (12 + cfglen))
+        init = {'version': '', 'target_version': ''}
+        cfg = configparser.RawConfigParser(init)
+        try:
+            part = f.read(cfglen)
+            # Read up to the first null byte.
+            config = part.split(b'\0', 1)[0]
+            # Now the config is in bytes, but for RawConfigParser, it should
+            #  be text, so decode it.
+            config = config.decode(sys.getfilesystemencoding())
+            cfg.readfp(six.StringIO(config))
+        except configparser.Error:
+            return None
+        if not cfg.has_section('metadata') or not cfg.has_section('Setup'):
+            return None
+        return cfg
+
+    finally:
+        f.close()
+
+
+def get_exe_prefixes(exe_filename):
+    """Get exe->egg path translations for a given .exe file"""
+
+    prefixes = [
+        ('PURELIB/', ''),
+        ('PLATLIB/pywin32_system32', ''),
+        ('PLATLIB/', ''),
+        ('SCRIPTS/', 'EGG-INFO/scripts/'),
+        ('DATA/lib/site-packages', ''),
+    ]
+    z = zipfile.ZipFile(exe_filename)
+    try:
+        for info in z.infolist():
+            name = info.filename
+            parts = name.split('/')
+            if len(parts) == 3 and parts[2] == 'PKG-INFO':
+                if parts[1].endswith('.egg-info'):
+                    prefixes.insert(0, ('/'.join(parts[:2]), 'EGG-INFO/'))
+                    break
+            if len(parts) != 2 or not name.endswith('.pth'):
+                continue
+            if name.endswith('-nspkg.pth'):
+                continue
+            if parts[0].upper() in ('PURELIB', 'PLATLIB'):
+                contents = z.read(name)
+                if six.PY3:
+                    contents = contents.decode()
+                for pth in yield_lines(contents):
+                    pth = pth.strip().replace('\\', '/')
+                    if not pth.startswith('import'):
+                        prefixes.append((('%s/%s/' % (parts[0], pth)), ''))
+    finally:
+        z.close()
+    prefixes = [(x.lower(), y) for x, y in prefixes]
+    prefixes.sort()
+    prefixes.reverse()
+    return prefixes
+
+
+class PthDistributions(Environment):
+    """A .pth file with Distribution paths in it"""
+
+    dirty = False
+
+    def __init__(self, filename, sitedirs=()):
+        self.filename = filename
+        self.sitedirs = list(map(normalize_path, sitedirs))
+        self.basedir = normalize_path(os.path.dirname(self.filename))
+        self._load()
+        Environment.__init__(self, [], None, None)
+        for path in yield_lines(self.paths):
+            list(map(self.add, find_distributions(path, True)))
+
+    def _load(self):
+        self.paths = []
+        saw_import = False
+        seen = dict.fromkeys(self.sitedirs)
+        if os.path.isfile(self.filename):
+            f = open(self.filename, 'rt')
+            for line in f:
+                if line.startswith('import'):
+                    saw_import = True
+                    continue
+                path = line.rstrip()
+                self.paths.append(path)
+                if not path.strip() or path.strip().startswith('#'):
+                    continue
+                # skip non-existent paths, in case somebody deleted a package
+                # manually, and duplicate paths as well
+                path = self.paths[-1] = normalize_path(
+                    os.path.join(self.basedir, path)
+                )
+                if not os.path.exists(path) or path in seen:
+                    self.paths.pop()  # skip it
+                    self.dirty = True  # we cleaned up, so we're dirty now :)
+                    continue
+                seen[path] = 1
+            f.close()
+
+        if self.paths and not saw_import:
+            self.dirty = True  # ensure anything we touch has import wrappers
+        while self.paths and not self.paths[-1].strip():
+            self.paths.pop()
+
+    def save(self):
+        """Write changed .pth file back to disk"""
+        if not self.dirty:
+            return
+
+        rel_paths = list(map(self.make_relative, self.paths))
+        if rel_paths:
+            log.debug("Saving %s", self.filename)
+            lines = self._wrap_lines(rel_paths)
+            data = '\n'.join(lines) + '\n'
+
+            if os.path.islink(self.filename):
+                os.unlink(self.filename)
+            with open(self.filename, 'wt') as f:
+                f.write(data)
+
+        elif os.path.exists(self.filename):
+            log.debug("Deleting empty %s", self.filename)
+            os.unlink(self.filename)
+
+        self.dirty = False
+
+    @staticmethod
+    def _wrap_lines(lines):
+        return lines
+
+    def add(self, dist):
+        """Add `dist` to the distribution map"""
+        new_path = (
+            dist.location not in self.paths and (
+                dist.location not in self.sitedirs or
+                # account for '.' being in PYTHONPATH
+                dist.location == os.getcwd()
+            )
+        )
+        if new_path:
+            self.paths.append(dist.location)
+            self.dirty = True
+        Environment.add(self, dist)
+
+    def remove(self, dist):
+        """Remove `dist` from the distribution map"""
+        while dist.location in self.paths:
+            self.paths.remove(dist.location)
+            self.dirty = True
+        Environment.remove(self, dist)
+
+    def make_relative(self, path):
+        npath, last = os.path.split(normalize_path(path))
+        baselen = len(self.basedir)
+        parts = [last]
+        sep = os.altsep == '/' and '/' or os.sep
+        while len(npath) >= baselen:
+            if npath == self.basedir:
+                parts.append(os.curdir)
+                parts.reverse()
+                return sep.join(parts)
+            npath, last = os.path.split(npath)
+            parts.append(last)
+        else:
+            return path
+
+
+class RewritePthDistributions(PthDistributions):
+    @classmethod
+    def _wrap_lines(cls, lines):
+        yield cls.prelude
+        for line in lines:
+            yield line
+        yield cls.postlude
+
+    prelude = _one_liner("""
+        import sys
+        sys.__plen = len(sys.path)
+        """)
+    postlude = _one_liner("""
+        import sys
+        new = sys.path[sys.__plen:]
+        del sys.path[sys.__plen:]
+        p = getattr(sys, '__egginsert', 0)
+        sys.path[p:p] = new
+        sys.__egginsert = p + len(new)
+        """)
+
+
+if os.environ.get('SETUPTOOLS_SYS_PATH_TECHNIQUE', 'raw') == 'rewrite':
+    PthDistributions = RewritePthDistributions
+
+
+def _first_line_re():
+    """
+    Return a regular expression based on first_line_re suitable for matching
+    strings.
+    """
+    if isinstance(first_line_re.pattern, str):
+        return first_line_re
+
+    # first_line_re in Python >=3.1.4 and >=3.2.1 is a bytes pattern.
+    return re.compile(first_line_re.pattern.decode())
+
+
+def auto_chmod(func, arg, exc):
+    if func in [os.unlink, os.remove] and os.name == 'nt':
+        chmod(arg, stat.S_IWRITE)
+        return func(arg)
+    et, ev, _ = sys.exc_info()
+    six.reraise(et, (ev[0], ev[1] + (" %s %s" % (func, arg))))
+
+
+def update_dist_caches(dist_path, fix_zipimporter_caches):
+    """
+    Fix any globally cached `dist_path` related data
+
+    `dist_path` should be a path of a newly installed egg distribution (zipped
+    or unzipped).
+
+    sys.path_importer_cache contains finder objects that have been cached when
+    importing data from the original distribution. Any such finders need to be
+    cleared since the replacement distribution might be packaged differently,
+    e.g. a zipped egg distribution might get replaced with an unzipped egg
+    folder or vice versa. Having the old finders cached may then cause Python
+    to attempt loading modules from the replacement distribution using an
+    incorrect loader.
+
+    zipimport.zipimporter objects are Python loaders charged with importing
+    data packaged inside zip archives. If stale loaders referencing the
+    original distribution, are left behind, they can fail to load modules from
+    the replacement distribution. E.g. if an old zipimport.zipimporter instance
+    is used to load data from a new zipped egg archive, it may cause the
+    operation to attempt to locate the requested data in the wrong location -
+    one indicated by the original distribution's zip archive directory
+    information. Such an operation may then fail outright, e.g. report having
+    read a 'bad local file header', or even worse, it may fail silently &
+    return invalid data.
+
+    zipimport._zip_directory_cache contains cached zip archive directory
+    information for all existing zipimport.zipimporter instances and all such
+    instances connected to the same archive share the same cached directory
+    information.
+
+    If asked, and the underlying Python implementation allows it, we can fix
+    all existing zipimport.zipimporter instances instead of having to track
+    them down and remove them one by one, by updating their shared cached zip
+    archive directory information. This, of course, assumes that the
+    replacement distribution is packaged as a zipped egg.
+
+    If not asked to fix existing zipimport.zipimporter instances, we still do
+    our best to clear any remaining zipimport.zipimporter related cached data
+    that might somehow later get used when attempting to load data from the new
+    distribution and thus cause such load operations to fail. Note that when
+    tracking down such remaining stale data, we can not catch every conceivable
+    usage from here, and we clear only those that we know of and have found to
+    cause problems if left alive. Any remaining caches should be updated by
+    whomever is in charge of maintaining them, i.e. they should be ready to
+    handle us replacing their zip archives with new distributions at runtime.
+
+    """
+    # There are several other known sources of stale zipimport.zipimporter
+    # instances that we do not clear here, but might if ever given a reason to
+    # do so:
+    # * Global setuptools pkg_resources.working_set (a.k.a. 'master working
+    # set') may contain distributions which may in turn contain their
+    #   zipimport.zipimporter loaders.
+    # * Several zipimport.zipimporter loaders held by local variables further
+    #   up the function call stack when running the setuptools installation.
+    # * Already loaded modules may have their __loader__ attribute set to the
+    #   exact loader instance used when importing them. Python 3.4 docs state
+    #   that this information is intended mostly for introspection and so is
+    #   not expected to cause us problems.
+    normalized_path = normalize_path(dist_path)
+    _uncache(normalized_path, sys.path_importer_cache)
+    if fix_zipimporter_caches:
+        _replace_zip_directory_cache_data(normalized_path)
+    else:
+        # Here, even though we do not want to fix existing and now stale
+        # zipimporter cache information, we still want to remove it. Related to
+        # Python's zip archive directory information cache, we clear each of
+        # its stale entries in two phases:
+        #   1. Clear the entry so attempting to access zip archive information
+        #      via any existing stale zipimport.zipimporter instances fails.
+        #   2. Remove the entry from the cache so any newly constructed
+        #      zipimport.zipimporter instances do not end up using old stale
+        #      zip archive directory information.
+        # This whole stale data removal step does not seem strictly necessary,
+        # but has been left in because it was done before we started replacing
+        # the zip archive directory information cache content if possible, and
+        # there are no relevant unit tests that we can depend on to tell us if
+        # this is really needed.
+        _remove_and_clear_zip_directory_cache_data(normalized_path)
+
+
+def _collect_zipimporter_cache_entries(normalized_path, cache):
+    """
+    Return zipimporter cache entry keys related to a given normalized path.
+
+    Alternative path spellings (e.g. those using different character case or
+    those using alternative path separators) related to the same path are
+    included. Any sub-path entries are included as well, i.e. those
+    corresponding to zip archives embedded in other zip archives.
+
+    """
+    result = []
+    prefix_len = len(normalized_path)
+    for p in cache:
+        np = normalize_path(p)
+        if (np.startswith(normalized_path) and
+                np[prefix_len:prefix_len + 1] in (os.sep, '')):
+            result.append(p)
+    return result
+
+
+def _update_zipimporter_cache(normalized_path, cache, updater=None):
+    """
+    Update zipimporter cache data for a given normalized path.
+
+    Any sub-path entries are processed as well, i.e. those corresponding to zip
+    archives embedded in other zip archives.
+
+    Given updater is a callable taking a cache entry key and the original entry
+    (after already removing the entry from the cache), and expected to update
+    the entry and possibly return a new one to be inserted in its place.
+    Returning None indicates that the entry should not be replaced with a new
+    one. If no updater is given, the cache entries are simply removed without
+    any additional processing, the same as if the updater simply returned None.
+
+    """
+    for p in _collect_zipimporter_cache_entries(normalized_path, cache):
+        # N.B. pypy's custom zipimport._zip_directory_cache implementation does
+        # not support the complete dict interface:
+        # * Does not support item assignment, thus not allowing this function
+        #    to be used only for removing existing cache entries.
+        #  * Does not support the dict.pop() method, forcing us to use the
+        #    get/del patterns instead. For more detailed information see the
+        #    following links:
+        #      https://github.com/pypa/setuptools/issues/202#issuecomment-202913420
+        #      http://bit.ly/2h9itJX
+        old_entry = cache[p]
+        del cache[p]
+        new_entry = updater and updater(p, old_entry)
+        if new_entry is not None:
+            cache[p] = new_entry
+
+
+def _uncache(normalized_path, cache):
+    _update_zipimporter_cache(normalized_path, cache)
+
+
+def _remove_and_clear_zip_directory_cache_data(normalized_path):
+    def clear_and_remove_cached_zip_archive_directory_data(path, old_entry):
+        old_entry.clear()
+
+    _update_zipimporter_cache(
+        normalized_path, zipimport._zip_directory_cache,
+        updater=clear_and_remove_cached_zip_archive_directory_data)
+
+
+# PyPy Python implementation does not allow directly writing to the
+# zipimport._zip_directory_cache and so prevents us from attempting to correct
+# its content. The best we can do there is clear the problematic cache content
+# and have PyPy repopulate it as needed. The downside is that if there are any
+# stale zipimport.zipimporter instances laying around, attempting to use them
+# will fail due to not having its zip archive directory information available
+# instead of being automatically corrected to use the new correct zip archive
+# directory information.
+if '__pypy__' in sys.builtin_module_names:
+    _replace_zip_directory_cache_data = \
+        _remove_and_clear_zip_directory_cache_data
+else:
+
+    def _replace_zip_directory_cache_data(normalized_path):
+        def replace_cached_zip_archive_directory_data(path, old_entry):
+            # N.B. In theory, we could load the zip directory information just
+            # once for all updated path spellings, and then copy it locally and
+            # update its contained path strings to contain the correct
+            # spelling, but that seems like a way too invasive move (this cache
+            # structure is not officially documented anywhere and could in
+            # theory change with new Python releases) for no significant
+            # benefit.
+            old_entry.clear()
+            zipimport.zipimporter(path)
+            old_entry.update(zipimport._zip_directory_cache[path])
+            return old_entry
+
+        _update_zipimporter_cache(
+            normalized_path, zipimport._zip_directory_cache,
+            updater=replace_cached_zip_archive_directory_data)
+
+
+def is_python(text, filename='<string>'):
+    "Is this string a valid Python script?"
+    try:
+        compile(text, filename, 'exec')
+    except (SyntaxError, TypeError):
+        return False
+    else:
+        return True
+
+
+def is_sh(executable):
+    """Determine if the specified executable is a .sh (contains a #! line)"""
+    try:
+        with io.open(executable, encoding='latin-1') as fp:
+            magic = fp.read(2)
+    except (OSError, IOError):
+        return executable
+    return magic == '#!'
+
+
+def nt_quote_arg(arg):
+    """Quote a command line argument according to Windows parsing rules"""
+    return subprocess.list2cmdline([arg])
+
+
+def is_python_script(script_text, filename):
+    """Is this text, as a whole, a Python script? (as opposed to shell/bat/etc.
+    """
+    if filename.endswith('.py') or filename.endswith('.pyw'):
+        return True  # extension says it's Python
+    if is_python(script_text, filename):
+        return True  # it's syntactically valid Python
+    if script_text.startswith('#!'):
+        # It begins with a '#!' line, so check if 'python' is in it somewhere
+        return 'python' in script_text.splitlines()[0].lower()
+
+    return False  # Not any Python I can recognize
+
+
+try:
+    from os import chmod as _chmod
+except ImportError:
+    # Jython compatibility
+    def _chmod(*args):
+        pass
+
+
+def chmod(path, mode):
+    log.debug("changing mode of %s to %o", path, mode)
+    try:
+        _chmod(path, mode)
+    except os.error as e:
+        log.debug("chmod failed: %s", e)
+
+
+class CommandSpec(list):
+    """
+    A command spec for a #! header, specified as a list of arguments akin to
+    those passed to Popen.
+    """
+
+    options = []
+    split_args = dict()
+
+    @classmethod
+    def best(cls):
+        """
+        Choose the best CommandSpec class based on environmental conditions.
+        """
+        return cls
+
+    @classmethod
+    def _sys_executable(cls):
+        _default = os.path.normpath(sys.executable)
+        return os.environ.get('__PYVENV_LAUNCHER__', _default)
+
+    @classmethod
+    def from_param(cls, param):
+        """
+        Construct a CommandSpec from a parameter to build_scripts, which may
+        be None.
+        """
+        if isinstance(param, cls):
+            return param
+        if isinstance(param, list):
+            return cls(param)
+        if param is None:
+            return cls.from_environment()
+        # otherwise, assume it's a string.
+        return cls.from_string(param)
+
+    @classmethod
+    def from_environment(cls):
+        return cls([cls._sys_executable()])
+
+    @classmethod
+    def from_string(cls, string):
+        """
+        Construct a command spec from a simple string representing a command
+        line parseable by shlex.split.
+        """
+        items = shlex.split(string, **cls.split_args)
+        return cls(items)
+
+    def install_options(self, script_text):
+        self.options = shlex.split(self._extract_options(script_text))
+        cmdline = subprocess.list2cmdline(self)
+        if not isascii(cmdline):
+            self.options[:0] = ['-x']
+
+    @staticmethod
+    def _extract_options(orig_script):
+        """
+        Extract any options from the first line of the script.
+        """
+        first = (orig_script + '\n').splitlines()[0]
+        match = _first_line_re().match(first)
+        options = match.group(1) or '' if match else ''
+        return options.strip()
+
+    def as_header(self):
+        return self._render(self + list(self.options))
+
+    @staticmethod
+    def _strip_quotes(item):
+        _QUOTES = '"\''
+        for q in _QUOTES:
+            if item.startswith(q) and item.endswith(q):
+                return item[1:-1]
+        return item
+
+    @staticmethod
+    def _render(items):
+        cmdline = subprocess.list2cmdline(
+            CommandSpec._strip_quotes(item.strip()) for item in items)
+        return '#!' + cmdline + '\n'
+
+
+# For pbr compat; will be removed in a future version.
+sys_executable = CommandSpec._sys_executable()
+
+
+class WindowsCommandSpec(CommandSpec):
+    split_args = dict(posix=False)
+
+
+class ScriptWriter(object):
+    """
+    Encapsulates behavior around writing entry point scripts for console and
+    gui apps.
+    """
+
+    template = textwrap.dedent(r"""
+        # EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r
+        __requires__ = %(spec)r
+        import re
+        import sys
+        from pkg_resources import load_entry_point
+
+        if __name__ == '__main__':
+            sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
+            sys.exit(
+                load_entry_point(%(spec)r, %(group)r, %(name)r)()
+            )
+    """).lstrip()
+
+    command_spec_class = CommandSpec
+
+    @classmethod
+    def get_script_args(cls, dist, executable=None, wininst=False):
+        # for backward compatibility
+        warnings.warn("Use get_args", DeprecationWarning)
+        writer = (WindowsScriptWriter if wininst else ScriptWriter).best()
+        header = cls.get_script_header("", executable, wininst)
+        return writer.get_args(dist, header)
+
+    @classmethod
+    def get_script_header(cls, script_text, executable=None, wininst=False):
+        # for backward compatibility
+        warnings.warn("Use get_header", DeprecationWarning)
+        if wininst:
+            executable = "python.exe"
+        cmd = cls.command_spec_class.best().from_param(executable)
+        cmd.install_options(script_text)
+        return cmd.as_header()
+
+    @classmethod
+    def get_args(cls, dist, header=None):
+        """
+        Yield write_script() argument tuples for a distribution's
+        console_scripts and gui_scripts entry points.
+        """
+        if header is None:
+            header = cls.get_header()
+        spec = str(dist.as_requirement())
+        for type_ in 'console', 'gui':
+            group = type_ + '_scripts'
+            for name, ep in dist.get_entry_map(group).items():
+                cls._ensure_safe_name(name)
+                script_text = cls.template % locals()
+                args = cls._get_script_args(type_, name, header, script_text)
+                for res in args:
+                    yield res
+
+    @staticmethod
+    def _ensure_safe_name(name):
+        """
+        Prevent paths in *_scripts entry point names.
+        """
+        has_path_sep = re.search(r'[\\/]', name)
+        if has_path_sep:
+            raise ValueError("Path separators not allowed in script names")
+
+    @classmethod
+    def get_writer(cls, force_windows):
+        # for backward compatibility
+        warnings.warn("Use best", DeprecationWarning)
+        return WindowsScriptWriter.best() if force_windows else cls.best()
+
+    @classmethod
+    def best(cls):
+        """
+        Select the best ScriptWriter for this environment.
+        """
+        if sys.platform == 'win32' or (os.name == 'java' and os._name == 'nt'):
+            return WindowsScriptWriter.best()
+        else:
+            return cls
+
+    @classmethod
+    def _get_script_args(cls, type_, name, header, script_text):
+        # Simply write the stub with no extension.
+        yield (name, header + script_text)
+
+    @classmethod
+    def get_header(cls, script_text="", executable=None):
+        """Create a #! line, getting options (if any) from script_text"""
+        cmd = cls.command_spec_class.best().from_param(executable)
+        cmd.install_options(script_text)
+        return cmd.as_header()
+
+
+class WindowsScriptWriter(ScriptWriter):
+    command_spec_class = WindowsCommandSpec
+
+    @classmethod
+    def get_writer(cls):
+        # for backward compatibility
+        warnings.warn("Use best", DeprecationWarning)
+        return cls.best()
+
+    @classmethod
+    def best(cls):
+        """
+        Select the best ScriptWriter suitable for Windows
+        """
+        writer_lookup = dict(
+            executable=WindowsExecutableLauncherWriter,
+            natural=cls,
+        )
+        # for compatibility, use the executable launcher by default
+        launcher = os.environ.get('SETUPTOOLS_LAUNCHER', 'executable')
+        return writer_lookup[launcher]
+
+    @classmethod
+    def _get_script_args(cls, type_, name, header, script_text):
+        "For Windows, add a .py extension"
+        ext = dict(console='.pya', gui='.pyw')[type_]
+        if ext not in os.environ['PATHEXT'].lower().split(';'):
+            msg = (
+                "{ext} not listed in PATHEXT; scripts will not be "
+                "recognized as executables."
+            ).format(**locals())
+            warnings.warn(msg, UserWarning)
+        old = ['.pya', '.py', '-script.py', '.pyc', '.pyo', '.pyw', '.exe']
+        old.remove(ext)
+        header = cls._adjust_header(type_, header)
+        blockers = [name + x for x in old]
+        yield name + ext, header + script_text, 't', blockers
+
+    @classmethod
+    def _adjust_header(cls, type_, orig_header):
+        """
+        Make sure 'pythonw' is used for gui and and 'python' is used for
+        console (regardless of what sys.executable is).
+        """
+        pattern = 'pythonw.exe'
+        repl = 'python.exe'
+        if type_ == 'gui':
+            pattern, repl = repl, pattern
+        pattern_ob = re.compile(re.escape(pattern), re.IGNORECASE)
+        new_header = pattern_ob.sub(string=orig_header, repl=repl)
+        return new_header if cls._use_header(new_header) else orig_header
+
+    @staticmethod
+    def _use_header(new_header):
+        """
+        Should _adjust_header use the replaced header?
+
+        On non-windows systems, always use. On
+        Windows systems, only use the replaced header if it resolves
+        to an executable on the system.
+        """
+        clean_header = new_header[2:-1].strip('"')
+        return sys.platform != 'win32' or find_executable(clean_header)
+
+
+class WindowsExecutableLauncherWriter(WindowsScriptWriter):
+    @classmethod
+    def _get_script_args(cls, type_, name, header, script_text):
+        """
+        For Windows, add a .py extension and an .exe launcher
+        """
+        if type_ == 'gui':
+            launcher_type = 'gui'
+            ext = '-script.pyw'
+            old = ['.pyw']
+        else:
+            launcher_type = 'cli'
+            ext = '-script.py'
+            old = ['.py', '.pyc', '.pyo']
+        hdr = cls._adjust_header(type_, header)
+        blockers = [name + x for x in old]
+        yield (name + ext, hdr + script_text, 't', blockers)
+        yield (
+            name + '.exe', get_win_launcher(launcher_type),
+            'b'  # write in binary mode
+        )
+        if not is_64bit():
+            # install a manifest for the launcher to prevent Windows
+            # from detecting it as an installer (which it will for
+            #  launchers like easy_install.exe). Consider only
+            #  adding a manifest for launchers detected as installers.
+            #  See Distribute #143 for details.
+            m_name = name + '.exe.manifest'
+            yield (m_name, load_launcher_manifest(name), 't')
+
+
+# for backward-compatibility
+get_script_args = ScriptWriter.get_script_args
+get_script_header = ScriptWriter.get_script_header
+
+
+def get_win_launcher(type):
+    """
+    Load the Windows launcher (executable) suitable for launching a script.
+
+    `type` should be either 'cli' or 'gui'
+
+    Returns the executable as a byte string.
+    """
+    launcher_fn = '%s.exe' % type
+    if is_64bit():
+        launcher_fn = launcher_fn.replace(".", "-64.")
+    else:
+        launcher_fn = launcher_fn.replace(".", "-32.")
+    return resource_string('setuptools', launcher_fn)
+
+
+def load_launcher_manifest(name):
+    manifest = pkg_resources.resource_string(__name__, 'launcher manifest.xml')
+    if six.PY2:
+        return manifest % vars()
+    else:
+        return manifest.decode('utf-8') % vars()
+
+
+def rmtree(path, ignore_errors=False, onerror=auto_chmod):
+    return shutil.rmtree(path, ignore_errors, onerror)
+
+
+def current_umask():
+    tmp = os.umask(0o022)
+    os.umask(tmp)
+    return tmp
+
+
+def bootstrap():
+    # This function is called when setuptools*.egg is run using /bin/sh
+    import setuptools
+
+    argv0 = os.path.dirname(setuptools.__path__[0])
+    sys.argv[0] = argv0
+    sys.argv.append(argv0)
+    main()
+
+
+def main(argv=None, **kw):
+    from setuptools import setup
+    from setuptools.dist import Distribution
+
+    class DistributionWithoutHelpCommands(Distribution):
+        common_usage = ""
+
+        def _show_help(self, *args, **kw):
+            with _patch_usage():
+                Distribution._show_help(self, *args, **kw)
+
+    if argv is None:
+        argv = sys.argv[1:]
+
+    with _patch_usage():
+        setup(
+            script_args=['-q', 'easy_install', '-v'] + argv,
+            script_name=sys.argv[0] or 'easy_install',
+            distclass=DistributionWithoutHelpCommands,
+            **kw
+        )
+
+
+@contextlib.contextmanager
+def _patch_usage():
+    import distutils.core
+    USAGE = textwrap.dedent("""
+        usage: %(script)s [options] requirement_or_url ...
+           or: %(script)s --help
+        """).lstrip()
+
+    def gen_usage(script_name):
+        return USAGE % dict(
+            script=os.path.basename(script_name),
+        )
+
+    saved = distutils.core.gen_usage
+    distutils.core.gen_usage = gen_usage
+    try:
+        yield
+    finally:
+        distutils.core.gen_usage = saved
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/egg_info.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/egg_info.py
new file mode 100644
index 00000000..f3e604d3
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/egg_info.py
@@ -0,0 +1,696 @@
+"""setuptools.command.egg_info
+
+Create a distribution's .egg-info directory and contents"""
+
+from distutils.filelist import FileList as _FileList
+from distutils.errors import DistutilsInternalError
+from distutils.util import convert_path
+from distutils import log
+import distutils.errors
+import distutils.filelist
+import os
+import re
+import sys
+import io
+import warnings
+import time
+import collections
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import map
+
+from setuptools import Command
+from setuptools.command.sdist import sdist
+from setuptools.command.sdist import walk_revctrl
+from setuptools.command.setopt import edit_config
+from setuptools.command import bdist_egg
+from pkg_resources import (
+    parse_requirements, safe_name, parse_version,
+    safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename)
+import setuptools.unicode_utils as unicode_utils
+from setuptools.glob import glob
+
+from setuptools.extern import packaging
+
+
+def translate_pattern(glob):
+    """
+    Translate a file path glob like '*.txt' in to a regular expression.
+    This differs from fnmatch.translate which allows wildcards to match
+    directory separators. It also knows about '**/' which matches any number of
+    directories.
+    """
+    pat = ''
+
+    # This will split on '/' within [character classes]. This is deliberate.
+    chunks = glob.split(os.path.sep)
+
+    sep = re.escape(os.sep)
+    valid_char = '[^%s]' % (sep,)
+
+    for c, chunk in enumerate(chunks):
+        last_chunk = c == len(chunks) - 1
+
+        # Chunks that are a literal ** are globstars. They match anything.
+        if chunk == '**':
+            if last_chunk:
+                # Match anything if this is the last component
+                pat += '.*'
+            else:
+                # Match '(name/)*'
+                pat += '(?:%s+%s)*' % (valid_char, sep)
+            continue  # Break here as the whole path component has been handled
+
+        # Find any special characters in the remainder
+        i = 0
+        chunk_len = len(chunk)
+        while i < chunk_len:
+            char = chunk[i]
+            if char == '*':
+                # Match any number of name characters
+                pat += valid_char + '*'
+            elif char == '?':
+                # Match a name character
+                pat += valid_char
+            elif char == '[':
+                # Character class
+                inner_i = i + 1
+                # Skip initial !/] chars
+                if inner_i < chunk_len and chunk[inner_i] == '!':
+                    inner_i = inner_i + 1
+                if inner_i < chunk_len and chunk[inner_i] == ']':
+                    inner_i = inner_i + 1
+
+                # Loop till the closing ] is found
+                while inner_i < chunk_len and chunk[inner_i] != ']':
+                    inner_i = inner_i + 1
+
+                if inner_i >= chunk_len:
+                    # Got to the end of the string without finding a closing ]
+                    # Do not treat this as a matching group, but as a literal [
+                    pat += re.escape(char)
+                else:
+                    # Grab the insides of the [brackets]
+                    inner = chunk[i + 1:inner_i]
+                    char_class = ''
+
+                    # Class negation
+                    if inner[0] == '!':
+                        char_class = '^'
+                        inner = inner[1:]
+
+                    char_class += re.escape(inner)
+                    pat += '[%s]' % (char_class,)
+
+                    # Skip to the end ]
+                    i = inner_i
+            else:
+                pat += re.escape(char)
+            i += 1
+
+        # Join each chunk with the dir separator
+        if not last_chunk:
+            pat += sep
+
+    pat += r'\Z'
+    return re.compile(pat, flags=re.MULTILINE|re.DOTALL)
+
+
+class egg_info(Command):
+    description = "create a distribution's .egg-info directory"
+
+    user_options = [
+        ('egg-base=', 'e', "directory containing .egg-info directories"
+                           " (default: top of the source tree)"),
+        ('tag-date', 'd', "Add date stamp (e.g. 20050528) to version number"),
+        ('tag-build=', 'b', "Specify explicit tag to add to version number"),
+        ('no-date', 'D', "Don't include date stamp [default]"),
+    ]
+
+    boolean_options = ['tag-date']
+    negative_opt = {
+        'no-date': 'tag-date',
+    }
+
+    def initialize_options(self):
+        self.egg_name = None
+        self.egg_version = None
+        self.egg_base = None
+        self.egg_info = None
+        self.tag_build = None
+        self.tag_date = 0
+        self.broken_egg_info = False
+        self.vtags = None
+
+    ####################################
+    # allow the 'tag_svn_revision' to be detected and
+    # set, supporting sdists built on older Setuptools.
+    @property
+    def tag_svn_revision(self):
+        pass
+
+    @tag_svn_revision.setter
+    def tag_svn_revision(self, value):
+        pass
+    ####################################
+
+    def save_version_info(self, filename):
+        """
+        Materialize the value of date into the
+        build tag. Install build keys in a deterministic order
+        to avoid arbitrary reordering on subsequent builds.
+        """
+        egg_info = collections.OrderedDict()
+        # follow the order these keys would have been added
+        # when PYTHONHASHSEED=0
+        egg_info['tag_build'] = self.tags()
+        egg_info['tag_date'] = 0
+        edit_config(filename, dict(egg_info=egg_info))
+
+    def finalize_options(self):
+        self.egg_name = safe_name(self.distribution.get_name())
+        self.vtags = self.tags()
+        self.egg_version = self.tagged_version()
+
+        parsed_version = parse_version(self.egg_version)
+
+        try:
+            is_version = isinstance(parsed_version, packaging.version.Version)
+            spec = (
+                "%s==%s" if is_version else "%s===%s"
+            )
+            list(
+                parse_requirements(spec % (self.egg_name, self.egg_version))
+            )
+        except ValueError:
+            raise distutils.errors.DistutilsOptionError(
+                "Invalid distribution name or version syntax: %s-%s" %
+                (self.egg_name, self.egg_version)
+            )
+
+        if self.egg_base is None:
+            dirs = self.distribution.package_dir
+            self.egg_base = (dirs or {}).get('', os.curdir)
+
+        self.ensure_dirname('egg_base')
+        self.egg_info = to_filename(self.egg_name) + '.egg-info'
+        if self.egg_base != os.curdir:
+            self.egg_info = os.path.join(self.egg_base, self.egg_info)
+        if '-' in self.egg_name:
+            self.check_broken_egg_info()
+
+        # Set package version for the benefit of dumber commands
+        # (e.g. sdist, bdist_wininst, etc.)
+        #
+        self.distribution.metadata.version = self.egg_version
+
+        # If we bootstrapped around the lack of a PKG-INFO, as might be the
+        # case in a fresh checkout, make sure that any special tags get added
+        # to the version info
+        #
+        pd = self.distribution._patched_dist
+        if pd is not None and pd.key == self.egg_name.lower():
+            pd._version = self.egg_version
+            pd._parsed_version = parse_version(self.egg_version)
+            self.distribution._patched_dist = None
+
+    def write_or_delete_file(self, what, filename, data, force=False):
+        """Write `data` to `filename` or delete if empty
+
+        If `data` is non-empty, this routine is the same as ``write_file()``.
+        If `data` is empty but not ``None``, this is the same as calling
+        ``delete_file(filename)`.  If `data` is ``None``, then this is a no-op
+        unless `filename` exists, in which case a warning is issued about the
+        orphaned file (if `force` is false), or deleted (if `force` is true).
+        """
+        if data:
+            self.write_file(what, filename, data)
+        elif os.path.exists(filename):
+            if data is None and not force:
+                log.warn(
+                    "%s not set in setup(), but %s exists", what, filename
+                )
+                return
+            else:
+                self.delete_file(filename)
+
+    def write_file(self, what, filename, data):
+        """Write `data` to `filename` (if not a dry run) after announcing it
+
+        `what` is used in a log message to identify what is being written
+        to the file.
+        """
+        log.info("writing %s to %s", what, filename)
+        if six.PY3:
+            data = data.encode("utf-8")
+        if not self.dry_run:
+            f = open(filename, 'wb')
+            f.write(data)
+            f.close()
+
+    def delete_file(self, filename):
+        """Delete `filename` (if not a dry run) after announcing it"""
+        log.info("deleting %s", filename)
+        if not self.dry_run:
+            os.unlink(filename)
+
+    def tagged_version(self):
+        version = self.distribution.get_version()
+        # egg_info may be called more than once for a distribution,
+        # in which case the version string already contains all tags.
+        if self.vtags and version.endswith(self.vtags):
+            return safe_version(version)
+        return safe_version(version + self.vtags)
+
+    def run(self):
+        self.mkpath(self.egg_info)
+        installer = self.distribution.fetch_build_egg
+        for ep in iter_entry_points('egg_info.writers'):
+            ep.require(installer=installer)
+            writer = ep.resolve()
+            writer(self, ep.name, os.path.join(self.egg_info, ep.name))
+
+        # Get rid of native_libs.txt if it was put there by older bdist_egg
+        nl = os.path.join(self.egg_info, "native_libs.txt")
+        if os.path.exists(nl):
+            self.delete_file(nl)
+
+        self.find_sources()
+
+    def tags(self):
+        version = ''
+        if self.tag_build:
+            version += self.tag_build
+        if self.tag_date:
+            version += time.strftime("-%Y%m%d")
+        return version
+
+    def find_sources(self):
+        """Generate SOURCES.txt manifest file"""
+        manifest_filename = os.path.join(self.egg_info, "SOURCES.txt")
+        mm = manifest_maker(self.distribution)
+        mm.manifest = manifest_filename
+        mm.run()
+        self.filelist = mm.filelist
+
+    def check_broken_egg_info(self):
+        bei = self.egg_name + '.egg-info'
+        if self.egg_base != os.curdir:
+            bei = os.path.join(self.egg_base, bei)
+        if os.path.exists(bei):
+            log.warn(
+                "-" * 78 + '\n'
+                "Note: Your current .egg-info directory has a '-' in its name;"
+                '\nthis will not work correctly with "setup.py develop".\n\n'
+                'Please rename %s to %s to correct this problem.\n' + '-' * 78,
+                bei, self.egg_info
+            )
+            self.broken_egg_info = self.egg_info
+            self.egg_info = bei  # make it work for now
+
+
+class FileList(_FileList):
+    # Implementations of the various MANIFEST.in commands
+
+    def process_template_line(self, line):
+        # Parse the line: split it up, make sure the right number of words
+        # is there, and return the relevant words.  'action' is always
+        # defined: it's the first word of the line.  Which of the other
+        # three are defined depends on the action; it'll be either
+        # patterns, (dir and patterns), or (dir_pattern).
+        (action, patterns, dir, dir_pattern) = self._parse_template_line(line)
+
+        # OK, now we know that the action is valid and we have the
+        # right number of words on the line for that action -- so we
+        # can proceed with minimal error-checking.
+        if action == 'include':
+            self.debug_print("include " + ' '.join(patterns))
+            for pattern in patterns:
+                if not self.include(pattern):
+                    log.warn("warning: no files found matching '%s'", pattern)
+
+        elif action == 'exclude':
+            self.debug_print("exclude " + ' '.join(patterns))
+            for pattern in patterns:
+                if not self.exclude(pattern):
+                    log.warn(("warning: no previously-included files "
+                              "found matching '%s'"), pattern)
+
+        elif action == 'global-include':
+            self.debug_print("global-include " + ' '.join(patterns))
+            for pattern in patterns:
+                if not self.global_include(pattern):
+                    log.warn(("warning: no files found matching '%s' "
+                              "anywhere in distribution"), pattern)
+
+        elif action == 'global-exclude':
+            self.debug_print("global-exclude " + ' '.join(patterns))
+            for pattern in patterns:
+                if not self.global_exclude(pattern):
+                    log.warn(("warning: no previously-included files matching "
+                              "'%s' found anywhere in distribution"),
+                             pattern)
+
+        elif action == 'recursive-include':
+            self.debug_print("recursive-include %s %s" %
+                             (dir, ' '.join(patterns)))
+            for pattern in patterns:
+                if not self.recursive_include(dir, pattern):
+                    log.warn(("warning: no files found matching '%s' "
+                              "under directory '%s'"),
+                             pattern, dir)
+
+        elif action == 'recursive-exclude':
+            self.debug_print("recursive-exclude %s %s" %
+                             (dir, ' '.join(patterns)))
+            for pattern in patterns:
+                if not self.recursive_exclude(dir, pattern):
+                    log.warn(("warning: no previously-included files matching "
+                              "'%s' found under directory '%s'"),
+                             pattern, dir)
+
+        elif action == 'graft':
+            self.debug_print("graft " + dir_pattern)
+            if not self.graft(dir_pattern):
+                log.warn("warning: no directories found matching '%s'",
+                         dir_pattern)
+
+        elif action == 'prune':
+            self.debug_print("prune " + dir_pattern)
+            if not self.prune(dir_pattern):
+                log.warn(("no previously-included directories found "
+                          "matching '%s'"), dir_pattern)
+
+        else:
+            raise DistutilsInternalError(
+                "this cannot happen: invalid action '%s'" % action)
+
+    def _remove_files(self, predicate):
+        """
+        Remove all files from the file list that match the predicate.
+        Return True if any matching files were removed
+        """
+        found = False
+        for i in range(len(self.files) - 1, -1, -1):
+            if predicate(self.files[i]):
+                self.debug_print(" removing " + self.files[i])
+                del self.files[i]
+                found = True
+        return found
+
+    def include(self, pattern):
+        """Include files that match 'pattern'."""
+        found = [f for f in glob(pattern) if not os.path.isdir(f)]
+        self.extend(found)
+        return bool(found)
+
+    def exclude(self, pattern):
+        """Exclude files that match 'pattern'."""
+        match = translate_pattern(pattern)
+        return self._remove_files(match.match)
+
+    def recursive_include(self, dir, pattern):
+        """
+        Include all files anywhere in 'dir/' that match the pattern.
+        """
+        full_pattern = os.path.join(dir, '**', pattern)
+        found = [f for f in glob(full_pattern, recursive=True)
+                 if not os.path.isdir(f)]
+        self.extend(found)
+        return bool(found)
+
+    def recursive_exclude(self, dir, pattern):
+        """
+        Exclude any file anywhere in 'dir/' that match the pattern.
+        """
+        match = translate_pattern(os.path.join(dir, '**', pattern))
+        return self._remove_files(match.match)
+
+    def graft(self, dir):
+        """Include all files from 'dir/'."""
+        found = [
+            item
+            for match_dir in glob(dir)
+            for item in distutils.filelist.findall(match_dir)
+        ]
+        self.extend(found)
+        return bool(found)
+
+    def prune(self, dir):
+        """Filter out files from 'dir/'."""
+        match = translate_pattern(os.path.join(dir, '**'))
+        return self._remove_files(match.match)
+
+    def global_include(self, pattern):
+        """
+        Include all files anywhere in the current directory that match the
+        pattern. This is very inefficient on large file trees.
+        """
+        if self.allfiles is None:
+            self.findall()
+        match = translate_pattern(os.path.join('**', pattern))
+        found = [f for f in self.allfiles if match.match(f)]
+        self.extend(found)
+        return bool(found)
+
+    def global_exclude(self, pattern):
+        """
+        Exclude all files anywhere that match the pattern.
+        """
+        match = translate_pattern(os.path.join('**', pattern))
+        return self._remove_files(match.match)
+
+    def append(self, item):
+        if item.endswith('\r'):  # Fix older sdists built on Windows
+            item = item[:-1]
+        path = convert_path(item)
+
+        if self._safe_path(path):
+            self.files.append(path)
+
+    def extend(self, paths):
+        self.files.extend(filter(self._safe_path, paths))
+
+    def _repair(self):
+        """
+        Replace self.files with only safe paths
+
+        Because some owners of FileList manipulate the underlying
+        ``files`` attribute directly, this method must be called to
+        repair those paths.
+        """
+        self.files = list(filter(self._safe_path, self.files))
+
+    def _safe_path(self, path):
+        enc_warn = "'%s' not %s encodable -- skipping"
+
+        # To avoid accidental trans-codings errors, first to unicode
+        u_path = unicode_utils.filesys_decode(path)
+        if u_path is None:
+            log.warn("'%s' in unexpected encoding -- skipping" % path)
+            return False
+
+        # Must ensure utf-8 encodability
+        utf8_path = unicode_utils.try_encode(u_path, "utf-8")
+        if utf8_path is None:
+            log.warn(enc_warn, path, 'utf-8')
+            return False
+
+        try:
+            # accept is either way checks out
+            if os.path.exists(u_path) or os.path.exists(utf8_path):
+                return True
+        # this will catch any encode errors decoding u_path
+        except UnicodeEncodeError:
+            log.warn(enc_warn, path, sys.getfilesystemencoding())
+
+
+class manifest_maker(sdist):
+    template = "MANIFEST.in"
+
+    def initialize_options(self):
+        self.use_defaults = 1
+        self.prune = 1
+        self.manifest_only = 1
+        self.force_manifest = 1
+
+    def finalize_options(self):
+        pass
+
+    def run(self):
+        self.filelist = FileList()
+        if not os.path.exists(self.manifest):
+            self.write_manifest()  # it must exist so it'll get in the list
+        self.add_defaults()
+        if os.path.exists(self.template):
+            self.read_template()
+        self.prune_file_list()
+        self.filelist.sort()
+        self.filelist.remove_duplicates()
+        self.write_manifest()
+
+    def _manifest_normalize(self, path):
+        path = unicode_utils.filesys_decode(path)
+        return path.replace(os.sep, '/')
+
+    def write_manifest(self):
+        """
+        Write the file list in 'self.filelist' to the manifest file
+        named by 'self.manifest'.
+        """
+        self.filelist._repair()
+
+        # Now _repairs should encodability, but not unicode
+        files = [self._manifest_normalize(f) for f in self.filelist.files]
+        msg = "writing manifest file '%s'" % self.manifest
+        self.execute(write_file, (self.manifest, files), msg)
+
+    def warn(self, msg):
+        if not self._should_suppress_warning(msg):
+            sdist.warn(self, msg)
+
+    @staticmethod
+    def _should_suppress_warning(msg):
+        """
+        suppress missing-file warnings from sdist
+        """
+        return re.match(r"standard file .*not found", msg)
+
+    def add_defaults(self):
+        sdist.add_defaults(self)
+        self.filelist.append(self.template)
+        self.filelist.append(self.manifest)
+        rcfiles = list(walk_revctrl())
+        if rcfiles:
+            self.filelist.extend(rcfiles)
+        elif os.path.exists(self.manifest):
+            self.read_manifest()
+        ei_cmd = self.get_finalized_command('egg_info')
+        self.filelist.graft(ei_cmd.egg_info)
+
+    def prune_file_list(self):
+        build = self.get_finalized_command('build')
+        base_dir = self.distribution.get_fullname()
+        self.filelist.prune(build.build_base)
+        self.filelist.prune(base_dir)
+        sep = re.escape(os.sep)
+        self.filelist.exclude_pattern(r'(^|' + sep + r')(RCS|CVS|\.svn)' + sep,
+                                      is_regex=1)
+
+
+def write_file(filename, contents):
+    """Create a file with the specified name and write 'contents' (a
+    sequence of strings without line terminators) to it.
+    """
+    contents = "\n".join(contents)
+
+    # assuming the contents has been vetted for utf-8 encoding
+    contents = contents.encode("utf-8")
+
+    with open(filename, "wb") as f:  # always write POSIX-style manifest
+        f.write(contents)
+
+
+def write_pkg_info(cmd, basename, filename):
+    log.info("writing %s", filename)
+    if not cmd.dry_run:
+        metadata = cmd.distribution.metadata
+        metadata.version, oldver = cmd.egg_version, metadata.version
+        metadata.name, oldname = cmd.egg_name, metadata.name
+
+        try:
+            # write unescaped data to PKG-INFO, so older pkg_resources
+            # can still parse it
+            metadata.write_pkg_info(cmd.egg_info)
+        finally:
+            metadata.name, metadata.version = oldname, oldver
+
+        safe = getattr(cmd.distribution, 'zip_safe', None)
+
+        bdist_egg.write_safety_flag(cmd.egg_info, safe)
+
+
+def warn_depends_obsolete(cmd, basename, filename):
+    if os.path.exists(filename):
+        log.warn(
+            "WARNING: 'depends.txt' is not used by setuptools 0.6!\n"
+            "Use the install_requires/extras_require setup() args instead."
+        )
+
+
+def _write_requirements(stream, reqs):
+    lines = yield_lines(reqs or ())
+    append_cr = lambda line: line + '\n'
+    lines = map(append_cr, lines)
+    stream.writelines(lines)
+
+
+def write_requirements(cmd, basename, filename):
+    dist = cmd.distribution
+    data = six.StringIO()
+    _write_requirements(data, dist.install_requires)
+    extras_require = dist.extras_require or {}
+    for extra in sorted(extras_require):
+        data.write('\n[{extra}]\n'.format(**vars()))
+        _write_requirements(data, extras_require[extra])
+    cmd.write_or_delete_file("requirements", filename, data.getvalue())
+
+
+def write_setup_requirements(cmd, basename, filename):
+    data = io.StringIO()
+    _write_requirements(data, cmd.distribution.setup_requires)
+    cmd.write_or_delete_file("setup-requirements", filename, data.getvalue())
+
+
+def write_toplevel_names(cmd, basename, filename):
+    pkgs = dict.fromkeys(
+        [
+            k.split('.', 1)[0]
+            for k in cmd.distribution.iter_distribution_names()
+        ]
+    )
+    cmd.write_file("top-level names", filename, '\n'.join(sorted(pkgs)) + '\n')
+
+
+def overwrite_arg(cmd, basename, filename):
+    write_arg(cmd, basename, filename, True)
+
+
+def write_arg(cmd, basename, filename, force=False):
+    argname = os.path.splitext(basename)[0]
+    value = getattr(cmd.distribution, argname, None)
+    if value is not None:
+        value = '\n'.join(value) + '\n'
+    cmd.write_or_delete_file(argname, filename, value, force)
+
+
+def write_entries(cmd, basename, filename):
+    ep = cmd.distribution.entry_points
+
+    if isinstance(ep, six.string_types) or ep is None:
+        data = ep
+    elif ep is not None:
+        data = []
+        for section, contents in sorted(ep.items()):
+            if not isinstance(contents, six.string_types):
+                contents = EntryPoint.parse_group(section, contents)
+                contents = '\n'.join(sorted(map(str, contents.values())))
+            data.append('[%s]\n%s\n\n' % (section, contents))
+        data = ''.join(data)
+
+    cmd.write_or_delete_file('entry points', filename, data, True)
+
+
+def get_pkg_info_revision():
+    """
+    Get a -r### off of PKG-INFO Version in case this is an sdist of
+    a subversion revision.
+    """
+    warnings.warn("get_pkg_info_revision is deprecated.", DeprecationWarning)
+    if os.path.exists('PKG-INFO'):
+        with io.open('PKG-INFO') as f:
+            for line in f:
+                match = re.match(r"Version:.*-r(\d+)\s*$", line)
+                if match:
+                    return int(match.group(1))
+    return 0
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/install.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/install.py
new file mode 100644
index 00000000..31a5ddb5
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/install.py
@@ -0,0 +1,125 @@
+from distutils.errors import DistutilsArgError
+import inspect
+import glob
+import warnings
+import platform
+import distutils.command.install as orig
+
+import setuptools
+
+# Prior to numpy 1.9, NumPy relies on the '_install' name, so provide it for
+# now. See https://github.com/pypa/setuptools/issues/199/
+_install = orig.install
+
+
+class install(orig.install):
+    """Use easy_install to install the package, w/dependencies"""
+
+    user_options = orig.install.user_options + [
+        ('old-and-unmanageable', None, "Try not to use this!"),
+        ('single-version-externally-managed', None,
+         "used by system package builders to create 'flat' eggs"),
+    ]
+    boolean_options = orig.install.boolean_options + [
+        'old-and-unmanageable', 'single-version-externally-managed',
+    ]
+    new_commands = [
+        ('install_egg_info', lambda self: True),
+        ('install_scripts', lambda self: True),
+    ]
+    _nc = dict(new_commands)
+
+    def initialize_options(self):
+        orig.install.initialize_options(self)
+        self.old_and_unmanageable = None
+        self.single_version_externally_managed = None
+
+    def finalize_options(self):
+        orig.install.finalize_options(self)
+        if self.root:
+            self.single_version_externally_managed = True
+        elif self.single_version_externally_managed:
+            if not self.root and not self.record:
+                raise DistutilsArgError(
+                    "You must specify --record or --root when building system"
+                    " packages"
+                )
+
+    def handle_extra_path(self):
+        if self.root or self.single_version_externally_managed:
+            # explicit backward-compatibility mode, allow extra_path to work
+            return orig.install.handle_extra_path(self)
+
+        # Ignore extra_path when installing an egg (or being run by another
+        # command without --root or --single-version-externally-managed
+        self.path_file = None
+        self.extra_dirs = ''
+
+    def run(self):
+        # Explicit request for old-style install?  Just do it
+        if self.old_and_unmanageable or self.single_version_externally_managed:
+            return orig.install.run(self)
+
+        if not self._called_from_setup(inspect.currentframe()):
+            # Run in backward-compatibility mode to support bdist_* commands.
+            orig.install.run(self)
+        else:
+            self.do_egg_install()
+
+    @staticmethod
+    def _called_from_setup(run_frame):
+        """
+        Attempt to detect whether run() was called from setup() or by another
+        command.  If called by setup(), the parent caller will be the
+        'run_command' method in 'distutils.dist', and *its* caller will be
+        the 'run_commands' method.  If called any other way, the
+        immediate caller *might* be 'run_command', but it won't have been
+        called by 'run_commands'. Return True in that case or if a call stack
+        is unavailable. Return False otherwise.
+        """
+        if run_frame is None:
+            msg = "Call stack not available. bdist_* commands may fail."
+            warnings.warn(msg)
+            if platform.python_implementation() == 'IronPython':
+                msg = "For best results, pass -X:Frames to enable call stack."
+                warnings.warn(msg)
+            return True
+        res = inspect.getouterframes(run_frame)[2]
+        caller, = res[:1]
+        info = inspect.getframeinfo(caller)
+        caller_module = caller.f_globals.get('__name__', '')
+        return (
+            caller_module == 'distutils.dist'
+            and info.function == 'run_commands'
+        )
+
+    def do_egg_install(self):
+
+        easy_install = self.distribution.get_command_class('easy_install')
+
+        cmd = easy_install(
+            self.distribution, args="x", root=self.root, record=self.record,
+        )
+        cmd.ensure_finalized()  # finalize before bdist_egg munges install cmd
+        cmd.always_copy_from = '.'  # make sure local-dir eggs get installed
+
+        # pick up setup-dir .egg files only: no .egg-info
+        cmd.package_index.scan(glob.glob('*.egg'))
+
+        self.run_command('bdist_egg')
+        args = [self.distribution.get_command_obj('bdist_egg').egg_output]
+
+        if setuptools.bootstrap_install_from:
+            # Bootstrap self-installation of setuptools
+            args.insert(0, setuptools.bootstrap_install_from)
+
+        cmd.args = args
+        cmd.run()
+        setuptools.bootstrap_install_from = None
+
+
+# XXX Python 3.1 doesn't see _nc if this is inside the class
+install.sub_commands = (
+    [cmd for cmd in orig.install.sub_commands if cmd[0] not in install._nc] +
+    install.new_commands
+)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/install_egg_info.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/install_egg_info.py
new file mode 100644
index 00000000..edc4718b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/install_egg_info.py
@@ -0,0 +1,62 @@
+from distutils import log, dir_util
+import os
+
+from setuptools import Command
+from setuptools import namespaces
+from setuptools.archive_util import unpack_archive
+import pkg_resources
+
+
+class install_egg_info(namespaces.Installer, Command):
+    """Install an .egg-info directory for the package"""
+
+    description = "Install an .egg-info directory for the package"
+
+    user_options = [
+        ('install-dir=', 'd', "directory to install to"),
+    ]
+
+    def initialize_options(self):
+        self.install_dir = None
+
+    def finalize_options(self):
+        self.set_undefined_options('install_lib',
+                                   ('install_dir', 'install_dir'))
+        ei_cmd = self.get_finalized_command("egg_info")
+        basename = pkg_resources.Distribution(
+            None, None, ei_cmd.egg_name, ei_cmd.egg_version
+        ).egg_name() + '.egg-info'
+        self.source = ei_cmd.egg_info
+        self.target = os.path.join(self.install_dir, basename)
+        self.outputs = []
+
+    def run(self):
+        self.run_command('egg_info')
+        if os.path.isdir(self.target) and not os.path.islink(self.target):
+            dir_util.remove_tree(self.target, dry_run=self.dry_run)
+        elif os.path.exists(self.target):
+            self.execute(os.unlink, (self.target,), "Removing " + self.target)
+        if not self.dry_run:
+            pkg_resources.ensure_directory(self.target)
+        self.execute(
+            self.copytree, (), "Copying %s to %s" % (self.source, self.target)
+        )
+        self.install_namespaces()
+
+    def get_outputs(self):
+        return self.outputs
+
+    def copytree(self):
+        # Copy the .egg-info tree to site-packages
+        def skimmer(src, dst):
+            # filter out source-control directories; note that 'src' is always
+            # a '/'-separated path, regardless of platform.  'dst' is a
+            # platform-specific path.
+            for skip in '.svn/', 'CVS/':
+                if src.startswith(skip) or '/' + skip in src:
+                    return None
+            self.outputs.append(dst)
+            log.debug("Copying %s to %s", src, dst)
+            return dst
+
+        unpack_archive(self.source, self.target, skimmer)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/install_lib.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/install_lib.py
new file mode 100644
index 00000000..2b31c3e3
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/install_lib.py
@@ -0,0 +1,121 @@
+import os
+import imp
+from itertools import product, starmap
+import distutils.command.install_lib as orig
+
+
+class install_lib(orig.install_lib):
+    """Don't add compiled flags to filenames of non-Python files"""
+
+    def run(self):
+        self.build()
+        outfiles = self.install()
+        if outfiles is not None:
+            # always compile, in case we have any extension stubs to deal with
+            self.byte_compile(outfiles)
+
+    def get_exclusions(self):
+        """
+        Return a collections.Sized collections.Container of paths to be
+        excluded for single_version_externally_managed installations.
+        """
+        all_packages = (
+            pkg
+            for ns_pkg in self._get_SVEM_NSPs()
+            for pkg in self._all_packages(ns_pkg)
+        )
+
+        excl_specs = product(all_packages, self._gen_exclusion_paths())
+        return set(starmap(self._exclude_pkg_path, excl_specs))
+
+    def _exclude_pkg_path(self, pkg, exclusion_path):
+        """
+        Given a package name and exclusion path within that package,
+        compute the full exclusion path.
+        """
+        parts = pkg.split('.') + [exclusion_path]
+        return os.path.join(self.install_dir, *parts)
+
+    @staticmethod
+    def _all_packages(pkg_name):
+        """
+        >>> list(install_lib._all_packages('foo.bar.baz'))
+        ['foo.bar.baz', 'foo.bar', 'foo']
+        """
+        while pkg_name:
+            yield pkg_name
+            pkg_name, sep, child = pkg_name.rpartition('.')
+
+    def _get_SVEM_NSPs(self):
+        """
+        Get namespace packages (list) but only for
+        single_version_externally_managed installations and empty otherwise.
+        """
+        # TODO: is it necessary to short-circuit here? i.e. what's the cost
+        # if get_finalized_command is called even when namespace_packages is
+        # False?
+        if not self.distribution.namespace_packages:
+            return []
+
+        install_cmd = self.get_finalized_command('install')
+        svem = install_cmd.single_version_externally_managed
+
+        return self.distribution.namespace_packages if svem else []
+
+    @staticmethod
+    def _gen_exclusion_paths():
+        """
+        Generate file paths to be excluded for namespace packages (bytecode
+        cache files).
+        """
+        # always exclude the package module itself
+        yield '__init__.py'
+
+        yield '__init__.pyc'
+        yield '__init__.pyo'
+
+        if not hasattr(imp, 'get_tag'):
+            return
+
+        base = os.path.join('__pycache__', '__init__.' + imp.get_tag())
+        yield base + '.pyc'
+        yield base + '.pyo'
+        yield base + '.opt-1.pyc'
+        yield base + '.opt-2.pyc'
+
+    def copy_tree(
+            self, infile, outfile,
+            preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1
+    ):
+        assert preserve_mode and preserve_times and not preserve_symlinks
+        exclude = self.get_exclusions()
+
+        if not exclude:
+            return orig.install_lib.copy_tree(self, infile, outfile)
+
+        # Exclude namespace package __init__.py* files from the output
+
+        from setuptools.archive_util import unpack_directory
+        from distutils import log
+
+        outfiles = []
+
+        def pf(src, dst):
+            if dst in exclude:
+                log.warn("Skipping installation of %s (namespace package)",
+                         dst)
+                return False
+
+            log.info("copying %s -> %s", src, os.path.dirname(dst))
+            outfiles.append(dst)
+            return dst
+
+        unpack_directory(infile, outfile, pf)
+        return outfiles
+
+    def get_outputs(self):
+        outputs = orig.install_lib.get_outputs(self)
+        exclude = self.get_exclusions()
+        if exclude:
+            return [f for f in outputs if f not in exclude]
+        return outputs
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/install_scripts.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/install_scripts.py
new file mode 100644
index 00000000..16234273
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/install_scripts.py
@@ -0,0 +1,65 @@
+from distutils import log
+import distutils.command.install_scripts as orig
+import os
+import sys
+
+from pkg_resources import Distribution, PathMetadata, ensure_directory
+
+
+class install_scripts(orig.install_scripts):
+    """Do normal script install, plus any egg_info wrapper scripts"""
+
+    def initialize_options(self):
+        orig.install_scripts.initialize_options(self)
+        self.no_ep = False
+
+    def run(self):
+        import setuptools.command.easy_install as ei
+
+        self.run_command("egg_info")
+        if self.distribution.scripts:
+            orig.install_scripts.run(self)  # run first to set up self.outfiles
+        else:
+            self.outfiles = []
+        if self.no_ep:
+            # don't install entry point scripts into .egg file!
+            return
+
+        ei_cmd = self.get_finalized_command("egg_info")
+        dist = Distribution(
+            ei_cmd.egg_base, PathMetadata(ei_cmd.egg_base, ei_cmd.egg_info),
+            ei_cmd.egg_name, ei_cmd.egg_version,
+        )
+        bs_cmd = self.get_finalized_command('build_scripts')
+        exec_param = getattr(bs_cmd, 'executable', None)
+        bw_cmd = self.get_finalized_command("bdist_wininst")
+        is_wininst = getattr(bw_cmd, '_is_running', False)
+        writer = ei.ScriptWriter
+        if is_wininst:
+            exec_param = "python.exe"
+            writer = ei.WindowsScriptWriter
+        if exec_param == sys.executable:
+            # In case the path to the Python executable contains a space, wrap
+            # it so it's not split up.
+            exec_param = [exec_param]
+        # resolve the writer to the environment
+        writer = writer.best()
+        cmd = writer.command_spec_class.best().from_param(exec_param)
+        for args in writer.get_args(dist, cmd.as_header()):
+            self.write_script(*args)
+
+    def write_script(self, script_name, contents, mode="t", *ignored):
+        """Write an executable file to the scripts directory"""
+        from setuptools.command.easy_install import chmod, current_umask
+
+        log.info("Installing %s script to %s", script_name, self.install_dir)
+        target = os.path.join(self.install_dir, script_name)
+        self.outfiles.append(target)
+
+        mask = current_umask()
+        if not self.dry_run:
+            ensure_directory(target)
+            f = open(target, "w" + mode)
+            f.write(contents)
+            f.close()
+            chmod(target, 0o777 - mask)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/launcher manifest.xml b/vendor/setuptools-39.0.1/build/lib/setuptools/command/launcher manifest.xml
new file mode 100644
index 00000000..5972a96d
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/launcher manifest.xml	
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+    <assemblyIdentity version="1.0.0.0"
+                      processorArchitecture="X86"
+                      name="%(name)s"
+                      type="win32"/>
+    <!-- Identify the application security requirements. -->
+    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+        <security>
+            <requestedPrivileges>
+                <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+            </requestedPrivileges>
+        </security>
+    </trustInfo>
+</assembly>
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/py36compat.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/py36compat.py
new file mode 100644
index 00000000..61063e75
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/py36compat.py
@@ -0,0 +1,136 @@
+import os
+from glob import glob
+from distutils.util import convert_path
+from distutils.command import sdist
+
+from setuptools.extern.six.moves import filter
+
+
+class sdist_add_defaults:
+    """
+    Mix-in providing forward-compatibility for functionality as found in
+    distutils on Python 3.7.
+
+    Do not edit the code in this class except to update functionality
+    as implemented in distutils. Instead, override in the subclass.
+    """
+
+    def add_defaults(self):
+        """Add all the default files to self.filelist:
+          - README or README.txt
+          - setup.py
+          - test/test*.py
+          - all pure Python modules mentioned in setup script
+          - all files pointed by package_data (build_py)
+          - all files defined in data_files.
+          - all files defined as scripts.
+          - all C sources listed as part of extensions or C libraries
+            in the setup script (doesn't catch C headers!)
+        Warns if (README or README.txt) or setup.py are missing; everything
+        else is optional.
+        """
+        self._add_defaults_standards()
+        self._add_defaults_optional()
+        self._add_defaults_python()
+        self._add_defaults_data_files()
+        self._add_defaults_ext()
+        self._add_defaults_c_libs()
+        self._add_defaults_scripts()
+
+    @staticmethod
+    def _cs_path_exists(fspath):
+        """
+        Case-sensitive path existence check
+
+        >>> sdist_add_defaults._cs_path_exists(__file__)
+        True
+        >>> sdist_add_defaults._cs_path_exists(__file__.upper())
+        False
+        """
+        if not os.path.exists(fspath):
+            return False
+        # make absolute so we always have a directory
+        abspath = os.path.abspath(fspath)
+        directory, filename = os.path.split(abspath)
+        return filename in os.listdir(directory)
+
+    def _add_defaults_standards(self):
+        standards = [self.READMES, self.distribution.script_name]
+        for fn in standards:
+            if isinstance(fn, tuple):
+                alts = fn
+                got_it = False
+                for fn in alts:
+                    if self._cs_path_exists(fn):
+                        got_it = True
+                        self.filelist.append(fn)
+                        break
+
+                if not got_it:
+                    self.warn("standard file not found: should have one of " +
+                              ', '.join(alts))
+            else:
+                if self._cs_path_exists(fn):
+                    self.filelist.append(fn)
+                else:
+                    self.warn("standard file '%s' not found" % fn)
+
+    def _add_defaults_optional(self):
+        optional = ['test/test*.py', 'setup.cfg']
+        for pattern in optional:
+            files = filter(os.path.isfile, glob(pattern))
+            self.filelist.extend(files)
+
+    def _add_defaults_python(self):
+        # build_py is used to get:
+        #  - python modules
+        #  - files defined in package_data
+        build_py = self.get_finalized_command('build_py')
+
+        # getting python files
+        if self.distribution.has_pure_modules():
+            self.filelist.extend(build_py.get_source_files())
+
+        # getting package_data files
+        # (computed in build_py.data_files by build_py.finalize_options)
+        for pkg, src_dir, build_dir, filenames in build_py.data_files:
+            for filename in filenames:
+                self.filelist.append(os.path.join(src_dir, filename))
+
+    def _add_defaults_data_files(self):
+        # getting distribution.data_files
+        if self.distribution.has_data_files():
+            for item in self.distribution.data_files:
+                if isinstance(item, str):
+                    # plain file
+                    item = convert_path(item)
+                    if os.path.isfile(item):
+                        self.filelist.append(item)
+                else:
+                    # a (dirname, filenames) tuple
+                    dirname, filenames = item
+                    for f in filenames:
+                        f = convert_path(f)
+                        if os.path.isfile(f):
+                            self.filelist.append(f)
+
+    def _add_defaults_ext(self):
+        if self.distribution.has_ext_modules():
+            build_ext = self.get_finalized_command('build_ext')
+            self.filelist.extend(build_ext.get_source_files())
+
+    def _add_defaults_c_libs(self):
+        if self.distribution.has_c_libraries():
+            build_clib = self.get_finalized_command('build_clib')
+            self.filelist.extend(build_clib.get_source_files())
+
+    def _add_defaults_scripts(self):
+        if self.distribution.has_scripts():
+            build_scripts = self.get_finalized_command('build_scripts')
+            self.filelist.extend(build_scripts.get_source_files())
+
+
+if hasattr(sdist.sdist, '_add_defaults_standards'):
+    # disable the functionality already available upstream
+    class sdist_add_defaults:
+        pass
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/register.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/register.py
new file mode 100644
index 00000000..8d6336a1
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/register.py
@@ -0,0 +1,10 @@
+import distutils.command.register as orig
+
+
+class register(orig.register):
+    __doc__ = orig.register.__doc__
+
+    def run(self):
+        # Make sure that we are using valid current name/version info
+        self.run_command('egg_info')
+        orig.register.run(self)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/rotate.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/rotate.py
new file mode 100644
index 00000000..b89353f5
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/rotate.py
@@ -0,0 +1,66 @@
+from distutils.util import convert_path
+from distutils import log
+from distutils.errors import DistutilsOptionError
+import os
+import shutil
+
+from setuptools.extern import six
+
+from setuptools import Command
+
+
+class rotate(Command):
+    """Delete older distributions"""
+
+    description = "delete older distributions, keeping N newest files"
+    user_options = [
+        ('match=', 'm', "patterns to match (required)"),
+        ('dist-dir=', 'd', "directory where the distributions are"),
+        ('keep=', 'k', "number of matching distributions to keep"),
+    ]
+
+    boolean_options = []
+
+    def initialize_options(self):
+        self.match = None
+        self.dist_dir = None
+        self.keep = None
+
+    def finalize_options(self):
+        if self.match is None:
+            raise DistutilsOptionError(
+                "Must specify one or more (comma-separated) match patterns "
+                "(e.g. '.zip' or '.egg')"
+            )
+        if self.keep is None:
+            raise DistutilsOptionError("Must specify number of files to keep")
+        try:
+            self.keep = int(self.keep)
+        except ValueError:
+            raise DistutilsOptionError("--keep must be an integer")
+        if isinstance(self.match, six.string_types):
+            self.match = [
+                convert_path(p.strip()) for p in self.match.split(',')
+            ]
+        self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
+
+    def run(self):
+        self.run_command("egg_info")
+        from glob import glob
+
+        for pattern in self.match:
+            pattern = self.distribution.get_name() + '*' + pattern
+            files = glob(os.path.join(self.dist_dir, pattern))
+            files = [(os.path.getmtime(f), f) for f in files]
+            files.sort()
+            files.reverse()
+
+            log.info("%d file(s) matching %s", len(files), pattern)
+            files = files[self.keep:]
+            for (t, f) in files:
+                log.info("Deleting %s", f)
+                if not self.dry_run:
+                    if os.path.isdir(f):
+                        shutil.rmtree(f)
+                    else:
+                        os.unlink(f)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/saveopts.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/saveopts.py
new file mode 100644
index 00000000..611cec55
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/saveopts.py
@@ -0,0 +1,22 @@
+from setuptools.command.setopt import edit_config, option_base
+
+
+class saveopts(option_base):
+    """Save command-line options to a file"""
+
+    description = "save supplied options to setup.cfg or other config file"
+
+    def run(self):
+        dist = self.distribution
+        settings = {}
+
+        for cmd in dist.command_options:
+
+            if cmd == 'saveopts':
+                continue  # don't save our own options!
+
+            for opt, (src, val) in dist.get_option_dict(cmd).items():
+                if src == "command line":
+                    settings.setdefault(cmd, {})[opt] = val
+
+        edit_config(self.filename, settings, self.dry_run)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/sdist.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/sdist.py
new file mode 100644
index 00000000..bcfae4d8
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/sdist.py
@@ -0,0 +1,200 @@
+from distutils import log
+import distutils.command.sdist as orig
+import os
+import sys
+import io
+import contextlib
+
+from setuptools.extern import six
+
+from .py36compat import sdist_add_defaults
+
+import pkg_resources
+
+_default_revctrl = list
+
+
+def walk_revctrl(dirname=''):
+    """Find all files under revision control"""
+    for ep in pkg_resources.iter_entry_points('setuptools.file_finders'):
+        for item in ep.load()(dirname):
+            yield item
+
+
+class sdist(sdist_add_defaults, orig.sdist):
+    """Smart sdist that finds anything supported by revision control"""
+
+    user_options = [
+        ('formats=', None,
+         "formats for source distribution (comma-separated list)"),
+        ('keep-temp', 'k',
+         "keep the distribution tree around after creating " +
+         "archive file(s)"),
+        ('dist-dir=', 'd',
+         "directory to put the source distribution archive(s) in "
+         "[default: dist]"),
+    ]
+
+    negative_opt = {}
+
+    README_EXTENSIONS = ['', '.rst', '.txt', '.md']
+    READMES = tuple('README{0}'.format(ext) for ext in README_EXTENSIONS)
+
+    def run(self):
+        self.run_command('egg_info')
+        ei_cmd = self.get_finalized_command('egg_info')
+        self.filelist = ei_cmd.filelist
+        self.filelist.append(os.path.join(ei_cmd.egg_info, 'SOURCES.txt'))
+        self.check_readme()
+
+        # Run sub commands
+        for cmd_name in self.get_sub_commands():
+            self.run_command(cmd_name)
+
+        self.make_distribution()
+
+        dist_files = getattr(self.distribution, 'dist_files', [])
+        for file in self.archive_files:
+            data = ('sdist', '', file)
+            if data not in dist_files:
+                dist_files.append(data)
+
+    def initialize_options(self):
+        orig.sdist.initialize_options(self)
+
+        self._default_to_gztar()
+
+    def _default_to_gztar(self):
+        # only needed on Python prior to 3.6.
+        if sys.version_info >= (3, 6, 0, 'beta', 1):
+            return
+        self.formats = ['gztar']
+
+    def make_distribution(self):
+        """
+        Workaround for #516
+        """
+        with self._remove_os_link():
+            orig.sdist.make_distribution(self)
+
+    @staticmethod
+    @contextlib.contextmanager
+    def _remove_os_link():
+        """
+        In a context, remove and restore os.link if it exists
+        """
+
+        class NoValue:
+            pass
+
+        orig_val = getattr(os, 'link', NoValue)
+        try:
+            del os.link
+        except Exception:
+            pass
+        try:
+            yield
+        finally:
+            if orig_val is not NoValue:
+                setattr(os, 'link', orig_val)
+
+    def __read_template_hack(self):
+        # This grody hack closes the template file (MANIFEST.in) if an
+        #  exception occurs during read_template.
+        # Doing so prevents an error when easy_install attempts to delete the
+        #  file.
+        try:
+            orig.sdist.read_template(self)
+        except Exception:
+            _, _, tb = sys.exc_info()
+            tb.tb_next.tb_frame.f_locals['template'].close()
+            raise
+
+    # Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle
+    #  has been fixed, so only override the method if we're using an earlier
+    #  Python.
+    has_leaky_handle = (
+        sys.version_info < (2, 7, 2)
+        or (3, 0) <= sys.version_info < (3, 1, 4)
+        or (3, 2) <= sys.version_info < (3, 2, 1)
+    )
+    if has_leaky_handle:
+        read_template = __read_template_hack
+
+    def _add_defaults_python(self):
+        """getting python files"""
+        if self.distribution.has_pure_modules():
+            build_py = self.get_finalized_command('build_py')
+            self.filelist.extend(build_py.get_source_files())
+            # This functionality is incompatible with include_package_data, and
+            # will in fact create an infinite recursion if include_package_data
+            # is True.  Use of include_package_data will imply that
+            # distutils-style automatic handling of package_data is disabled
+            if not self.distribution.include_package_data:
+                for _, src_dir, _, filenames in build_py.data_files:
+                    self.filelist.extend([os.path.join(src_dir, filename)
+                                          for filename in filenames])
+
+    def _add_defaults_data_files(self):
+        try:
+            if six.PY2:
+                sdist_add_defaults._add_defaults_data_files(self)
+            else:
+                super()._add_defaults_data_files()
+        except TypeError:
+            log.warn("data_files contains unexpected objects")
+
+    def check_readme(self):
+        for f in self.READMES:
+            if os.path.exists(f):
+                return
+        else:
+            self.warn(
+                "standard file not found: should have one of " +
+                ', '.join(self.READMES)
+            )
+
+    def make_release_tree(self, base_dir, files):
+        orig.sdist.make_release_tree(self, base_dir, files)
+
+        # Save any egg_info command line options used to create this sdist
+        dest = os.path.join(base_dir, 'setup.cfg')
+        if hasattr(os, 'link') and os.path.exists(dest):
+            # unlink and re-copy, since it might be hard-linked, and
+            # we don't want to change the source version
+            os.unlink(dest)
+            self.copy_file('setup.cfg', dest)
+
+        self.get_finalized_command('egg_info').save_version_info(dest)
+
+    def _manifest_is_not_generated(self):
+        # check for special comment used in 2.7.1 and higher
+        if not os.path.isfile(self.manifest):
+            return False
+
+        with io.open(self.manifest, 'rb') as fp:
+            first_line = fp.readline()
+        return (first_line !=
+                '# file GENERATED by distutils, do NOT edit\n'.encode())
+
+    def read_manifest(self):
+        """Read the manifest file (named by 'self.manifest') and use it to
+        fill in 'self.filelist', the list of files to include in the source
+        distribution.
+        """
+        log.info("reading manifest file '%s'", self.manifest)
+        manifest = open(self.manifest, 'rb')
+        for line in manifest:
+            # The manifest must contain UTF-8. See #303.
+            if six.PY3:
+                try:
+                    line = line.decode('UTF-8')
+                except UnicodeDecodeError:
+                    log.warn("%r not UTF-8 decodable -- skipping" % line)
+                    continue
+            # ignore comments and blank lines
+            line = line.strip()
+            if line.startswith('#') or not line:
+                continue
+            self.filelist.append(line)
+        manifest.close()
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/setopt.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/setopt.py
new file mode 100644
index 00000000..7e57cc02
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/setopt.py
@@ -0,0 +1,149 @@
+from distutils.util import convert_path
+from distutils import log
+from distutils.errors import DistutilsOptionError
+import distutils
+import os
+
+from setuptools.extern.six.moves import configparser
+
+from setuptools import Command
+
+__all__ = ['config_file', 'edit_config', 'option_base', 'setopt']
+
+
+def config_file(kind="local"):
+    """Get the filename of the distutils, local, global, or per-user config
+
+    `kind` must be one of "local", "global", or "user"
+    """
+    if kind == 'local':
+        return 'setup.cfg'
+    if kind == 'global':
+        return os.path.join(
+            os.path.dirname(distutils.__file__), 'distutils.cfg'
+        )
+    if kind == 'user':
+        dot = os.name == 'posix' and '.' or ''
+        return os.path.expanduser(convert_path("~/%spydistutils.cfg" % dot))
+    raise ValueError(
+        "config_file() type must be 'local', 'global', or 'user'", kind
+    )
+
+
+def edit_config(filename, settings, dry_run=False):
+    """Edit a configuration file to include `settings`
+
+    `settings` is a dictionary of dictionaries or ``None`` values, keyed by
+    command/section name.  A ``None`` value means to delete the entire section,
+    while a dictionary lists settings to be changed or deleted in that section.
+    A setting of ``None`` means to delete that setting.
+    """
+    log.debug("Reading configuration from %s", filename)
+    opts = configparser.RawConfigParser()
+    opts.read([filename])
+    for section, options in settings.items():
+        if options is None:
+            log.info("Deleting section [%s] from %s", section, filename)
+            opts.remove_section(section)
+        else:
+            if not opts.has_section(section):
+                log.debug("Adding new section [%s] to %s", section, filename)
+                opts.add_section(section)
+            for option, value in options.items():
+                if value is None:
+                    log.debug(
+                        "Deleting %s.%s from %s",
+                        section, option, filename
+                    )
+                    opts.remove_option(section, option)
+                    if not opts.options(section):
+                        log.info("Deleting empty [%s] section from %s",
+                                 section, filename)
+                        opts.remove_section(section)
+                else:
+                    log.debug(
+                        "Setting %s.%s to %r in %s",
+                        section, option, value, filename
+                    )
+                    opts.set(section, option, value)
+
+    log.info("Writing %s", filename)
+    if not dry_run:
+        with open(filename, 'w') as f:
+            opts.write(f)
+
+
+class option_base(Command):
+    """Abstract base class for commands that mess with config files"""
+
+    user_options = [
+        ('global-config', 'g',
+         "save options to the site-wide distutils.cfg file"),
+        ('user-config', 'u',
+         "save options to the current user's pydistutils.cfg file"),
+        ('filename=', 'f',
+         "configuration file to use (default=setup.cfg)"),
+    ]
+
+    boolean_options = [
+        'global-config', 'user-config',
+    ]
+
+    def initialize_options(self):
+        self.global_config = None
+        self.user_config = None
+        self.filename = None
+
+    def finalize_options(self):
+        filenames = []
+        if self.global_config:
+            filenames.append(config_file('global'))
+        if self.user_config:
+            filenames.append(config_file('user'))
+        if self.filename is not None:
+            filenames.append(self.filename)
+        if not filenames:
+            filenames.append(config_file('local'))
+        if len(filenames) > 1:
+            raise DistutilsOptionError(
+                "Must specify only one configuration file option",
+                filenames
+            )
+        self.filename, = filenames
+
+
+class setopt(option_base):
+    """Save command-line options to a file"""
+
+    description = "set an option in setup.cfg or another config file"
+
+    user_options = [
+        ('command=', 'c', 'command to set an option for'),
+        ('option=', 'o', 'option to set'),
+        ('set-value=', 's', 'value of the option'),
+        ('remove', 'r', 'remove (unset) the value'),
+    ] + option_base.user_options
+
+    boolean_options = option_base.boolean_options + ['remove']
+
+    def initialize_options(self):
+        option_base.initialize_options(self)
+        self.command = None
+        self.option = None
+        self.set_value = None
+        self.remove = None
+
+    def finalize_options(self):
+        option_base.finalize_options(self)
+        if self.command is None or self.option is None:
+            raise DistutilsOptionError("Must specify --command *and* --option")
+        if self.set_value is None and not self.remove:
+            raise DistutilsOptionError("Must specify --set-value or --remove")
+
+    def run(self):
+        edit_config(
+            self.filename, {
+                self.command: {self.option.replace('-', '_'): self.set_value}
+            },
+            self.dry_run
+        )
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/test.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/test.py
new file mode 100644
index 00000000..51aee1f7
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/test.py
@@ -0,0 +1,268 @@
+import os
+import operator
+import sys
+import contextlib
+import itertools
+import unittest
+from distutils.errors import DistutilsError, DistutilsOptionError
+from distutils import log
+from unittest import TestLoader
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import map, filter
+
+from pkg_resources import (resource_listdir, resource_exists, normalize_path,
+                           working_set, _namespace_packages, evaluate_marker,
+                           add_activation_listener, require, EntryPoint)
+from setuptools import Command
+
+
+class ScanningLoader(TestLoader):
+
+    def __init__(self):
+        TestLoader.__init__(self)
+        self._visited = set()
+
+    def loadTestsFromModule(self, module, pattern=None):
+        """Return a suite of all tests cases contained in the given module
+
+        If the module is a package, load tests from all the modules in it.
+        If the module has an ``additional_tests`` function, call it and add
+        the return value to the tests.
+        """
+        if module in self._visited:
+            return None
+        self._visited.add(module)
+
+        tests = []
+        tests.append(TestLoader.loadTestsFromModule(self, module))
+
+        if hasattr(module, "additional_tests"):
+            tests.append(module.additional_tests())
+
+        if hasattr(module, '__path__'):
+            for file in resource_listdir(module.__name__, ''):
+                if file.endswith('.py') and file != '__init__.py':
+                    submodule = module.__name__ + '.' + file[:-3]
+                else:
+                    if resource_exists(module.__name__, file + '/__init__.py'):
+                        submodule = module.__name__ + '.' + file
+                    else:
+                        continue
+                tests.append(self.loadTestsFromName(submodule))
+
+        if len(tests) != 1:
+            return self.suiteClass(tests)
+        else:
+            return tests[0]  # don't create a nested suite for only one return
+
+
+# adapted from jaraco.classes.properties:NonDataProperty
+class NonDataProperty(object):
+    def __init__(self, fget):
+        self.fget = fget
+
+    def __get__(self, obj, objtype=None):
+        if obj is None:
+            return self
+        return self.fget(obj)
+
+
+class test(Command):
+    """Command to run unit tests after in-place build"""
+
+    description = "run unit tests after in-place build"
+
+    user_options = [
+        ('test-module=', 'm', "Run 'test_suite' in specified module"),
+        ('test-suite=', 's',
+         "Run single test, case or suite (e.g. 'module.test_suite')"),
+        ('test-runner=', 'r', "Test runner to use"),
+    ]
+
+    def initialize_options(self):
+        self.test_suite = None
+        self.test_module = None
+        self.test_loader = None
+        self.test_runner = None
+
+    def finalize_options(self):
+
+        if self.test_suite and self.test_module:
+            msg = "You may specify a module or a suite, but not both"
+            raise DistutilsOptionError(msg)
+
+        if self.test_suite is None:
+            if self.test_module is None:
+                self.test_suite = self.distribution.test_suite
+            else:
+                self.test_suite = self.test_module + ".test_suite"
+
+        if self.test_loader is None:
+            self.test_loader = getattr(self.distribution, 'test_loader', None)
+        if self.test_loader is None:
+            self.test_loader = "setuptools.command.test:ScanningLoader"
+        if self.test_runner is None:
+            self.test_runner = getattr(self.distribution, 'test_runner', None)
+
+    @NonDataProperty
+    def test_args(self):
+        return list(self._test_args())
+
+    def _test_args(self):
+        if not self.test_suite and sys.version_info >= (2, 7):
+            yield 'discover'
+        if self.verbose:
+            yield '--verbose'
+        if self.test_suite:
+            yield self.test_suite
+
+    def with_project_on_sys_path(self, func):
+        """
+        Backward compatibility for project_on_sys_path context.
+        """
+        with self.project_on_sys_path():
+            func()
+
+    @contextlib.contextmanager
+    def project_on_sys_path(self, include_dists=[]):
+        with_2to3 = six.PY3 and getattr(self.distribution, 'use_2to3', False)
+
+        if with_2to3:
+            # If we run 2to3 we can not do this inplace:
+
+            # Ensure metadata is up-to-date
+            self.reinitialize_command('build_py', inplace=0)
+            self.run_command('build_py')
+            bpy_cmd = self.get_finalized_command("build_py")
+            build_path = normalize_path(bpy_cmd.build_lib)
+
+            # Build extensions
+            self.reinitialize_command('egg_info', egg_base=build_path)
+            self.run_command('egg_info')
+
+            self.reinitialize_command('build_ext', inplace=0)
+            self.run_command('build_ext')
+        else:
+            # Without 2to3 inplace works fine:
+            self.run_command('egg_info')
+
+            # Build extensions in-place
+            self.reinitialize_command('build_ext', inplace=1)
+            self.run_command('build_ext')
+
+        ei_cmd = self.get_finalized_command("egg_info")
+
+        old_path = sys.path[:]
+        old_modules = sys.modules.copy()
+
+        try:
+            project_path = normalize_path(ei_cmd.egg_base)
+            sys.path.insert(0, project_path)
+            working_set.__init__()
+            add_activation_listener(lambda dist: dist.activate())
+            require('%s==%s' % (ei_cmd.egg_name, ei_cmd.egg_version))
+            with self.paths_on_pythonpath([project_path]):
+                yield
+        finally:
+            sys.path[:] = old_path
+            sys.modules.clear()
+            sys.modules.update(old_modules)
+            working_set.__init__()
+
+    @staticmethod
+    @contextlib.contextmanager
+    def paths_on_pythonpath(paths):
+        """
+        Add the indicated paths to the head of the PYTHONPATH environment
+        variable so that subprocesses will also see the packages at
+        these paths.
+
+        Do this in a context that restores the value on exit.
+        """
+        nothing = object()
+        orig_pythonpath = os.environ.get('PYTHONPATH', nothing)
+        current_pythonpath = os.environ.get('PYTHONPATH', '')
+        try:
+            prefix = os.pathsep.join(paths)
+            to_join = filter(None, [prefix, current_pythonpath])
+            new_path = os.pathsep.join(to_join)
+            if new_path:
+                os.environ['PYTHONPATH'] = new_path
+            yield
+        finally:
+            if orig_pythonpath is nothing:
+                os.environ.pop('PYTHONPATH', None)
+            else:
+                os.environ['PYTHONPATH'] = orig_pythonpath
+
+    @staticmethod
+    def install_dists(dist):
+        """
+        Install the requirements indicated by self.distribution and
+        return an iterable of the dists that were built.
+        """
+        ir_d = dist.fetch_build_eggs(dist.install_requires)
+        tr_d = dist.fetch_build_eggs(dist.tests_require or [])
+        er_d = dist.fetch_build_eggs(
+            v for k, v in dist.extras_require.items()
+            if k.startswith(':') and evaluate_marker(k[1:])
+        )
+        return itertools.chain(ir_d, tr_d, er_d)
+
+    def run(self):
+        installed_dists = self.install_dists(self.distribution)
+
+        cmd = ' '.join(self._argv)
+        if self.dry_run:
+            self.announce('skipping "%s" (dry run)' % cmd)
+            return
+
+        self.announce('running "%s"' % cmd)
+
+        paths = map(operator.attrgetter('location'), installed_dists)
+        with self.paths_on_pythonpath(paths):
+            with self.project_on_sys_path():
+                self.run_tests()
+
+    def run_tests(self):
+        # Purge modules under test from sys.modules. The test loader will
+        # re-import them from the build location. Required when 2to3 is used
+        # with namespace packages.
+        if six.PY3 and getattr(self.distribution, 'use_2to3', False):
+            module = self.test_suite.split('.')[0]
+            if module in _namespace_packages:
+                del_modules = []
+                if module in sys.modules:
+                    del_modules.append(module)
+                module += '.'
+                for name in sys.modules:
+                    if name.startswith(module):
+                        del_modules.append(name)
+                list(map(sys.modules.__delitem__, del_modules))
+
+        test = unittest.main(
+            None, None, self._argv,
+            testLoader=self._resolve_as_ep(self.test_loader),
+            testRunner=self._resolve_as_ep(self.test_runner),
+            exit=False,
+        )
+        if not test.result.wasSuccessful():
+            msg = 'Test failed: %s' % test.result
+            self.announce(msg, log.ERROR)
+            raise DistutilsError(msg)
+
+    @property
+    def _argv(self):
+        return ['unittest'] + self.test_args
+
+    @staticmethod
+    def _resolve_as_ep(val):
+        """
+        Load the indicated attribute value, called, as a as if it were
+        specified as an entry point.
+        """
+        if val is None:
+            return
+        parsed = EntryPoint.parse("x=" + val)
+        return parsed.resolve()()
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/upload.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/upload.py
new file mode 100644
index 00000000..a44173a9
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/upload.py
@@ -0,0 +1,42 @@
+import getpass
+from distutils.command import upload as orig
+
+
+class upload(orig.upload):
+    """
+    Override default upload behavior to obtain password
+    in a variety of different ways.
+    """
+
+    def finalize_options(self):
+        orig.upload.finalize_options(self)
+        self.username = (
+            self.username or
+            getpass.getuser()
+        )
+        # Attempt to obtain password. Short circuit evaluation at the first
+        # sign of success.
+        self.password = (
+            self.password or
+            self._load_password_from_keyring() or
+            self._prompt_for_password()
+        )
+
+    def _load_password_from_keyring(self):
+        """
+        Attempt to load password from keyring. Suppress Exceptions.
+        """
+        try:
+            keyring = __import__('keyring')
+            return keyring.get_password(self.repository, self.username)
+        except Exception:
+            pass
+
+    def _prompt_for_password(self):
+        """
+        Prompt for a password on the tty. Suppress Exceptions.
+        """
+        try:
+            return getpass.getpass()
+        except (Exception, KeyboardInterrupt):
+            pass
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/command/upload_docs.py b/vendor/setuptools-39.0.1/build/lib/setuptools/command/upload_docs.py
new file mode 100644
index 00000000..07aa564a
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/command/upload_docs.py
@@ -0,0 +1,206 @@
+# -*- coding: utf-8 -*-
+"""upload_docs
+
+Implements a Distutils 'upload_docs' subcommand (upload documentation to
+PyPI's pythonhosted.org).
+"""
+
+from base64 import standard_b64encode
+from distutils import log
+from distutils.errors import DistutilsOptionError
+import os
+import socket
+import zipfile
+import tempfile
+import shutil
+import itertools
+import functools
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import http_client, urllib
+
+from pkg_resources import iter_entry_points
+from .upload import upload
+
+
+def _encode(s):
+    errors = 'surrogateescape' if six.PY3 else 'strict'
+    return s.encode('utf-8', errors)
+
+
+class upload_docs(upload):
+    # override the default repository as upload_docs isn't
+    # supported by Warehouse (and won't be).
+    DEFAULT_REPOSITORY = 'https://pypi.python.org/pypi/'
+
+    description = 'Upload documentation to PyPI'
+
+    user_options = [
+        ('repository=', 'r',
+         "url of repository [default: %s]" % upload.DEFAULT_REPOSITORY),
+        ('show-response', None,
+         'display full response text from server'),
+        ('upload-dir=', None, 'directory to upload'),
+    ]
+    boolean_options = upload.boolean_options
+
+    def has_sphinx(self):
+        if self.upload_dir is None:
+            for ep in iter_entry_points('distutils.commands', 'build_sphinx'):
+                return True
+
+    sub_commands = [('build_sphinx', has_sphinx)]
+
+    def initialize_options(self):
+        upload.initialize_options(self)
+        self.upload_dir = None
+        self.target_dir = None
+
+    def finalize_options(self):
+        upload.finalize_options(self)
+        if self.upload_dir is None:
+            if self.has_sphinx():
+                build_sphinx = self.get_finalized_command('build_sphinx')
+                self.target_dir = build_sphinx.builder_target_dir
+            else:
+                build = self.get_finalized_command('build')
+                self.target_dir = os.path.join(build.build_base, 'docs')
+        else:
+            self.ensure_dirname('upload_dir')
+            self.target_dir = self.upload_dir
+        if 'pypi.python.org' in self.repository:
+            log.warn("Upload_docs command is deprecated. Use RTD instead.")
+        self.announce('Using upload directory %s' % self.target_dir)
+
+    def create_zipfile(self, filename):
+        zip_file = zipfile.ZipFile(filename, "w")
+        try:
+            self.mkpath(self.target_dir)  # just in case
+            for root, dirs, files in os.walk(self.target_dir):
+                if root == self.target_dir and not files:
+                    tmpl = "no files found in upload directory '%s'"
+                    raise DistutilsOptionError(tmpl % self.target_dir)
+                for name in files:
+                    full = os.path.join(root, name)
+                    relative = root[len(self.target_dir):].lstrip(os.path.sep)
+                    dest = os.path.join(relative, name)
+                    zip_file.write(full, dest)
+        finally:
+            zip_file.close()
+
+    def run(self):
+        # Run sub commands
+        for cmd_name in self.get_sub_commands():
+            self.run_command(cmd_name)
+
+        tmp_dir = tempfile.mkdtemp()
+        name = self.distribution.metadata.get_name()
+        zip_file = os.path.join(tmp_dir, "%s.zip" % name)
+        try:
+            self.create_zipfile(zip_file)
+            self.upload_file(zip_file)
+        finally:
+            shutil.rmtree(tmp_dir)
+
+    @staticmethod
+    def _build_part(item, sep_boundary):
+        key, values = item
+        title = '\nContent-Disposition: form-data; name="%s"' % key
+        # handle multiple entries for the same name
+        if not isinstance(values, list):
+            values = [values]
+        for value in values:
+            if isinstance(value, tuple):
+                title += '; filename="%s"' % value[0]
+                value = value[1]
+            else:
+                value = _encode(value)
+            yield sep_boundary
+            yield _encode(title)
+            yield b"\n\n"
+            yield value
+            if value and value[-1:] == b'\r':
+                yield b'\n'  # write an extra newline (lurve Macs)
+
+    @classmethod
+    def _build_multipart(cls, data):
+        """
+        Build up the MIME payload for the POST data
+        """
+        boundary = b'--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
+        sep_boundary = b'\n--' + boundary
+        end_boundary = sep_boundary + b'--'
+        end_items = end_boundary, b"\n",
+        builder = functools.partial(
+            cls._build_part,
+            sep_boundary=sep_boundary,
+        )
+        part_groups = map(builder, data.items())
+        parts = itertools.chain.from_iterable(part_groups)
+        body_items = itertools.chain(parts, end_items)
+        content_type = 'multipart/form-data; boundary=%s' % boundary.decode('ascii')
+        return b''.join(body_items), content_type
+
+    def upload_file(self, filename):
+        with open(filename, 'rb') as f:
+            content = f.read()
+        meta = self.distribution.metadata
+        data = {
+            ':action': 'doc_upload',
+            'name': meta.get_name(),
+            'content': (os.path.basename(filename), content),
+        }
+        # set up the authentication
+        credentials = _encode(self.username + ':' + self.password)
+        credentials = standard_b64encode(credentials)
+        if six.PY3:
+            credentials = credentials.decode('ascii')
+        auth = "Basic " + credentials
+
+        body, ct = self._build_multipart(data)
+
+        msg = "Submitting documentation to %s" % (self.repository)
+        self.announce(msg, log.INFO)
+
+        # build the Request
+        # We can't use urllib2 since we need to send the Basic
+        # auth right with the first request
+        schema, netloc, url, params, query, fragments = \
+            urllib.parse.urlparse(self.repository)
+        assert not params and not query and not fragments
+        if schema == 'http':
+            conn = http_client.HTTPConnection(netloc)
+        elif schema == 'https':
+            conn = http_client.HTTPSConnection(netloc)
+        else:
+            raise AssertionError("unsupported schema " + schema)
+
+        data = ''
+        try:
+            conn.connect()
+            conn.putrequest("POST", url)
+            content_type = ct
+            conn.putheader('Content-type', content_type)
+            conn.putheader('Content-length', str(len(body)))
+            conn.putheader('Authorization', auth)
+            conn.endheaders()
+            conn.send(body)
+        except socket.error as e:
+            self.announce(str(e), log.ERROR)
+            return
+
+        r = conn.getresponse()
+        if r.status == 200:
+            msg = 'Server response (%s): %s' % (r.status, r.reason)
+            self.announce(msg, log.INFO)
+        elif r.status == 301:
+            location = r.getheader('Location')
+            if location is None:
+                location = 'https://pythonhosted.org/%s/' % meta.get_name()
+            msg = 'Upload successful. Visit %s' % location
+            self.announce(msg, log.INFO)
+        else:
+            msg = 'Upload failed (%s): %s' % (r.status, r.reason)
+            self.announce(msg, log.ERROR)
+        if self.show_response:
+            print('-' * 75, r.read(), '-' * 75)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/config.py b/vendor/setuptools-39.0.1/build/lib/setuptools/config.py
new file mode 100644
index 00000000..8eddcae8
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/config.py
@@ -0,0 +1,556 @@
+from __future__ import absolute_import, unicode_literals
+import io
+import os
+import sys
+from collections import defaultdict
+from functools import partial
+from importlib import import_module
+
+from distutils.errors import DistutilsOptionError, DistutilsFileError
+from setuptools.extern.six import string_types
+
+
+def read_configuration(
+        filepath, find_others=False, ignore_option_errors=False):
+    """Read given configuration file and returns options from it as a dict.
+
+    :param str|unicode filepath: Path to configuration file
+        to get options from.
+
+    :param bool find_others: Whether to search for other configuration files
+        which could be on in various places.
+
+    :param bool ignore_option_errors: Whether to silently ignore
+        options, values of which could not be resolved (e.g. due to exceptions
+        in directives such as file:, attr:, etc.).
+        If False exceptions are propagated as expected.
+
+    :rtype: dict
+    """
+    from setuptools.dist import Distribution, _Distribution
+
+    filepath = os.path.abspath(filepath)
+
+    if not os.path.isfile(filepath):
+        raise DistutilsFileError(
+            'Configuration file %s does not exist.' % filepath)
+
+    current_directory = os.getcwd()
+    os.chdir(os.path.dirname(filepath))
+
+    try:
+        dist = Distribution()
+
+        filenames = dist.find_config_files() if find_others else []
+        if filepath not in filenames:
+            filenames.append(filepath)
+
+        _Distribution.parse_config_files(dist, filenames=filenames)
+
+        handlers = parse_configuration(
+            dist, dist.command_options,
+            ignore_option_errors=ignore_option_errors)
+
+    finally:
+        os.chdir(current_directory)
+
+    return configuration_to_dict(handlers)
+
+
+def configuration_to_dict(handlers):
+    """Returns configuration data gathered by given handlers as a dict.
+
+    :param list[ConfigHandler] handlers: Handlers list,
+        usually from parse_configuration()
+
+    :rtype: dict
+    """
+    config_dict = defaultdict(dict)
+
+    for handler in handlers:
+
+        obj_alias = handler.section_prefix
+        target_obj = handler.target_obj
+
+        for option in handler.set_options:
+            getter = getattr(target_obj, 'get_%s' % option, None)
+
+            if getter is None:
+                value = getattr(target_obj, option)
+
+            else:
+                value = getter()
+
+            config_dict[obj_alias][option] = value
+
+    return config_dict
+
+
+def parse_configuration(
+        distribution, command_options, ignore_option_errors=False):
+    """Performs additional parsing of configuration options
+    for a distribution.
+
+    Returns a list of used option handlers.
+
+    :param Distribution distribution:
+    :param dict command_options:
+    :param bool ignore_option_errors: Whether to silently ignore
+        options, values of which could not be resolved (e.g. due to exceptions
+        in directives such as file:, attr:, etc.).
+        If False exceptions are propagated as expected.
+    :rtype: list
+    """
+    meta = ConfigMetadataHandler(
+        distribution.metadata, command_options, ignore_option_errors)
+    meta.parse()
+
+    options = ConfigOptionsHandler(
+        distribution, command_options, ignore_option_errors)
+    options.parse()
+
+    return meta, options
+
+
+class ConfigHandler(object):
+    """Handles metadata supplied in configuration files."""
+
+    section_prefix = None
+    """Prefix for config sections handled by this handler.
+    Must be provided by class heirs.
+
+    """
+
+    aliases = {}
+    """Options aliases.
+    For compatibility with various packages. E.g.: d2to1 and pbr.
+    Note: `-` in keys is replaced with `_` by config parser.
+
+    """
+
+    def __init__(self, target_obj, options, ignore_option_errors=False):
+        sections = {}
+
+        section_prefix = self.section_prefix
+        for section_name, section_options in options.items():
+            if not section_name.startswith(section_prefix):
+                continue
+
+            section_name = section_name.replace(section_prefix, '').strip('.')
+            sections[section_name] = section_options
+
+        self.ignore_option_errors = ignore_option_errors
+        self.target_obj = target_obj
+        self.sections = sections
+        self.set_options = []
+
+    @property
+    def parsers(self):
+        """Metadata item name to parser function mapping."""
+        raise NotImplementedError(
+            '%s must provide .parsers property' % self.__class__.__name__)
+
+    def __setitem__(self, option_name, value):
+        unknown = tuple()
+        target_obj = self.target_obj
+
+        # Translate alias into real name.
+        option_name = self.aliases.get(option_name, option_name)
+
+        current_value = getattr(target_obj, option_name, unknown)
+
+        if current_value is unknown:
+            raise KeyError(option_name)
+
+        if current_value:
+            # Already inhabited. Skipping.
+            return
+
+        skip_option = False
+        parser = self.parsers.get(option_name)
+        if parser:
+            try:
+                value = parser(value)
+
+            except Exception:
+                skip_option = True
+                if not self.ignore_option_errors:
+                    raise
+
+        if skip_option:
+            return
+
+        setter = getattr(target_obj, 'set_%s' % option_name, None)
+        if setter is None:
+            setattr(target_obj, option_name, value)
+        else:
+            setter(value)
+
+        self.set_options.append(option_name)
+
+    @classmethod
+    def _parse_list(cls, value, separator=','):
+        """Represents value as a list.
+
+        Value is split either by separator (defaults to comma) or by lines.
+
+        :param value:
+        :param separator: List items separator character.
+        :rtype: list
+        """
+        if isinstance(value, list):  # _get_parser_compound case
+            return value
+
+        if '\n' in value:
+            value = value.splitlines()
+        else:
+            value = value.split(separator)
+
+        return [chunk.strip() for chunk in value if chunk.strip()]
+
+    @classmethod
+    def _parse_dict(cls, value):
+        """Represents value as a dict.
+
+        :param value:
+        :rtype: dict
+        """
+        separator = '='
+        result = {}
+        for line in cls._parse_list(value):
+            key, sep, val = line.partition(separator)
+            if sep != separator:
+                raise DistutilsOptionError(
+                    'Unable to parse option value to dict: %s' % value)
+            result[key.strip()] = val.strip()
+
+        return result
+
+    @classmethod
+    def _parse_bool(cls, value):
+        """Represents value as boolean.
+
+        :param value:
+        :rtype: bool
+        """
+        value = value.lower()
+        return value in ('1', 'true', 'yes')
+
+    @classmethod
+    def _parse_file(cls, value):
+        """Represents value as a string, allowing including text
+        from nearest files using `file:` directive.
+
+        Directive is sandboxed and won't reach anything outside
+        directory with setup.py.
+
+        Examples:
+            file: LICENSE
+            file: README.rst, CHANGELOG.md, src/file.txt
+
+        :param str value:
+        :rtype: str
+        """
+        include_directive = 'file:'
+
+        if not isinstance(value, string_types):
+            return value
+
+        if not value.startswith(include_directive):
+            return value
+
+        spec = value[len(include_directive):]
+        filepaths = (os.path.abspath(path.strip()) for path in spec.split(','))
+        return '\n'.join(
+            cls._read_file(path)
+            for path in filepaths
+            if (cls._assert_local(path) or True)
+            and os.path.isfile(path)
+        )
+
+    @staticmethod
+    def _assert_local(filepath):
+        if not filepath.startswith(os.getcwd()):
+            raise DistutilsOptionError(
+                '`file:` directive can not access %s' % filepath)
+
+    @staticmethod
+    def _read_file(filepath):
+        with io.open(filepath, encoding='utf-8') as f:
+            return f.read()
+
+    @classmethod
+    def _parse_attr(cls, value):
+        """Represents value as a module attribute.
+
+        Examples:
+            attr: package.attr
+            attr: package.module.attr
+
+        :param str value:
+        :rtype: str
+        """
+        attr_directive = 'attr:'
+        if not value.startswith(attr_directive):
+            return value
+
+        attrs_path = value.replace(attr_directive, '').strip().split('.')
+        attr_name = attrs_path.pop()
+
+        module_name = '.'.join(attrs_path)
+        module_name = module_name or '__init__'
+
+        sys.path.insert(0, os.getcwd())
+        try:
+            module = import_module(module_name)
+            value = getattr(module, attr_name)
+
+        finally:
+            sys.path = sys.path[1:]
+
+        return value
+
+    @classmethod
+    def _get_parser_compound(cls, *parse_methods):
+        """Returns parser function to represents value as a list.
+
+        Parses a value applying given methods one after another.
+
+        :param parse_methods:
+        :rtype: callable
+        """
+        def parse(value):
+            parsed = value
+
+            for method in parse_methods:
+                parsed = method(parsed)
+
+            return parsed
+
+        return parse
+
+    @classmethod
+    def _parse_section_to_dict(cls, section_options, values_parser=None):
+        """Parses section options into a dictionary.
+
+        Optionally applies a given parser to values.
+
+        :param dict section_options:
+        :param callable values_parser:
+        :rtype: dict
+        """
+        value = {}
+        values_parser = values_parser or (lambda val: val)
+        for key, (_, val) in section_options.items():
+            value[key] = values_parser(val)
+        return value
+
+    def parse_section(self, section_options):
+        """Parses configuration file section.
+
+        :param dict section_options:
+        """
+        for (name, (_, value)) in section_options.items():
+            try:
+                self[name] = value
+
+            except KeyError:
+                pass  # Keep silent for a new option may appear anytime.
+
+    def parse(self):
+        """Parses configuration file items from one
+        or more related sections.
+
+        """
+        for section_name, section_options in self.sections.items():
+
+            method_postfix = ''
+            if section_name:  # [section.option] variant
+                method_postfix = '_%s' % section_name
+
+            section_parser_method = getattr(
+                self,
+                # Dots in section names are tranlsated into dunderscores.
+                ('parse_section%s' % method_postfix).replace('.', '__'),
+                None)
+
+            if section_parser_method is None:
+                raise DistutilsOptionError(
+                    'Unsupported distribution option section: [%s.%s]' % (
+                        self.section_prefix, section_name))
+
+            section_parser_method(section_options)
+
+
+class ConfigMetadataHandler(ConfigHandler):
+
+    section_prefix = 'metadata'
+
+    aliases = {
+        'home_page': 'url',
+        'summary': 'description',
+        'classifier': 'classifiers',
+        'platform': 'platforms',
+    }
+
+    strict_mode = False
+    """We need to keep it loose, to be partially compatible with
+    `pbr` and `d2to1` packages which also uses `metadata` section.
+
+    """
+
+    @property
+    def parsers(self):
+        """Metadata item name to parser function mapping."""
+        parse_list = self._parse_list
+        parse_file = self._parse_file
+        parse_dict = self._parse_dict
+
+        return {
+            'platforms': parse_list,
+            'keywords': parse_list,
+            'provides': parse_list,
+            'requires': parse_list,
+            'obsoletes': parse_list,
+            'classifiers': self._get_parser_compound(parse_file, parse_list),
+            'license': parse_file,
+            'description': parse_file,
+            'long_description': parse_file,
+            'version': self._parse_version,
+            'project_urls': parse_dict,
+        }
+
+    def _parse_version(self, value):
+        """Parses `version` option value.
+
+        :param value:
+        :rtype: str
+
+        """
+        version = self._parse_attr(value)
+
+        if callable(version):
+            version = version()
+
+        if not isinstance(version, string_types):
+            if hasattr(version, '__iter__'):
+                version = '.'.join(map(str, version))
+            else:
+                version = '%s' % version
+
+        return version
+
+
+class ConfigOptionsHandler(ConfigHandler):
+
+    section_prefix = 'options'
+
+    @property
+    def parsers(self):
+        """Metadata item name to parser function mapping."""
+        parse_list = self._parse_list
+        parse_list_semicolon = partial(self._parse_list, separator=';')
+        parse_bool = self._parse_bool
+        parse_dict = self._parse_dict
+
+        return {
+            'zip_safe': parse_bool,
+            'use_2to3': parse_bool,
+            'include_package_data': parse_bool,
+            'package_dir': parse_dict,
+            'use_2to3_fixers': parse_list,
+            'use_2to3_exclude_fixers': parse_list,
+            'convert_2to3_doctests': parse_list,
+            'scripts': parse_list,
+            'eager_resources': parse_list,
+            'dependency_links': parse_list,
+            'namespace_packages': parse_list,
+            'install_requires': parse_list_semicolon,
+            'setup_requires': parse_list_semicolon,
+            'tests_require': parse_list_semicolon,
+            'packages': self._parse_packages,
+            'entry_points': self._parse_file,
+            'py_modules': parse_list,
+        }
+
+    def _parse_packages(self, value):
+        """Parses `packages` option value.
+
+        :param value:
+        :rtype: list
+        """
+        find_directive = 'find:'
+
+        if not value.startswith(find_directive):
+            return self._parse_list(value)
+
+        # Read function arguments from a dedicated section.
+        find_kwargs = self.parse_section_packages__find(
+            self.sections.get('packages.find', {}))
+
+        from setuptools import find_packages
+
+        return find_packages(**find_kwargs)
+
+    def parse_section_packages__find(self, section_options):
+        """Parses `packages.find` configuration file section.
+
+        To be used in conjunction with _parse_packages().
+
+        :param dict section_options:
+        """
+        section_data = self._parse_section_to_dict(
+            section_options, self._parse_list)
+
+        valid_keys = ['where', 'include', 'exclude']
+
+        find_kwargs = dict(
+            [(k, v) for k, v in section_data.items() if k in valid_keys and v])
+
+        where = find_kwargs.get('where')
+        if where is not None:
+            find_kwargs['where'] = where[0]  # cast list to single val
+
+        return find_kwargs
+
+    def parse_section_entry_points(self, section_options):
+        """Parses `entry_points` configuration file section.
+
+        :param dict section_options:
+        """
+        parsed = self._parse_section_to_dict(section_options, self._parse_list)
+        self['entry_points'] = parsed
+
+    def _parse_package_data(self, section_options):
+        parsed = self._parse_section_to_dict(section_options, self._parse_list)
+
+        root = parsed.get('*')
+        if root:
+            parsed[''] = root
+            del parsed['*']
+
+        return parsed
+
+    def parse_section_package_data(self, section_options):
+        """Parses `package_data` configuration file section.
+
+        :param dict section_options:
+        """
+        self['package_data'] = self._parse_package_data(section_options)
+
+    def parse_section_exclude_package_data(self, section_options):
+        """Parses `exclude_package_data` configuration file section.
+
+        :param dict section_options:
+        """
+        self['exclude_package_data'] = self._parse_package_data(
+            section_options)
+
+    def parse_section_extras_require(self, section_options):
+        """Parses `extras_require` configuration file section.
+
+        :param dict section_options:
+        """
+        parse_list = partial(self._parse_list, separator=';')
+        self['extras_require'] = self._parse_section_to_dict(
+            section_options, parse_list)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/dep_util.py b/vendor/setuptools-39.0.1/build/lib/setuptools/dep_util.py
new file mode 100644
index 00000000..2931c13e
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/dep_util.py
@@ -0,0 +1,23 @@
+from distutils.dep_util import newer_group
+
+# yes, this is was almost entirely copy-pasted from
+# 'newer_pairwise()', this is just another convenience
+# function.
+def newer_pairwise_group(sources_groups, targets):
+    """Walk both arguments in parallel, testing if each source group is newer
+    than its corresponding target. Returns a pair of lists (sources_groups,
+    targets) where sources is newer than target, according to the semantics
+    of 'newer_group()'.
+    """
+    if len(sources_groups) != len(targets):
+        raise ValueError("'sources_group' and 'targets' must be the same length")
+
+    # build a pair of lists (sources_groups, targets) where source is newer
+    n_sources = []
+    n_targets = []
+    for i in range(len(sources_groups)):
+        if newer_group(sources_groups[i], targets[i]):
+            n_sources.append(sources_groups[i])
+            n_targets.append(targets[i])
+
+    return n_sources, n_targets
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/depends.py b/vendor/setuptools-39.0.1/build/lib/setuptools/depends.py
new file mode 100644
index 00000000..45e7052d
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/depends.py
@@ -0,0 +1,186 @@
+import sys
+import imp
+import marshal
+from distutils.version import StrictVersion
+from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN
+
+from .py33compat import Bytecode
+
+
+__all__ = [
+    'Require', 'find_module', 'get_module_constant', 'extract_constant'
+]
+
+
+class Require:
+    """A prerequisite to building or installing a distribution"""
+
+    def __init__(self, name, requested_version, module, homepage='',
+            attribute=None, format=None):
+
+        if format is None and requested_version is not None:
+            format = StrictVersion
+
+        if format is not None:
+            requested_version = format(requested_version)
+            if attribute is None:
+                attribute = '__version__'
+
+        self.__dict__.update(locals())
+        del self.self
+
+    def full_name(self):
+        """Return full package/distribution name, w/version"""
+        if self.requested_version is not None:
+            return '%s-%s' % (self.name, self.requested_version)
+        return self.name
+
+    def version_ok(self, version):
+        """Is 'version' sufficiently up-to-date?"""
+        return self.attribute is None or self.format is None or \
+            str(version) != "unknown" and version >= self.requested_version
+
+    def get_version(self, paths=None, default="unknown"):
+        """Get version number of installed module, 'None', or 'default'
+
+        Search 'paths' for module.  If not found, return 'None'.  If found,
+        return the extracted version attribute, or 'default' if no version
+        attribute was specified, or the value cannot be determined without
+        importing the module.  The version is formatted according to the
+        requirement's version format (if any), unless it is 'None' or the
+        supplied 'default'.
+        """
+
+        if self.attribute is None:
+            try:
+                f, p, i = find_module(self.module, paths)
+                if f:
+                    f.close()
+                return default
+            except ImportError:
+                return None
+
+        v = get_module_constant(self.module, self.attribute, default, paths)
+
+        if v is not None and v is not default and self.format is not None:
+            return self.format(v)
+
+        return v
+
+    def is_present(self, paths=None):
+        """Return true if dependency is present on 'paths'"""
+        return self.get_version(paths) is not None
+
+    def is_current(self, paths=None):
+        """Return true if dependency is present and up-to-date on 'paths'"""
+        version = self.get_version(paths)
+        if version is None:
+            return False
+        return self.version_ok(version)
+
+
+def find_module(module, paths=None):
+    """Just like 'imp.find_module()', but with package support"""
+
+    parts = module.split('.')
+
+    while parts:
+        part = parts.pop(0)
+        f, path, (suffix, mode, kind) = info = imp.find_module(part, paths)
+
+        if kind == PKG_DIRECTORY:
+            parts = parts or ['__init__']
+            paths = [path]
+
+        elif parts:
+            raise ImportError("Can't find %r in %s" % (parts, module))
+
+    return info
+
+
+def get_module_constant(module, symbol, default=-1, paths=None):
+    """Find 'module' by searching 'paths', and extract 'symbol'
+
+    Return 'None' if 'module' does not exist on 'paths', or it does not define
+    'symbol'.  If the module defines 'symbol' as a constant, return the
+    constant.  Otherwise, return 'default'."""
+
+    try:
+        f, path, (suffix, mode, kind) = find_module(module, paths)
+    except ImportError:
+        # Module doesn't exist
+        return None
+
+    try:
+        if kind == PY_COMPILED:
+            f.read(8)  # skip magic & date
+            code = marshal.load(f)
+        elif kind == PY_FROZEN:
+            code = imp.get_frozen_object(module)
+        elif kind == PY_SOURCE:
+            code = compile(f.read(), path, 'exec')
+        else:
+            # Not something we can parse; we'll have to import it.  :(
+            if module not in sys.modules:
+                imp.load_module(module, f, path, (suffix, mode, kind))
+            return getattr(sys.modules[module], symbol, None)
+
+    finally:
+        if f:
+            f.close()
+
+    return extract_constant(code, symbol, default)
+
+
+def extract_constant(code, symbol, default=-1):
+    """Extract the constant value of 'symbol' from 'code'
+
+    If the name 'symbol' is bound to a constant value by the Python code
+    object 'code', return that value.  If 'symbol' is bound to an expression,
+    return 'default'.  Otherwise, return 'None'.
+
+    Return value is based on the first assignment to 'symbol'.  'symbol' must
+    be a global, or at least a non-"fast" local in the code block.  That is,
+    only 'STORE_NAME' and 'STORE_GLOBAL' opcodes are checked, and 'symbol'
+    must be present in 'code.co_names'.
+    """
+    if symbol not in code.co_names:
+        # name's not there, can't possibly be an assignment
+        return None
+
+    name_idx = list(code.co_names).index(symbol)
+
+    STORE_NAME = 90
+    STORE_GLOBAL = 97
+    LOAD_CONST = 100
+
+    const = default
+
+    for byte_code in Bytecode(code):
+        op = byte_code.opcode
+        arg = byte_code.arg
+
+        if op == LOAD_CONST:
+            const = code.co_consts[arg]
+        elif arg == name_idx and (op == STORE_NAME or op == STORE_GLOBAL):
+            return const
+        else:
+            const = default
+
+
+def _update_globals():
+    """
+    Patch the globals to remove the objects not available on some platforms.
+
+    XXX it'd be better to test assertions about bytecode instead.
+    """
+
+    if not sys.platform.startswith('java') and sys.platform != 'cli':
+        return
+    incompatible = 'extract_constant', 'get_module_constant'
+    for name in incompatible:
+        del globals()[name]
+        __all__.remove(name)
+
+
+_update_globals()
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/dist.py b/vendor/setuptools-39.0.1/build/lib/setuptools/dist.py
new file mode 100644
index 00000000..284d922d
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/dist.py
@@ -0,0 +1,1070 @@
+# -*- coding: utf-8 -*-
+__all__ = ['Distribution']
+
+import re
+import os
+import warnings
+import numbers
+import distutils.log
+import distutils.core
+import distutils.cmd
+import distutils.dist
+import itertools
+from collections import defaultdict
+from distutils.errors import (
+    DistutilsOptionError, DistutilsPlatformError, DistutilsSetupError,
+)
+from distutils.util import rfc822_escape
+from distutils.version import StrictVersion
+
+from setuptools.extern import six
+from setuptools.extern import packaging
+from setuptools.extern.six.moves import map, filter, filterfalse
+
+from setuptools.depends import Require
+from setuptools import windows_support
+from setuptools.monkey import get_unpatched
+from setuptools.config import parse_configuration
+import pkg_resources
+from .py36compat import Distribution_parse_config_files
+
+__import__('setuptools.extern.packaging.specifiers')
+__import__('setuptools.extern.packaging.version')
+
+
+def _get_unpatched(cls):
+    warnings.warn("Do not call this function", DeprecationWarning)
+    return get_unpatched(cls)
+
+
+def get_metadata_version(dist_md):
+    if dist_md.long_description_content_type or dist_md.provides_extras:
+        return StrictVersion('2.1')
+    elif (dist_md.maintainer is not None or
+          dist_md.maintainer_email is not None or
+          getattr(dist_md, 'python_requires', None) is not None):
+        return StrictVersion('1.2')
+    elif (dist_md.provides or dist_md.requires or dist_md.obsoletes or
+            dist_md.classifiers or dist_md.download_url):
+        return StrictVersion('1.1')
+
+    return StrictVersion('1.0')
+
+
+# Based on Python 3.5 version
+def write_pkg_file(self, file):
+    """Write the PKG-INFO format data to a file object.
+    """
+    version = get_metadata_version(self)
+
+    file.write('Metadata-Version: %s\n' % version)
+    file.write('Name: %s\n' % self.get_name())
+    file.write('Version: %s\n' % self.get_version())
+    file.write('Summary: %s\n' % self.get_description())
+    file.write('Home-page: %s\n' % self.get_url())
+
+    if version < StrictVersion('1.2'):
+        file.write('Author: %s\n' % self.get_contact())
+        file.write('Author-email: %s\n' % self.get_contact_email())
+    else:
+        optional_fields = (
+            ('Author', 'author'),
+            ('Author-email', 'author_email'),
+            ('Maintainer', 'maintainer'),
+            ('Maintainer-email', 'maintainer_email'),
+        )
+
+        for field, attr in optional_fields:
+            attr_val = getattr(self, attr)
+            if six.PY2:
+                attr_val = self._encode_field(attr_val)
+
+            if attr_val is not None:
+                file.write('%s: %s\n' % (field, attr_val))
+
+    file.write('License: %s\n' % self.get_license())
+    if self.download_url:
+        file.write('Download-URL: %s\n' % self.download_url)
+    for project_url in self.project_urls.items():
+        file.write('Project-URL: %s, %s\n' % project_url)
+
+    long_desc = rfc822_escape(self.get_long_description())
+    file.write('Description: %s\n' % long_desc)
+
+    keywords = ','.join(self.get_keywords())
+    if keywords:
+        file.write('Keywords: %s\n' % keywords)
+
+    if version >= StrictVersion('1.2'):
+        for platform in self.get_platforms():
+            file.write('Platform: %s\n' % platform)
+    else:
+        self._write_list(file, 'Platform', self.get_platforms())
+
+    self._write_list(file, 'Classifier', self.get_classifiers())
+
+    # PEP 314
+    self._write_list(file, 'Requires', self.get_requires())
+    self._write_list(file, 'Provides', self.get_provides())
+    self._write_list(file, 'Obsoletes', self.get_obsoletes())
+
+    # Setuptools specific for PEP 345
+    if hasattr(self, 'python_requires'):
+        file.write('Requires-Python: %s\n' % self.python_requires)
+
+    # PEP 566
+    if self.long_description_content_type:
+        file.write(
+            'Description-Content-Type: %s\n' %
+            self.long_description_content_type
+        )
+    if self.provides_extras:
+        for extra in self.provides_extras:
+            file.write('Provides-Extra: %s\n' % extra)
+
+
+# from Python 3.4
+def write_pkg_info(self, base_dir):
+    """Write the PKG-INFO file into the release tree.
+    """
+    with open(os.path.join(base_dir, 'PKG-INFO'), 'w',
+              encoding='UTF-8') as pkg_info:
+        self.write_pkg_file(pkg_info)
+
+
+sequence = tuple, list
+
+
+def check_importable(dist, attr, value):
+    try:
+        ep = pkg_resources.EntryPoint.parse('x=' + value)
+        assert not ep.extras
+    except (TypeError, ValueError, AttributeError, AssertionError):
+        raise DistutilsSetupError(
+            "%r must be importable 'module:attrs' string (got %r)"
+            % (attr, value)
+        )
+
+
+def assert_string_list(dist, attr, value):
+    """Verify that value is a string list or None"""
+    try:
+        assert ''.join(value) != value
+    except (TypeError, ValueError, AttributeError, AssertionError):
+        raise DistutilsSetupError(
+            "%r must be a list of strings (got %r)" % (attr, value)
+        )
+
+
+def check_nsp(dist, attr, value):
+    """Verify that namespace packages are valid"""
+    ns_packages = value
+    assert_string_list(dist, attr, ns_packages)
+    for nsp in ns_packages:
+        if not dist.has_contents_for(nsp):
+            raise DistutilsSetupError(
+                "Distribution contains no modules or packages for " +
+                "namespace package %r" % nsp
+            )
+        parent, sep, child = nsp.rpartition('.')
+        if parent and parent not in ns_packages:
+            distutils.log.warn(
+                "WARNING: %r is declared as a package namespace, but %r"
+                " is not: please correct this in setup.py", nsp, parent
+            )
+
+
+def check_extras(dist, attr, value):
+    """Verify that extras_require mapping is valid"""
+    try:
+        list(itertools.starmap(_check_extra, value.items()))
+    except (TypeError, ValueError, AttributeError):
+        raise DistutilsSetupError(
+            "'extras_require' must be a dictionary whose values are "
+            "strings or lists of strings containing valid project/version "
+            "requirement specifiers."
+        )
+
+
+def _check_extra(extra, reqs):
+    name, sep, marker = extra.partition(':')
+    if marker and pkg_resources.invalid_marker(marker):
+        raise DistutilsSetupError("Invalid environment marker: " + marker)
+    list(pkg_resources.parse_requirements(reqs))
+
+
+def assert_bool(dist, attr, value):
+    """Verify that value is True, False, 0, or 1"""
+    if bool(value) != value:
+        tmpl = "{attr!r} must be a boolean value (got {value!r})"
+        raise DistutilsSetupError(tmpl.format(attr=attr, value=value))
+
+
+def check_requirements(dist, attr, value):
+    """Verify that install_requires is a valid requirements list"""
+    try:
+        list(pkg_resources.parse_requirements(value))
+        if isinstance(value, (dict, set)):
+            raise TypeError("Unordered types are not allowed")
+    except (TypeError, ValueError) as error:
+        tmpl = (
+            "{attr!r} must be a string or list of strings "
+            "containing valid project/version requirement specifiers; {error}"
+        )
+        raise DistutilsSetupError(tmpl.format(attr=attr, error=error))
+
+
+def check_specifier(dist, attr, value):
+    """Verify that value is a valid version specifier"""
+    try:
+        packaging.specifiers.SpecifierSet(value)
+    except packaging.specifiers.InvalidSpecifier as error:
+        tmpl = (
+            "{attr!r} must be a string "
+            "containing valid version specifiers; {error}"
+        )
+        raise DistutilsSetupError(tmpl.format(attr=attr, error=error))
+
+
+def check_entry_points(dist, attr, value):
+    """Verify that entry_points map is parseable"""
+    try:
+        pkg_resources.EntryPoint.parse_map(value)
+    except ValueError as e:
+        raise DistutilsSetupError(e)
+
+
+def check_test_suite(dist, attr, value):
+    if not isinstance(value, six.string_types):
+        raise DistutilsSetupError("test_suite must be a string")
+
+
+def check_package_data(dist, attr, value):
+    """Verify that value is a dictionary of package names to glob lists"""
+    if isinstance(value, dict):
+        for k, v in value.items():
+            if not isinstance(k, str):
+                break
+            try:
+                iter(v)
+            except TypeError:
+                break
+        else:
+            return
+    raise DistutilsSetupError(
+        attr + " must be a dictionary mapping package names to lists of "
+        "wildcard patterns"
+    )
+
+
+def check_packages(dist, attr, value):
+    for pkgname in value:
+        if not re.match(r'\w+(\.\w+)*', pkgname):
+            distutils.log.warn(
+                "WARNING: %r not a valid package name; please use only "
+                ".-separated package names in setup.py", pkgname
+            )
+
+
+_Distribution = get_unpatched(distutils.core.Distribution)
+
+
+class Distribution(Distribution_parse_config_files, _Distribution):
+    """Distribution with support for features, tests, and package data
+
+    This is an enhanced version of 'distutils.dist.Distribution' that
+    effectively adds the following new optional keyword arguments to 'setup()':
+
+     'install_requires' -- a string or sequence of strings specifying project
+        versions that the distribution requires when installed, in the format
+        used by 'pkg_resources.require()'.  They will be installed
+        automatically when the package is installed.  If you wish to use
+        packages that are not available in PyPI, or want to give your users an
+        alternate download location, you can add a 'find_links' option to the
+        '[easy_install]' section of your project's 'setup.cfg' file, and then
+        setuptools will scan the listed web pages for links that satisfy the
+        requirements.
+
+     'extras_require' -- a dictionary mapping names of optional "extras" to the
+        additional requirement(s) that using those extras incurs. For example,
+        this::
+
+            extras_require = dict(reST = ["docutils>=0.3", "reSTedit"])
+
+        indicates that the distribution can optionally provide an extra
+        capability called "reST", but it can only be used if docutils and
+        reSTedit are installed.  If the user installs your package using
+        EasyInstall and requests one of your extras, the corresponding
+        additional requirements will be installed if needed.
+
+     'features' **deprecated** -- a dictionary mapping option names to
+        'setuptools.Feature'
+        objects.  Features are a portion of the distribution that can be
+        included or excluded based on user options, inter-feature dependencies,
+        and availability on the current system.  Excluded features are omitted
+        from all setup commands, including source and binary distributions, so
+        you can create multiple distributions from the same source tree.
+        Feature names should be valid Python identifiers, except that they may
+        contain the '-' (minus) sign.  Features can be included or excluded
+        via the command line options '--with-X' and '--without-X', where 'X' is
+        the name of the feature.  Whether a feature is included by default, and
+        whether you are allowed to control this from the command line, is
+        determined by the Feature object.  See the 'Feature' class for more
+        information.
+
+     'test_suite' -- the name of a test suite to run for the 'test' command.
+        If the user runs 'python setup.py test', the package will be installed,
+        and the named test suite will be run.  The format is the same as
+        would be used on a 'unittest.py' command line.  That is, it is the
+        dotted name of an object to import and call to generate a test suite.
+
+     'package_data' -- a dictionary mapping package names to lists of filenames
+        or globs to use to find data files contained in the named packages.
+        If the dictionary has filenames or globs listed under '""' (the empty
+        string), those names will be searched for in every package, in addition
+        to any names for the specific package.  Data files found using these
+        names/globs will be installed along with the package, in the same
+        location as the package.  Note that globs are allowed to reference
+        the contents of non-package subdirectories, as long as you use '/' as
+        a path separator.  (Globs are automatically converted to
+        platform-specific paths at runtime.)
+
+    In addition to these new keywords, this class also has several new methods
+    for manipulating the distribution's contents.  For example, the 'include()'
+    and 'exclude()' methods can be thought of as in-place add and subtract
+    commands that add or remove packages, modules, extensions, and so on from
+    the distribution.  They are used by the feature subsystem to configure the
+    distribution for the included and excluded features.
+    """
+
+    _patched_dist = None
+
+    def patch_missing_pkg_info(self, attrs):
+        # Fake up a replacement for the data that would normally come from
+        # PKG-INFO, but which might not yet be built if this is a fresh
+        # checkout.
+        #
+        if not attrs or 'name' not in attrs or 'version' not in attrs:
+            return
+        key = pkg_resources.safe_name(str(attrs['name'])).lower()
+        dist = pkg_resources.working_set.by_key.get(key)
+        if dist is not None and not dist.has_metadata('PKG-INFO'):
+            dist._version = pkg_resources.safe_version(str(attrs['version']))
+            self._patched_dist = dist
+
+    def __init__(self, attrs=None):
+        have_package_data = hasattr(self, "package_data")
+        if not have_package_data:
+            self.package_data = {}
+        attrs = attrs or {}
+        if 'features' in attrs or 'require_features' in attrs:
+            Feature.warn_deprecated()
+        self.require_features = []
+        self.features = {}
+        self.dist_files = []
+        self.src_root = attrs.pop("src_root", None)
+        self.patch_missing_pkg_info(attrs)
+        self.project_urls = attrs.get('project_urls', {})
+        self.dependency_links = attrs.pop('dependency_links', [])
+        self.setup_requires = attrs.pop('setup_requires', [])
+        for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'):
+            vars(self).setdefault(ep.name, None)
+        _Distribution.__init__(self, attrs)
+
+        # The project_urls attribute may not be supported in distutils, so
+        # prime it here from our value if not automatically set
+        self.metadata.project_urls = getattr(
+            self.metadata, 'project_urls', self.project_urls)
+        self.metadata.long_description_content_type = attrs.get(
+            'long_description_content_type'
+        )
+        self.metadata.provides_extras = getattr(
+            self.metadata, 'provides_extras', set()
+        )
+
+        if isinstance(self.metadata.version, numbers.Number):
+            # Some people apparently take "version number" too literally :)
+            self.metadata.version = str(self.metadata.version)
+
+        if self.metadata.version is not None:
+            try:
+                ver = packaging.version.Version(self.metadata.version)
+                normalized_version = str(ver)
+                if self.metadata.version != normalized_version:
+                    warnings.warn(
+                        "Normalizing '%s' to '%s'" % (
+                            self.metadata.version,
+                            normalized_version,
+                        )
+                    )
+                    self.metadata.version = normalized_version
+            except (packaging.version.InvalidVersion, TypeError):
+                warnings.warn(
+                    "The version specified (%r) is an invalid version, this "
+                    "may not work as expected with newer versions of "
+                    "setuptools, pip, and PyPI. Please see PEP 440 for more "
+                    "details." % self.metadata.version
+                )
+        self._finalize_requires()
+
+    def _finalize_requires(self):
+        """
+        Set `metadata.python_requires` and fix environment markers
+        in `install_requires` and `extras_require`.
+        """
+        if getattr(self, 'python_requires', None):
+            self.metadata.python_requires = self.python_requires
+
+        if getattr(self, 'extras_require', None):
+            for extra in self.extras_require.keys():
+                # Since this gets called multiple times at points where the
+                # keys have become 'converted' extras, ensure that we are only
+                # truly adding extras we haven't seen before here.
+                extra = extra.split(':')[0]
+                if extra:
+                    self.metadata.provides_extras.add(extra)
+
+        self._convert_extras_requirements()
+        self._move_install_requirements_markers()
+
+    def _convert_extras_requirements(self):
+        """
+        Convert requirements in `extras_require` of the form
+        `"extra": ["barbazquux; {marker}"]` to
+        `"extra:{marker}": ["barbazquux"]`.
+        """
+        spec_ext_reqs = getattr(self, 'extras_require', None) or {}
+        self._tmp_extras_require = defaultdict(list)
+        for section, v in spec_ext_reqs.items():
+            # Do not strip empty sections.
+            self._tmp_extras_require[section]
+            for r in pkg_resources.parse_requirements(v):
+                suffix = self._suffix_for(r)
+                self._tmp_extras_require[section + suffix].append(r)
+
+    @staticmethod
+    def _suffix_for(req):
+        """
+        For a requirement, return the 'extras_require' suffix for
+        that requirement.
+        """
+        return ':' + str(req.marker) if req.marker else ''
+
+    def _move_install_requirements_markers(self):
+        """
+        Move requirements in `install_requires` that are using environment
+        markers `extras_require`.
+        """
+
+        # divide the install_requires into two sets, simple ones still
+        # handled by install_requires and more complex ones handled
+        # by extras_require.
+
+        def is_simple_req(req):
+            return not req.marker
+
+        spec_inst_reqs = getattr(self, 'install_requires', None) or ()
+        inst_reqs = list(pkg_resources.parse_requirements(spec_inst_reqs))
+        simple_reqs = filter(is_simple_req, inst_reqs)
+        complex_reqs = filterfalse(is_simple_req, inst_reqs)
+        self.install_requires = list(map(str, simple_reqs))
+
+        for r in complex_reqs:
+            self._tmp_extras_require[':' + str(r.marker)].append(r)
+        self.extras_require = dict(
+            (k, [str(r) for r in map(self._clean_req, v)])
+            for k, v in self._tmp_extras_require.items()
+        )
+
+    def _clean_req(self, req):
+        """
+        Given a Requirement, remove environment markers and return it.
+        """
+        req.marker = None
+        return req
+
+    def parse_config_files(self, filenames=None, ignore_option_errors=False):
+        """Parses configuration files from various levels
+        and loads configuration.
+
+        """
+        _Distribution.parse_config_files(self, filenames=filenames)
+
+        parse_configuration(self, self.command_options,
+                            ignore_option_errors=ignore_option_errors)
+        self._finalize_requires()
+
+    def parse_command_line(self):
+        """Process features after parsing command line options"""
+        result = _Distribution.parse_command_line(self)
+        if self.features:
+            self._finalize_features()
+        return result
+
+    def _feature_attrname(self, name):
+        """Convert feature name to corresponding option attribute name"""
+        return 'with_' + name.replace('-', '_')
+
+    def fetch_build_eggs(self, requires):
+        """Resolve pre-setup requirements"""
+        resolved_dists = pkg_resources.working_set.resolve(
+            pkg_resources.parse_requirements(requires),
+            installer=self.fetch_build_egg,
+            replace_conflicting=True,
+        )
+        for dist in resolved_dists:
+            pkg_resources.working_set.add(dist, replace=True)
+        return resolved_dists
+
+    def finalize_options(self):
+        _Distribution.finalize_options(self)
+        if self.features:
+            self._set_global_opts_from_features()
+
+        for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'):
+            value = getattr(self, ep.name, None)
+            if value is not None:
+                ep.require(installer=self.fetch_build_egg)
+                ep.load()(self, ep.name, value)
+        if getattr(self, 'convert_2to3_doctests', None):
+            # XXX may convert to set here when we can rely on set being builtin
+            self.convert_2to3_doctests = [
+                os.path.abspath(p)
+                for p in self.convert_2to3_doctests
+            ]
+        else:
+            self.convert_2to3_doctests = []
+
+    def get_egg_cache_dir(self):
+        egg_cache_dir = os.path.join(os.curdir, '.eggs')
+        if not os.path.exists(egg_cache_dir):
+            os.mkdir(egg_cache_dir)
+            windows_support.hide_file(egg_cache_dir)
+            readme_txt_filename = os.path.join(egg_cache_dir, 'README.txt')
+            with open(readme_txt_filename, 'w') as f:
+                f.write('This directory contains eggs that were downloaded '
+                        'by setuptools to build, test, and run plug-ins.\n\n')
+                f.write('This directory caches those eggs to prevent '
+                        'repeated downloads.\n\n')
+                f.write('However, it is safe to delete this directory.\n\n')
+
+        return egg_cache_dir
+
+    def fetch_build_egg(self, req):
+        """Fetch an egg needed for building"""
+        from setuptools.command.easy_install import easy_install
+        dist = self.__class__({'script_args': ['easy_install']})
+        opts = dist.get_option_dict('easy_install')
+        opts.clear()
+        opts.update(
+            (k, v)
+            for k, v in self.get_option_dict('easy_install').items()
+            if k in (
+                # don't use any other settings
+                'find_links', 'site_dirs', 'index_url',
+                'optimize', 'site_dirs', 'allow_hosts',
+            ))
+        if self.dependency_links:
+            links = self.dependency_links[:]
+            if 'find_links' in opts:
+                links = opts['find_links'][1] + links
+            opts['find_links'] = ('setup', links)
+        install_dir = self.get_egg_cache_dir()
+        cmd = easy_install(
+            dist, args=["x"], install_dir=install_dir,
+            exclude_scripts=True,
+            always_copy=False, build_directory=None, editable=False,
+            upgrade=False, multi_version=True, no_report=True, user=False
+        )
+        cmd.ensure_finalized()
+        return cmd.easy_install(req)
+
+    def _set_global_opts_from_features(self):
+        """Add --with-X/--without-X options based on optional features"""
+
+        go = []
+        no = self.negative_opt.copy()
+
+        for name, feature in self.features.items():
+            self._set_feature(name, None)
+            feature.validate(self)
+
+            if feature.optional:
+                descr = feature.description
+                incdef = ' (default)'
+                excdef = ''
+                if not feature.include_by_default():
+                    excdef, incdef = incdef, excdef
+
+                new = (
+                    ('with-' + name, None, 'include ' + descr + incdef),
+                    ('without-' + name, None, 'exclude ' + descr + excdef),
+                )
+                go.extend(new)
+                no['without-' + name] = 'with-' + name
+
+        self.global_options = self.feature_options = go + self.global_options
+        self.negative_opt = self.feature_negopt = no
+
+    def _finalize_features(self):
+        """Add/remove features and resolve dependencies between them"""
+
+        # First, flag all the enabled items (and thus their dependencies)
+        for name, feature in self.features.items():
+            enabled = self.feature_is_included(name)
+            if enabled or (enabled is None and feature.include_by_default()):
+                feature.include_in(self)
+                self._set_feature(name, 1)
+
+        # Then disable the rest, so that off-by-default features don't
+        # get flagged as errors when they're required by an enabled feature
+        for name, feature in self.features.items():
+            if not self.feature_is_included(name):
+                feature.exclude_from(self)
+                self._set_feature(name, 0)
+
+    def get_command_class(self, command):
+        """Pluggable version of get_command_class()"""
+        if command in self.cmdclass:
+            return self.cmdclass[command]
+
+        eps = pkg_resources.iter_entry_points('distutils.commands', command)
+        for ep in eps:
+            ep.require(installer=self.fetch_build_egg)
+            self.cmdclass[command] = cmdclass = ep.load()
+            return cmdclass
+        else:
+            return _Distribution.get_command_class(self, command)
+
+    def print_commands(self):
+        for ep in pkg_resources.iter_entry_points('distutils.commands'):
+            if ep.name not in self.cmdclass:
+                # don't require extras as the commands won't be invoked
+                cmdclass = ep.resolve()
+                self.cmdclass[ep.name] = cmdclass
+        return _Distribution.print_commands(self)
+
+    def get_command_list(self):
+        for ep in pkg_resources.iter_entry_points('distutils.commands'):
+            if ep.name not in self.cmdclass:
+                # don't require extras as the commands won't be invoked
+                cmdclass = ep.resolve()
+                self.cmdclass[ep.name] = cmdclass
+        return _Distribution.get_command_list(self)
+
+    def _set_feature(self, name, status):
+        """Set feature's inclusion status"""
+        setattr(self, self._feature_attrname(name), status)
+
+    def feature_is_included(self, name):
+        """Return 1 if feature is included, 0 if excluded, 'None' if unknown"""
+        return getattr(self, self._feature_attrname(name))
+
+    def include_feature(self, name):
+        """Request inclusion of feature named 'name'"""
+
+        if self.feature_is_included(name) == 0:
+            descr = self.features[name].description
+            raise DistutilsOptionError(
+                descr + " is required, but was excluded or is not available"
+            )
+        self.features[name].include_in(self)
+        self._set_feature(name, 1)
+
+    def include(self, **attrs):
+        """Add items to distribution that are named in keyword arguments
+
+        For example, 'dist.exclude(py_modules=["x"])' would add 'x' to
+        the distribution's 'py_modules' attribute, if it was not already
+        there.
+
+        Currently, this method only supports inclusion for attributes that are
+        lists or tuples.  If you need to add support for adding to other
+        attributes in this or a subclass, you can add an '_include_X' method,
+        where 'X' is the name of the attribute.  The method will be called with
+        the value passed to 'include()'.  So, 'dist.include(foo={"bar":"baz"})'
+        will try to call 'dist._include_foo({"bar":"baz"})', which can then
+        handle whatever special inclusion logic is needed.
+        """
+        for k, v in attrs.items():
+            include = getattr(self, '_include_' + k, None)
+            if include:
+                include(v)
+            else:
+                self._include_misc(k, v)
+
+    def exclude_package(self, package):
+        """Remove packages, modules, and extensions in named package"""
+
+        pfx = package + '.'
+        if self.packages:
+            self.packages = [
+                p for p in self.packages
+                if p != package and not p.startswith(pfx)
+            ]
+
+        if self.py_modules:
+            self.py_modules = [
+                p for p in self.py_modules
+                if p != package and not p.startswith(pfx)
+            ]
+
+        if self.ext_modules:
+            self.ext_modules = [
+                p for p in self.ext_modules
+                if p.name != package and not p.name.startswith(pfx)
+            ]
+
+    def has_contents_for(self, package):
+        """Return true if 'exclude_package(package)' would do something"""
+
+        pfx = package + '.'
+
+        for p in self.iter_distribution_names():
+            if p == package or p.startswith(pfx):
+                return True
+
+    def _exclude_misc(self, name, value):
+        """Handle 'exclude()' for list/tuple attrs without a special handler"""
+        if not isinstance(value, sequence):
+            raise DistutilsSetupError(
+                "%s: setting must be a list or tuple (%r)" % (name, value)
+            )
+        try:
+            old = getattr(self, name)
+        except AttributeError:
+            raise DistutilsSetupError(
+                "%s: No such distribution setting" % name
+            )
+        if old is not None and not isinstance(old, sequence):
+            raise DistutilsSetupError(
+                name + ": this setting cannot be changed via include/exclude"
+            )
+        elif old:
+            setattr(self, name, [item for item in old if item not in value])
+
+    def _include_misc(self, name, value):
+        """Handle 'include()' for list/tuple attrs without a special handler"""
+
+        if not isinstance(value, sequence):
+            raise DistutilsSetupError(
+                "%s: setting must be a list (%r)" % (name, value)
+            )
+        try:
+            old = getattr(self, name)
+        except AttributeError:
+            raise DistutilsSetupError(
+                "%s: No such distribution setting" % name
+            )
+        if old is None:
+            setattr(self, name, value)
+        elif not isinstance(old, sequence):
+            raise DistutilsSetupError(
+                name + ": this setting cannot be changed via include/exclude"
+            )
+        else:
+            new = [item for item in value if item not in old]
+            setattr(self, name, old + new)
+
+    def exclude(self, **attrs):
+        """Remove items from distribution that are named in keyword arguments
+
+        For example, 'dist.exclude(py_modules=["x"])' would remove 'x' from
+        the distribution's 'py_modules' attribute.  Excluding packages uses
+        the 'exclude_package()' method, so all of the package's contained
+        packages, modules, and extensions are also excluded.
+
+        Currently, this method only supports exclusion from attributes that are
+        lists or tuples.  If you need to add support for excluding from other
+        attributes in this or a subclass, you can add an '_exclude_X' method,
+        where 'X' is the name of the attribute.  The method will be called with
+        the value passed to 'exclude()'.  So, 'dist.exclude(foo={"bar":"baz"})'
+        will try to call 'dist._exclude_foo({"bar":"baz"})', which can then
+        handle whatever special exclusion logic is needed.
+        """
+        for k, v in attrs.items():
+            exclude = getattr(self, '_exclude_' + k, None)
+            if exclude:
+                exclude(v)
+            else:
+                self._exclude_misc(k, v)
+
+    def _exclude_packages(self, packages):
+        if not isinstance(packages, sequence):
+            raise DistutilsSetupError(
+                "packages: setting must be a list or tuple (%r)" % (packages,)
+            )
+        list(map(self.exclude_package, packages))
+
+    def _parse_command_opts(self, parser, args):
+        # Remove --with-X/--without-X options when processing command args
+        self.global_options = self.__class__.global_options
+        self.negative_opt = self.__class__.negative_opt
+
+        # First, expand any aliases
+        command = args[0]
+        aliases = self.get_option_dict('aliases')
+        while command in aliases:
+            src, alias = aliases[command]
+            del aliases[command]  # ensure each alias can expand only once!
+            import shlex
+            args[:1] = shlex.split(alias, True)
+            command = args[0]
+
+        nargs = _Distribution._parse_command_opts(self, parser, args)
+
+        # Handle commands that want to consume all remaining arguments
+        cmd_class = self.get_command_class(command)
+        if getattr(cmd_class, 'command_consumes_arguments', None):
+            self.get_option_dict(command)['args'] = ("command line", nargs)
+            if nargs is not None:
+                return []
+
+        return nargs
+
+    def get_cmdline_options(self):
+        """Return a '{cmd: {opt:val}}' map of all command-line options
+
+        Option names are all long, but do not include the leading '--', and
+        contain dashes rather than underscores.  If the option doesn't take
+        an argument (e.g. '--quiet'), the 'val' is 'None'.
+
+        Note that options provided by config files are intentionally excluded.
+        """
+
+        d = {}
+
+        for cmd, opts in self.command_options.items():
+
+            for opt, (src, val) in opts.items():
+
+                if src != "command line":
+                    continue
+
+                opt = opt.replace('_', '-')
+
+                if val == 0:
+                    cmdobj = self.get_command_obj(cmd)
+                    neg_opt = self.negative_opt.copy()
+                    neg_opt.update(getattr(cmdobj, 'negative_opt', {}))
+                    for neg, pos in neg_opt.items():
+                        if pos == opt:
+                            opt = neg
+                            val = None
+                            break
+                    else:
+                        raise AssertionError("Shouldn't be able to get here")
+
+                elif val == 1:
+                    val = None
+
+                d.setdefault(cmd, {})[opt] = val
+
+        return d
+
+    def iter_distribution_names(self):
+        """Yield all packages, modules, and extension names in distribution"""
+
+        for pkg in self.packages or ():
+            yield pkg
+
+        for module in self.py_modules or ():
+            yield module
+
+        for ext in self.ext_modules or ():
+            if isinstance(ext, tuple):
+                name, buildinfo = ext
+            else:
+                name = ext.name
+            if name.endswith('module'):
+                name = name[:-6]
+            yield name
+
+    def handle_display_options(self, option_order):
+        """If there were any non-global "display-only" options
+        (--help-commands or the metadata display options) on the command
+        line, display the requested info and return true; else return
+        false.
+        """
+        import sys
+
+        if six.PY2 or self.help_commands:
+            return _Distribution.handle_display_options(self, option_order)
+
+        # Stdout may be StringIO (e.g. in tests)
+        import io
+        if not isinstance(sys.stdout, io.TextIOWrapper):
+            return _Distribution.handle_display_options(self, option_order)
+
+        # Don't wrap stdout if utf-8 is already the encoding. Provides
+        #  workaround for #334.
+        if sys.stdout.encoding.lower() in ('utf-8', 'utf8'):
+            return _Distribution.handle_display_options(self, option_order)
+
+        # Print metadata in UTF-8 no matter the platform
+        encoding = sys.stdout.encoding
+        errors = sys.stdout.errors
+        newline = sys.platform != 'win32' and '\n' or None
+        line_buffering = sys.stdout.line_buffering
+
+        sys.stdout = io.TextIOWrapper(
+            sys.stdout.detach(), 'utf-8', errors, newline, line_buffering)
+        try:
+            return _Distribution.handle_display_options(self, option_order)
+        finally:
+            sys.stdout = io.TextIOWrapper(
+                sys.stdout.detach(), encoding, errors, newline, line_buffering)
+
+
+class Feature:
+    """
+    **deprecated** -- The `Feature` facility was never completely implemented
+    or supported, `has reported issues
+    <https://github.com/pypa/setuptools/issues/58>`_ and will be removed in
+    a future version.
+
+    A subset of the distribution that can be excluded if unneeded/wanted
+
+    Features are created using these keyword arguments:
+
+      'description' -- a short, human readable description of the feature, to
+         be used in error messages, and option help messages.
+
+      'standard' -- if true, the feature is included by default if it is
+         available on the current system.  Otherwise, the feature is only
+         included if requested via a command line '--with-X' option, or if
+         another included feature requires it.  The default setting is 'False'.
+
+      'available' -- if true, the feature is available for installation on the
+         current system.  The default setting is 'True'.
+
+      'optional' -- if true, the feature's inclusion can be controlled from the
+         command line, using the '--with-X' or '--without-X' options.  If
+         false, the feature's inclusion status is determined automatically,
+         based on 'availabile', 'standard', and whether any other feature
+         requires it.  The default setting is 'True'.
+
+      'require_features' -- a string or sequence of strings naming features
+         that should also be included if this feature is included.  Defaults to
+         empty list.  May also contain 'Require' objects that should be
+         added/removed from the distribution.
+
+      'remove' -- a string or list of strings naming packages to be removed
+         from the distribution if this feature is *not* included.  If the
+         feature *is* included, this argument is ignored.  This argument exists
+         to support removing features that "crosscut" a distribution, such as
+         defining a 'tests' feature that removes all the 'tests' subpackages
+         provided by other features.  The default for this argument is an empty
+         list.  (Note: the named package(s) or modules must exist in the base
+         distribution when the 'setup()' function is initially called.)
+
+      other keywords -- any other keyword arguments are saved, and passed to
+         the distribution's 'include()' and 'exclude()' methods when the
+         feature is included or excluded, respectively.  So, for example, you
+         could pass 'packages=["a","b"]' to cause packages 'a' and 'b' to be
+         added or removed from the distribution as appropriate.
+
+    A feature must include at least one 'requires', 'remove', or other
+    keyword argument.  Otherwise, it can't affect the distribution in any way.
+    Note also that you can subclass 'Feature' to create your own specialized
+    feature types that modify the distribution in other ways when included or
+    excluded.  See the docstrings for the various methods here for more detail.
+    Aside from the methods, the only feature attributes that distributions look
+    at are 'description' and 'optional'.
+    """
+
+    @staticmethod
+    def warn_deprecated():
+        msg = (
+            "Features are deprecated and will be removed in a future "
+            "version. See https://github.com/pypa/setuptools/issues/65."
+        )
+        warnings.warn(msg, DeprecationWarning, stacklevel=3)
+
+    def __init__(
+            self, description, standard=False, available=True,
+            optional=True, require_features=(), remove=(), **extras):
+        self.warn_deprecated()
+
+        self.description = description
+        self.standard = standard
+        self.available = available
+        self.optional = optional
+        if isinstance(require_features, (str, Require)):
+            require_features = require_features,
+
+        self.require_features = [
+            r for r in require_features if isinstance(r, str)
+        ]
+        er = [r for r in require_features if not isinstance(r, str)]
+        if er:
+            extras['require_features'] = er
+
+        if isinstance(remove, str):
+            remove = remove,
+        self.remove = remove
+        self.extras = extras
+
+        if not remove and not require_features and not extras:
+            raise DistutilsSetupError(
+                "Feature %s: must define 'require_features', 'remove', or "
+                "at least one of 'packages', 'py_modules', etc."
+            )
+
+    def include_by_default(self):
+        """Should this feature be included by default?"""
+        return self.available and self.standard
+
+    def include_in(self, dist):
+        """Ensure feature and its requirements are included in distribution
+
+        You may override this in a subclass to perform additional operations on
+        the distribution.  Note that this method may be called more than once
+        per feature, and so should be idempotent.
+
+        """
+
+        if not self.available:
+            raise DistutilsPlatformError(
+                self.description + " is required, "
+                "but is not available on this platform"
+            )
+
+        dist.include(**self.extras)
+
+        for f in self.require_features:
+            dist.include_feature(f)
+
+    def exclude_from(self, dist):
+        """Ensure feature is excluded from distribution
+
+        You may override this in a subclass to perform additional operations on
+        the distribution.  This method will be called at most once per
+        feature, and only after all included features have been asked to
+        include themselves.
+        """
+
+        dist.exclude(**self.extras)
+
+        if self.remove:
+            for item in self.remove:
+                dist.exclude_package(item)
+
+    def validate(self, dist):
+        """Verify that feature makes sense in context of distribution
+
+        This method is called by the distribution just before it parses its
+        command line.  It checks to ensure that the 'remove' attribute, if any,
+        contains only valid package/module names that are present in the base
+        distribution when 'setup()' is called.  You may override it in a
+        subclass to perform any other required validation of the feature
+        against a target distribution.
+        """
+
+        for item in self.remove:
+            if not dist.has_contents_for(item):
+                raise DistutilsSetupError(
+                    "%s wants to be able to remove %s, but the distribution"
+                    " doesn't contain any packages or modules under %s"
+                    % (self.description, item, item)
+                )
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/extension.py b/vendor/setuptools-39.0.1/build/lib/setuptools/extension.py
new file mode 100644
index 00000000..29468894
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/extension.py
@@ -0,0 +1,57 @@
+import re
+import functools
+import distutils.core
+import distutils.errors
+import distutils.extension
+
+from setuptools.extern.six.moves import map
+
+from .monkey import get_unpatched
+
+
+def _have_cython():
+    """
+    Return True if Cython can be imported.
+    """
+    cython_impl = 'Cython.Distutils.build_ext'
+    try:
+        # from (cython_impl) import build_ext
+        __import__(cython_impl, fromlist=['build_ext']).build_ext
+        return True
+    except Exception:
+        pass
+    return False
+
+
+# for compatibility
+have_pyrex = _have_cython
+
+_Extension = get_unpatched(distutils.core.Extension)
+
+
+class Extension(_Extension):
+    """Extension that uses '.c' files in place of '.pyx' files"""
+
+    def __init__(self, name, sources, *args, **kw):
+        # The *args is needed for compatibility as calls may use positional
+        # arguments. py_limited_api may be set only via keyword.
+        self.py_limited_api = kw.pop("py_limited_api", False)
+        _Extension.__init__(self, name, sources, *args, **kw)
+
+    def _convert_pyx_sources_to_lang(self):
+        """
+        Replace sources with .pyx extensions to sources with the target
+        language extension. This mechanism allows language authors to supply
+        pre-converted sources but to prefer the .pyx sources.
+        """
+        if _have_cython():
+            # the build has Cython, so allow it to compile the .pyx files
+            return
+        lang = self.language or ''
+        target_ext = '.cpp' if lang.lower() == 'c++' else '.c'
+        sub = functools.partial(re.sub, '.pyx$', target_ext)
+        self.sources = list(map(sub, self.sources))
+
+
+class Library(Extension):
+    """Just like a regular Extension, but built as a library instead"""
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/extern/__init__.py b/vendor/setuptools-39.0.1/build/lib/setuptools/extern/__init__.py
new file mode 100644
index 00000000..da3d668d
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/extern/__init__.py
@@ -0,0 +1,73 @@
+import sys
+
+
+class VendorImporter:
+    """
+    A PEP 302 meta path importer for finding optionally-vendored
+    or otherwise naturally-installed packages from root_name.
+    """
+
+    def __init__(self, root_name, vendored_names=(), vendor_pkg=None):
+        self.root_name = root_name
+        self.vendored_names = set(vendored_names)
+        self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor')
+
+    @property
+    def search_path(self):
+        """
+        Search first the vendor package then as a natural package.
+        """
+        yield self.vendor_pkg + '.'
+        yield ''
+
+    def find_module(self, fullname, path=None):
+        """
+        Return self when fullname starts with root_name and the
+        target module is one vendored through this importer.
+        """
+        root, base, target = fullname.partition(self.root_name + '.')
+        if root:
+            return
+        if not any(map(target.startswith, self.vendored_names)):
+            return
+        return self
+
+    def load_module(self, fullname):
+        """
+        Iterate over the search path to locate and load fullname.
+        """
+        root, base, target = fullname.partition(self.root_name + '.')
+        for prefix in self.search_path:
+            try:
+                extant = prefix + target
+                __import__(extant)
+                mod = sys.modules[extant]
+                sys.modules[fullname] = mod
+                # mysterious hack:
+                # Remove the reference to the extant package/module
+                # on later Python versions to cause relative imports
+                # in the vendor package to resolve the same modules
+                # as those going through this importer.
+                if sys.version_info > (3, 3):
+                    del sys.modules[extant]
+                return mod
+            except ImportError:
+                pass
+        else:
+            raise ImportError(
+                "The '{target}' package is required; "
+                "normally this is bundled with this package so if you get "
+                "this warning, consult the packager of your "
+                "distribution.".format(**locals())
+            )
+
+    def install(self):
+        """
+        Install this importer into sys.meta_path if not already present.
+        """
+        if self not in sys.meta_path:
+            sys.meta_path.append(self)
+
+
+names = 'six', 'packaging', 'pyparsing',
+VendorImporter(__name__, names, 'setuptools._vendor').install()
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/glibc.py b/vendor/setuptools-39.0.1/build/lib/setuptools/glibc.py
new file mode 100644
index 00000000..a134591c
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/glibc.py
@@ -0,0 +1,86 @@
+# This file originally from pip:
+# https://github.com/pypa/pip/blob/8f4f15a5a95d7d5b511ceaee9ed261176c181970/src/pip/_internal/utils/glibc.py
+from __future__ import absolute_import
+
+import ctypes
+import re
+import warnings
+
+
+def glibc_version_string():
+    "Returns glibc version string, or None if not using glibc."
+
+    # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
+    # manpage says, "If filename is NULL, then the returned handle is for the
+    # main program". This way we can let the linker do the work to figure out
+    # which libc our process is actually using.
+    process_namespace = ctypes.CDLL(None)
+    try:
+        gnu_get_libc_version = process_namespace.gnu_get_libc_version
+    except AttributeError:
+        # Symbol doesn't exist -> therefore, we are not linked to
+        # glibc.
+        return None
+
+    # Call gnu_get_libc_version, which returns a string like "2.5"
+    gnu_get_libc_version.restype = ctypes.c_char_p
+    version_str = gnu_get_libc_version()
+    # py2 / py3 compatibility:
+    if not isinstance(version_str, str):
+        version_str = version_str.decode("ascii")
+
+    return version_str
+
+
+# Separated out from have_compatible_glibc for easier unit testing
+def check_glibc_version(version_str, required_major, minimum_minor):
+    # Parse string and check against requested version.
+    #
+    # We use a regexp instead of str.split because we want to discard any
+    # random junk that might come after the minor version -- this might happen
+    # in patched/forked versions of glibc (e.g. Linaro's version of glibc
+    # uses version strings like "2.20-2014.11"). See gh-3588.
+    m = re.match(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)", version_str)
+    if not m:
+        warnings.warn("Expected glibc version with 2 components major.minor,"
+                      " got: %s" % version_str, RuntimeWarning)
+        return False
+    return (int(m.group("major")) == required_major and
+            int(m.group("minor")) >= minimum_minor)
+
+
+def have_compatible_glibc(required_major, minimum_minor):
+    version_str = glibc_version_string()
+    if version_str is None:
+        return False
+    return check_glibc_version(version_str, required_major, minimum_minor)
+
+
+# platform.libc_ver regularly returns completely nonsensical glibc
+# versions. E.g. on my computer, platform says:
+#
+#   ~$ python2.7 -c 'import platform; print(platform.libc_ver())'
+#   ('glibc', '2.7')
+#   ~$ python3.5 -c 'import platform; print(platform.libc_ver())'
+#   ('glibc', '2.9')
+#
+# But the truth is:
+#
+#   ~$ ldd --version
+#   ldd (Debian GLIBC 2.22-11) 2.22
+#
+# This is unfortunate, because it means that the linehaul data on libc
+# versions that was generated by pip 8.1.2 and earlier is useless and
+# misleading. Solution: instead of using platform, use our code that actually
+# works.
+def libc_ver():
+    """Try to determine the glibc version
+
+    Returns a tuple of strings (lib, version) which default to empty strings
+    in case the lookup fails.
+    """
+    glibc_version = glibc_version_string()
+    if glibc_version is None:
+        return ("", "")
+    else:
+        return ("glibc", glibc_version)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/glob.py b/vendor/setuptools-39.0.1/build/lib/setuptools/glob.py
new file mode 100644
index 00000000..6c781de3
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/glob.py
@@ -0,0 +1,176 @@
+"""
+Filename globbing utility. Mostly a copy of `glob` from Python 3.5.
+
+Changes include:
+ * `yield from` and PEP3102 `*` removed.
+ * `bytes` changed to `six.binary_type`.
+ * Hidden files are not ignored.
+"""
+
+import os
+import re
+import fnmatch
+from setuptools.extern.six import binary_type
+
+__all__ = ["glob", "iglob", "escape"]
+
+
+def glob(pathname, recursive=False):
+    """Return a list of paths matching a pathname pattern.
+
+    The pattern may contain simple shell-style wildcards a la
+    fnmatch. However, unlike fnmatch, filenames starting with a
+    dot are special cases that are not matched by '*' and '?'
+    patterns.
+
+    If recursive is true, the pattern '**' will match any files and
+    zero or more directories and subdirectories.
+    """
+    return list(iglob(pathname, recursive=recursive))
+
+
+def iglob(pathname, recursive=False):
+    """Return an iterator which yields the paths matching a pathname pattern.
+
+    The pattern may contain simple shell-style wildcards a la
+    fnmatch. However, unlike fnmatch, filenames starting with a
+    dot are special cases that are not matched by '*' and '?'
+    patterns.
+
+    If recursive is true, the pattern '**' will match any files and
+    zero or more directories and subdirectories.
+    """
+    it = _iglob(pathname, recursive)
+    if recursive and _isrecursive(pathname):
+        s = next(it)  # skip empty string
+        assert not s
+    return it
+
+
+def _iglob(pathname, recursive):
+    dirname, basename = os.path.split(pathname)
+    if not has_magic(pathname):
+        if basename:
+            if os.path.lexists(pathname):
+                yield pathname
+        else:
+            # Patterns ending with a slash should match only directories
+            if os.path.isdir(dirname):
+                yield pathname
+        return
+    if not dirname:
+        if recursive and _isrecursive(basename):
+            for x in glob2(dirname, basename):
+                yield x
+        else:
+            for x in glob1(dirname, basename):
+                yield x
+        return
+    # `os.path.split()` returns the argument itself as a dirname if it is a
+    # drive or UNC path.  Prevent an infinite recursion if a drive or UNC path
+    # contains magic characters (i.e. r'\\?\C:').
+    if dirname != pathname and has_magic(dirname):
+        dirs = _iglob(dirname, recursive)
+    else:
+        dirs = [dirname]
+    if has_magic(basename):
+        if recursive and _isrecursive(basename):
+            glob_in_dir = glob2
+        else:
+            glob_in_dir = glob1
+    else:
+        glob_in_dir = glob0
+    for dirname in dirs:
+        for name in glob_in_dir(dirname, basename):
+            yield os.path.join(dirname, name)
+
+
+# These 2 helper functions non-recursively glob inside a literal directory.
+# They return a list of basenames. `glob1` accepts a pattern while `glob0`
+# takes a literal basename (so it only has to check for its existence).
+
+
+def glob1(dirname, pattern):
+    if not dirname:
+        if isinstance(pattern, binary_type):
+            dirname = os.curdir.encode('ASCII')
+        else:
+            dirname = os.curdir
+    try:
+        names = os.listdir(dirname)
+    except OSError:
+        return []
+    return fnmatch.filter(names, pattern)
+
+
+def glob0(dirname, basename):
+    if not basename:
+        # `os.path.split()` returns an empty basename for paths ending with a
+        # directory separator.  'q*x/' should match only directories.
+        if os.path.isdir(dirname):
+            return [basename]
+    else:
+        if os.path.lexists(os.path.join(dirname, basename)):
+            return [basename]
+    return []
+
+
+# This helper function recursively yields relative pathnames inside a literal
+# directory.
+
+
+def glob2(dirname, pattern):
+    assert _isrecursive(pattern)
+    yield pattern[:0]
+    for x in _rlistdir(dirname):
+        yield x
+
+
+# Recursively yields relative pathnames inside a literal directory.
+def _rlistdir(dirname):
+    if not dirname:
+        if isinstance(dirname, binary_type):
+            dirname = binary_type(os.curdir, 'ASCII')
+        else:
+            dirname = os.curdir
+    try:
+        names = os.listdir(dirname)
+    except os.error:
+        return
+    for x in names:
+        yield x
+        path = os.path.join(dirname, x) if dirname else x
+        for y in _rlistdir(path):
+            yield os.path.join(x, y)
+
+
+magic_check = re.compile('([*?[])')
+magic_check_bytes = re.compile(b'([*?[])')
+
+
+def has_magic(s):
+    if isinstance(s, binary_type):
+        match = magic_check_bytes.search(s)
+    else:
+        match = magic_check.search(s)
+    return match is not None
+
+
+def _isrecursive(pattern):
+    if isinstance(pattern, binary_type):
+        return pattern == b'**'
+    else:
+        return pattern == '**'
+
+
+def escape(pathname):
+    """Escape all special characters.
+    """
+    # Escaping is done by wrapping any of "*?[" between square brackets.
+    # Metacharacters do not work in the drive part and shouldn't be escaped.
+    drive, pathname = os.path.splitdrive(pathname)
+    if isinstance(pathname, binary_type):
+        pathname = magic_check_bytes.sub(br'[\1]', pathname)
+    else:
+        pathname = magic_check.sub(r'[\1]', pathname)
+    return drive + pathname
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/gui-32.exe b/vendor/setuptools-39.0.1/build/lib/setuptools/gui-32.exe
new file mode 100644
index 0000000000000000000000000000000000000000..f8d3509653ba8f80ca7f3aa7f95616142ba83a94
GIT binary patch
literal 65536
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

literal 0
HcmV?d00001

diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/gui-64.exe b/vendor/setuptools-39.0.1/build/lib/setuptools/gui-64.exe
new file mode 100644
index 0000000000000000000000000000000000000000..330c51a5dde15a0bb610a48cd0ca11770c914dae
GIT binary patch
literal 75264
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

literal 0
HcmV?d00001

diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/gui.exe b/vendor/setuptools-39.0.1/build/lib/setuptools/gui.exe
new file mode 100644
index 0000000000000000000000000000000000000000..f8d3509653ba8f80ca7f3aa7f95616142ba83a94
GIT binary patch
literal 65536
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

literal 0
HcmV?d00001

diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/launch.py b/vendor/setuptools-39.0.1/build/lib/setuptools/launch.py
new file mode 100644
index 00000000..308283ea
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/launch.py
@@ -0,0 +1,35 @@
+"""
+Launch the Python script on the command line after
+setuptools is bootstrapped via import.
+"""
+
+# Note that setuptools gets imported implicitly by the
+# invocation of this script using python -m setuptools.launch
+
+import tokenize
+import sys
+
+
+def run():
+    """
+    Run the script in sys.argv[1] as if it had
+    been invoked naturally.
+    """
+    __builtins__
+    script_name = sys.argv[1]
+    namespace = dict(
+        __file__=script_name,
+        __name__='__main__',
+        __doc__=None,
+    )
+    sys.argv[:] = sys.argv[1:]
+
+    open_ = getattr(tokenize, 'open', open)
+    script = open_(script_name).read()
+    norm_script = script.replace('\\r\\n', '\\n')
+    code = compile(norm_script, script_name, 'exec')
+    exec(code, namespace)
+
+
+if __name__ == '__main__':
+    run()
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/lib2to3_ex.py b/vendor/setuptools-39.0.1/build/lib/setuptools/lib2to3_ex.py
new file mode 100644
index 00000000..4b1a73fe
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/lib2to3_ex.py
@@ -0,0 +1,62 @@
+"""
+Customized Mixin2to3 support:
+
+ - adds support for converting doctests
+
+
+This module raises an ImportError on Python 2.
+"""
+
+from distutils.util import Mixin2to3 as _Mixin2to3
+from distutils import log
+from lib2to3.refactor import RefactoringTool, get_fixers_from_package
+
+import setuptools
+
+
+class DistutilsRefactoringTool(RefactoringTool):
+    def log_error(self, msg, *args, **kw):
+        log.error(msg, *args)
+
+    def log_message(self, msg, *args):
+        log.info(msg, *args)
+
+    def log_debug(self, msg, *args):
+        log.debug(msg, *args)
+
+
+class Mixin2to3(_Mixin2to3):
+    def run_2to3(self, files, doctests=False):
+        # See of the distribution option has been set, otherwise check the
+        # setuptools default.
+        if self.distribution.use_2to3 is not True:
+            return
+        if not files:
+            return
+        log.info("Fixing " + " ".join(files))
+        self.__build_fixer_names()
+        self.__exclude_fixers()
+        if doctests:
+            if setuptools.run_2to3_on_doctests:
+                r = DistutilsRefactoringTool(self.fixer_names)
+                r.refactor(files, write=True, doctests_only=True)
+        else:
+            _Mixin2to3.run_2to3(self, files)
+
+    def __build_fixer_names(self):
+        if self.fixer_names:
+            return
+        self.fixer_names = []
+        for p in setuptools.lib2to3_fixer_packages:
+            self.fixer_names.extend(get_fixers_from_package(p))
+        if self.distribution.use_2to3_fixers is not None:
+            for p in self.distribution.use_2to3_fixers:
+                self.fixer_names.extend(get_fixers_from_package(p))
+
+    def __exclude_fixers(self):
+        excluded_fixers = getattr(self, 'exclude_fixers', [])
+        if self.distribution.use_2to3_exclude_fixers is not None:
+            excluded_fixers.extend(self.distribution.use_2to3_exclude_fixers)
+        for fixer_name in excluded_fixers:
+            if fixer_name in self.fixer_names:
+                self.fixer_names.remove(fixer_name)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/monkey.py b/vendor/setuptools-39.0.1/build/lib/setuptools/monkey.py
new file mode 100644
index 00000000..d9eb7d7b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/monkey.py
@@ -0,0 +1,197 @@
+"""
+Monkey patching of distutils.
+"""
+
+import sys
+import distutils.filelist
+import platform
+import types
+import functools
+from importlib import import_module
+import inspect
+
+from setuptools.extern import six
+
+import setuptools
+
+__all__ = []
+"""
+Everything is private. Contact the project team
+if you think you need this functionality.
+"""
+
+
+def _get_mro(cls):
+    """
+    Returns the bases classes for cls sorted by the MRO.
+
+    Works around an issue on Jython where inspect.getmro will not return all
+    base classes if multiple classes share the same name. Instead, this
+    function will return a tuple containing the class itself, and the contents
+    of cls.__bases__. See https://github.com/pypa/setuptools/issues/1024.
+    """
+    if platform.python_implementation() == "Jython":
+        return (cls,) + cls.__bases__
+    return inspect.getmro(cls)
+
+
+def get_unpatched(item):
+    lookup = (
+        get_unpatched_class if isinstance(item, six.class_types) else
+        get_unpatched_function if isinstance(item, types.FunctionType) else
+        lambda item: None
+    )
+    return lookup(item)
+
+
+def get_unpatched_class(cls):
+    """Protect against re-patching the distutils if reloaded
+
+    Also ensures that no other distutils extension monkeypatched the distutils
+    first.
+    """
+    external_bases = (
+        cls
+        for cls in _get_mro(cls)
+        if not cls.__module__.startswith('setuptools')
+    )
+    base = next(external_bases)
+    if not base.__module__.startswith('distutils'):
+        msg = "distutils has already been patched by %r" % cls
+        raise AssertionError(msg)
+    return base
+
+
+def patch_all():
+    # we can't patch distutils.cmd, alas
+    distutils.core.Command = setuptools.Command
+
+    has_issue_12885 = sys.version_info <= (3, 5, 3)
+
+    if has_issue_12885:
+        # fix findall bug in distutils (http://bugs.python.org/issue12885)
+        distutils.filelist.findall = setuptools.findall
+
+    needs_warehouse = (
+        sys.version_info < (2, 7, 13)
+        or
+        (3, 0) < sys.version_info < (3, 3, 7)
+        or
+        (3, 4) < sys.version_info < (3, 4, 6)
+        or
+        (3, 5) < sys.version_info <= (3, 5, 3)
+    )
+
+    if needs_warehouse:
+        warehouse = 'https://upload.pypi.org/legacy/'
+        distutils.config.PyPIRCCommand.DEFAULT_REPOSITORY = warehouse
+
+    _patch_distribution_metadata_write_pkg_file()
+    _patch_distribution_metadata_write_pkg_info()
+
+    # Install Distribution throughout the distutils
+    for module in distutils.dist, distutils.core, distutils.cmd:
+        module.Distribution = setuptools.dist.Distribution
+
+    # Install the patched Extension
+    distutils.core.Extension = setuptools.extension.Extension
+    distutils.extension.Extension = setuptools.extension.Extension
+    if 'distutils.command.build_ext' in sys.modules:
+        sys.modules['distutils.command.build_ext'].Extension = (
+            setuptools.extension.Extension
+        )
+
+    patch_for_msvc_specialized_compiler()
+
+
+def _patch_distribution_metadata_write_pkg_file():
+    """Patch write_pkg_file to also write Requires-Python/Requires-External"""
+    distutils.dist.DistributionMetadata.write_pkg_file = (
+        setuptools.dist.write_pkg_file
+    )
+
+
+def _patch_distribution_metadata_write_pkg_info():
+    """
+    Workaround issue #197 - Python 3 prior to 3.2.2 uses an environment-local
+    encoding to save the pkg_info. Monkey-patch its write_pkg_info method to
+    correct this undesirable behavior.
+    """
+    environment_local = (3,) <= sys.version_info[:3] < (3, 2, 2)
+    if not environment_local:
+        return
+
+    distutils.dist.DistributionMetadata.write_pkg_info = (
+        setuptools.dist.write_pkg_info
+    )
+
+
+def patch_func(replacement, target_mod, func_name):
+    """
+    Patch func_name in target_mod with replacement
+
+    Important - original must be resolved by name to avoid
+    patching an already patched function.
+    """
+    original = getattr(target_mod, func_name)
+
+    # set the 'unpatched' attribute on the replacement to
+    # point to the original.
+    vars(replacement).setdefault('unpatched', original)
+
+    # replace the function in the original module
+    setattr(target_mod, func_name, replacement)
+
+
+def get_unpatched_function(candidate):
+    return getattr(candidate, 'unpatched')
+
+
+def patch_for_msvc_specialized_compiler():
+    """
+    Patch functions in distutils to use standalone Microsoft Visual C++
+    compilers.
+    """
+    # import late to avoid circular imports on Python < 3.5
+    msvc = import_module('setuptools.msvc')
+
+    if platform.system() != 'Windows':
+        # Compilers only availables on Microsoft Windows
+        return
+
+    def patch_params(mod_name, func_name):
+        """
+        Prepare the parameters for patch_func to patch indicated function.
+        """
+        repl_prefix = 'msvc9_' if 'msvc9' in mod_name else 'msvc14_'
+        repl_name = repl_prefix + func_name.lstrip('_')
+        repl = getattr(msvc, repl_name)
+        mod = import_module(mod_name)
+        if not hasattr(mod, func_name):
+            raise ImportError(func_name)
+        return repl, mod, func_name
+
+    # Python 2.7 to 3.4
+    msvc9 = functools.partial(patch_params, 'distutils.msvc9compiler')
+
+    # Python 3.5+
+    msvc14 = functools.partial(patch_params, 'distutils._msvccompiler')
+
+    try:
+        # Patch distutils.msvc9compiler
+        patch_func(*msvc9('find_vcvarsall'))
+        patch_func(*msvc9('query_vcvarsall'))
+    except ImportError:
+        pass
+
+    try:
+        # Patch distutils._msvccompiler._get_vc_env
+        patch_func(*msvc14('_get_vc_env'))
+    except ImportError:
+        pass
+
+    try:
+        # Patch distutils._msvccompiler.gen_lib_options for Numpy
+        patch_func(*msvc14('gen_lib_options'))
+    except ImportError:
+        pass
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/msvc.py b/vendor/setuptools-39.0.1/build/lib/setuptools/msvc.py
new file mode 100644
index 00000000..5e20b3f1
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/msvc.py
@@ -0,0 +1,1302 @@
+"""
+Improved support for Microsoft Visual C++ compilers.
+
+Known supported compilers:
+--------------------------
+Microsoft Visual C++ 9.0:
+    Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64)
+    Microsoft Windows SDK 6.1 (x86, x64, ia64)
+    Microsoft Windows SDK 7.0 (x86, x64, ia64)
+
+Microsoft Visual C++ 10.0:
+    Microsoft Windows SDK 7.1 (x86, x64, ia64)
+
+Microsoft Visual C++ 14.0:
+    Microsoft Visual C++ Build Tools 2015 (x86, x64, arm)
+    Microsoft Visual Studio 2017 (x86, x64, arm, arm64)
+    Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64)
+"""
+
+import os
+import sys
+import platform
+import itertools
+import distutils.errors
+from setuptools.extern.packaging.version import LegacyVersion
+
+from setuptools.extern.six.moves import filterfalse
+
+from .monkey import get_unpatched
+
+if platform.system() == 'Windows':
+    from setuptools.extern.six.moves import winreg
+    safe_env = os.environ
+else:
+    """
+    Mock winreg and environ so the module can be imported
+    on this platform.
+    """
+
+    class winreg:
+        HKEY_USERS = None
+        HKEY_CURRENT_USER = None
+        HKEY_LOCAL_MACHINE = None
+        HKEY_CLASSES_ROOT = None
+
+    safe_env = dict()
+
+_msvc9_suppress_errors = (
+    # msvc9compiler isn't available on some platforms
+    ImportError,
+
+    # msvc9compiler raises DistutilsPlatformError in some
+    # environments. See #1118.
+    distutils.errors.DistutilsPlatformError,
+)
+
+try:
+    from distutils.msvc9compiler import Reg
+except _msvc9_suppress_errors:
+    pass
+
+
+def msvc9_find_vcvarsall(version):
+    """
+    Patched "distutils.msvc9compiler.find_vcvarsall" to use the standalone
+    compiler build for Python (VCForPython). Fall back to original behavior
+    when the standalone compiler is not available.
+
+    Redirect the path of "vcvarsall.bat".
+
+    Known supported compilers
+    -------------------------
+    Microsoft Visual C++ 9.0:
+        Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64)
+
+    Parameters
+    ----------
+    version: float
+        Required Microsoft Visual C++ version.
+
+    Return
+    ------
+    vcvarsall.bat path: str
+    """
+    VC_BASE = r'Software\%sMicrosoft\DevDiv\VCForPython\%0.1f'
+    key = VC_BASE % ('', version)
+    try:
+        # Per-user installs register the compiler path here
+        productdir = Reg.get_value(key, "installdir")
+    except KeyError:
+        try:
+            # All-user installs on a 64-bit system register here
+            key = VC_BASE % ('Wow6432Node\\', version)
+            productdir = Reg.get_value(key, "installdir")
+        except KeyError:
+            productdir = None
+
+    if productdir:
+        vcvarsall = os.path.os.path.join(productdir, "vcvarsall.bat")
+        if os.path.isfile(vcvarsall):
+            return vcvarsall
+
+    return get_unpatched(msvc9_find_vcvarsall)(version)
+
+
+def msvc9_query_vcvarsall(ver, arch='x86', *args, **kwargs):
+    """
+    Patched "distutils.msvc9compiler.query_vcvarsall" for support extra
+    compilers.
+
+    Set environment without use of "vcvarsall.bat".
+
+    Known supported compilers
+    -------------------------
+    Microsoft Visual C++ 9.0:
+        Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64)
+        Microsoft Windows SDK 6.1 (x86, x64, ia64)
+        Microsoft Windows SDK 7.0 (x86, x64, ia64)
+
+    Microsoft Visual C++ 10.0:
+        Microsoft Windows SDK 7.1 (x86, x64, ia64)
+
+    Parameters
+    ----------
+    ver: float
+        Required Microsoft Visual C++ version.
+    arch: str
+        Target architecture.
+
+    Return
+    ------
+    environment: dict
+    """
+    # Try to get environement from vcvarsall.bat (Classical way)
+    try:
+        orig = get_unpatched(msvc9_query_vcvarsall)
+        return orig(ver, arch, *args, **kwargs)
+    except distutils.errors.DistutilsPlatformError:
+        # Pass error if Vcvarsall.bat is missing
+        pass
+    except ValueError:
+        # Pass error if environment not set after executing vcvarsall.bat
+        pass
+
+    # If error, try to set environment directly
+    try:
+        return EnvironmentInfo(arch, ver).return_env()
+    except distutils.errors.DistutilsPlatformError as exc:
+        _augment_exception(exc, ver, arch)
+        raise
+
+
+def msvc14_get_vc_env(plat_spec):
+    """
+    Patched "distutils._msvccompiler._get_vc_env" for support extra
+    compilers.
+
+    Set environment without use of "vcvarsall.bat".
+
+    Known supported compilers
+    -------------------------
+    Microsoft Visual C++ 14.0:
+        Microsoft Visual C++ Build Tools 2015 (x86, x64, arm)
+        Microsoft Visual Studio 2017 (x86, x64, arm, arm64)
+        Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64)
+
+    Parameters
+    ----------
+    plat_spec: str
+        Target architecture.
+
+    Return
+    ------
+    environment: dict
+    """
+    # Try to get environment from vcvarsall.bat (Classical way)
+    try:
+        return get_unpatched(msvc14_get_vc_env)(plat_spec)
+    except distutils.errors.DistutilsPlatformError:
+        # Pass error Vcvarsall.bat is missing
+        pass
+
+    # If error, try to set environment directly
+    try:
+        return EnvironmentInfo(plat_spec, vc_min_ver=14.0).return_env()
+    except distutils.errors.DistutilsPlatformError as exc:
+        _augment_exception(exc, 14.0)
+        raise
+
+
+def msvc14_gen_lib_options(*args, **kwargs):
+    """
+    Patched "distutils._msvccompiler.gen_lib_options" for fix
+    compatibility between "numpy.distutils" and "distutils._msvccompiler"
+    (for Numpy < 1.11.2)
+    """
+    if "numpy.distutils" in sys.modules:
+        import numpy as np
+        if LegacyVersion(np.__version__) < LegacyVersion('1.11.2'):
+            return np.distutils.ccompiler.gen_lib_options(*args, **kwargs)
+    return get_unpatched(msvc14_gen_lib_options)(*args, **kwargs)
+
+
+def _augment_exception(exc, version, arch=''):
+    """
+    Add details to the exception message to help guide the user
+    as to what action will resolve it.
+    """
+    # Error if MSVC++ directory not found or environment not set
+    message = exc.args[0]
+
+    if "vcvarsall" in message.lower() or "visual c" in message.lower():
+        # Special error message if MSVC++ not installed
+        tmpl = 'Microsoft Visual C++ {version:0.1f} is required.'
+        message = tmpl.format(**locals())
+        msdownload = 'www.microsoft.com/download/details.aspx?id=%d'
+        if version == 9.0:
+            if arch.lower().find('ia64') > -1:
+                # For VC++ 9.0, if IA64 support is needed, redirect user
+                # to Windows SDK 7.0
+                message += ' Get it with "Microsoft Windows SDK 7.0": '
+                message += msdownload % 3138
+            else:
+                # For VC++ 9.0 redirect user to Vc++ for Python 2.7 :
+                # This redirection link is maintained by Microsoft.
+                # Contact vspython@microsoft.com if it needs updating.
+                message += ' Get it from http://aka.ms/vcpython27'
+        elif version == 10.0:
+            # For VC++ 10.0 Redirect user to Windows SDK 7.1
+            message += ' Get it with "Microsoft Windows SDK 7.1": '
+            message += msdownload % 8279
+        elif version >= 14.0:
+            # For VC++ 14.0 Redirect user to Visual C++ Build Tools
+            message += (' Get it with "Microsoft Visual C++ Build Tools": '
+                        r'http://landinghub.visualstudio.com/'
+                        'visual-cpp-build-tools')
+
+    exc.args = (message, )
+
+
+class PlatformInfo:
+    """
+    Current and Target Architectures informations.
+
+    Parameters
+    ----------
+    arch: str
+        Target architecture.
+    """
+    current_cpu = safe_env.get('processor_architecture', '').lower()
+
+    def __init__(self, arch):
+        self.arch = arch.lower().replace('x64', 'amd64')
+
+    @property
+    def target_cpu(self):
+        return self.arch[self.arch.find('_') + 1:]
+
+    def target_is_x86(self):
+        return self.target_cpu == 'x86'
+
+    def current_is_x86(self):
+        return self.current_cpu == 'x86'
+
+    def current_dir(self, hidex86=False, x64=False):
+        """
+        Current platform specific subfolder.
+
+        Parameters
+        ----------
+        hidex86: bool
+            return '' and not '\x86' if architecture is x86.
+        x64: bool
+            return '\x64' and not '\amd64' if architecture is amd64.
+
+        Return
+        ------
+        subfolder: str
+            '\target', or '' (see hidex86 parameter)
+        """
+        return (
+            '' if (self.current_cpu == 'x86' and hidex86) else
+            r'\x64' if (self.current_cpu == 'amd64' and x64) else
+            r'\%s' % self.current_cpu
+        )
+
+    def target_dir(self, hidex86=False, x64=False):
+        r"""
+        Target platform specific subfolder.
+
+        Parameters
+        ----------
+        hidex86: bool
+            return '' and not '\x86' if architecture is x86.
+        x64: bool
+            return '\x64' and not '\amd64' if architecture is amd64.
+
+        Return
+        ------
+        subfolder: str
+            '\current', or '' (see hidex86 parameter)
+        """
+        return (
+            '' if (self.target_cpu == 'x86' and hidex86) else
+            r'\x64' if (self.target_cpu == 'amd64' and x64) else
+            r'\%s' % self.target_cpu
+        )
+
+    def cross_dir(self, forcex86=False):
+        r"""
+        Cross platform specific subfolder.
+
+        Parameters
+        ----------
+        forcex86: bool
+            Use 'x86' as current architecture even if current acritecture is
+            not x86.
+
+        Return
+        ------
+        subfolder: str
+            '' if target architecture is current architecture,
+            '\current_target' if not.
+        """
+        current = 'x86' if forcex86 else self.current_cpu
+        return (
+            '' if self.target_cpu == current else
+            self.target_dir().replace('\\', '\\%s_' % current)
+        )
+
+
+class RegistryInfo:
+    """
+    Microsoft Visual Studio related registry informations.
+
+    Parameters
+    ----------
+    platform_info: PlatformInfo
+        "PlatformInfo" instance.
+    """
+    HKEYS = (winreg.HKEY_USERS,
+             winreg.HKEY_CURRENT_USER,
+             winreg.HKEY_LOCAL_MACHINE,
+             winreg.HKEY_CLASSES_ROOT)
+
+    def __init__(self, platform_info):
+        self.pi = platform_info
+
+    @property
+    def visualstudio(self):
+        """
+        Microsoft Visual Studio root registry key.
+        """
+        return 'VisualStudio'
+
+    @property
+    def sxs(self):
+        """
+        Microsoft Visual Studio SxS registry key.
+        """
+        return os.path.join(self.visualstudio, 'SxS')
+
+    @property
+    def vc(self):
+        """
+        Microsoft Visual C++ VC7 registry key.
+        """
+        return os.path.join(self.sxs, 'VC7')
+
+    @property
+    def vs(self):
+        """
+        Microsoft Visual Studio VS7 registry key.
+        """
+        return os.path.join(self.sxs, 'VS7')
+
+    @property
+    def vc_for_python(self):
+        """
+        Microsoft Visual C++ for Python registry key.
+        """
+        return r'DevDiv\VCForPython'
+
+    @property
+    def microsoft_sdk(self):
+        """
+        Microsoft SDK registry key.
+        """
+        return 'Microsoft SDKs'
+
+    @property
+    def windows_sdk(self):
+        """
+        Microsoft Windows/Platform SDK registry key.
+        """
+        return os.path.join(self.microsoft_sdk, 'Windows')
+
+    @property
+    def netfx_sdk(self):
+        """
+        Microsoft .NET Framework SDK registry key.
+        """
+        return os.path.join(self.microsoft_sdk, 'NETFXSDK')
+
+    @property
+    def windows_kits_roots(self):
+        """
+        Microsoft Windows Kits Roots registry key.
+        """
+        return r'Windows Kits\Installed Roots'
+
+    def microsoft(self, key, x86=False):
+        """
+        Return key in Microsoft software registry.
+
+        Parameters
+        ----------
+        key: str
+            Registry key path where look.
+        x86: str
+            Force x86 software registry.
+
+        Return
+        ------
+        str: value
+        """
+        node64 = '' if self.pi.current_is_x86() or x86 else 'Wow6432Node'
+        return os.path.join('Software', node64, 'Microsoft', key)
+
+    def lookup(self, key, name):
+        """
+        Look for values in registry in Microsoft software registry.
+
+        Parameters
+        ----------
+        key: str
+            Registry key path where look.
+        name: str
+            Value name to find.
+
+        Return
+        ------
+        str: value
+        """
+        KEY_READ = winreg.KEY_READ
+        openkey = winreg.OpenKey
+        ms = self.microsoft
+        for hkey in self.HKEYS:
+            try:
+                bkey = openkey(hkey, ms(key), 0, KEY_READ)
+            except (OSError, IOError):
+                if not self.pi.current_is_x86():
+                    try:
+                        bkey = openkey(hkey, ms(key, True), 0, KEY_READ)
+                    except (OSError, IOError):
+                        continue
+                else:
+                    continue
+            try:
+                return winreg.QueryValueEx(bkey, name)[0]
+            except (OSError, IOError):
+                pass
+
+
+class SystemInfo:
+    """
+    Microsoft Windows and Visual Studio related system inormations.
+
+    Parameters
+    ----------
+    registry_info: RegistryInfo
+        "RegistryInfo" instance.
+    vc_ver: float
+        Required Microsoft Visual C++ version.
+    """
+
+    # Variables and properties in this class use originals CamelCase variables
+    # names from Microsoft source files for more easy comparaison.
+    WinDir = safe_env.get('WinDir', '')
+    ProgramFiles = safe_env.get('ProgramFiles', '')
+    ProgramFilesx86 = safe_env.get('ProgramFiles(x86)', ProgramFiles)
+
+    def __init__(self, registry_info, vc_ver=None):
+        self.ri = registry_info
+        self.pi = self.ri.pi
+        self.vc_ver = vc_ver or self._find_latest_available_vc_ver()
+
+    def _find_latest_available_vc_ver(self):
+        try:
+            return self.find_available_vc_vers()[-1]
+        except IndexError:
+            err = 'No Microsoft Visual C++ version found'
+            raise distutils.errors.DistutilsPlatformError(err)
+
+    def find_available_vc_vers(self):
+        """
+        Find all available Microsoft Visual C++ versions.
+        """
+        ms = self.ri.microsoft
+        vckeys = (self.ri.vc, self.ri.vc_for_python, self.ri.vs)
+        vc_vers = []
+        for hkey in self.ri.HKEYS:
+            for key in vckeys:
+                try:
+                    bkey = winreg.OpenKey(hkey, ms(key), 0, winreg.KEY_READ)
+                except (OSError, IOError):
+                    continue
+                subkeys, values, _ = winreg.QueryInfoKey(bkey)
+                for i in range(values):
+                    try:
+                        ver = float(winreg.EnumValue(bkey, i)[0])
+                        if ver not in vc_vers:
+                            vc_vers.append(ver)
+                    except ValueError:
+                        pass
+                for i in range(subkeys):
+                    try:
+                        ver = float(winreg.EnumKey(bkey, i))
+                        if ver not in vc_vers:
+                            vc_vers.append(ver)
+                    except ValueError:
+                        pass
+        return sorted(vc_vers)
+
+    @property
+    def VSInstallDir(self):
+        """
+        Microsoft Visual Studio directory.
+        """
+        # Default path
+        name = 'Microsoft Visual Studio %0.1f' % self.vc_ver
+        default = os.path.join(self.ProgramFilesx86, name)
+
+        # Try to get path from registry, if fail use default path
+        return self.ri.lookup(self.ri.vs, '%0.1f' % self.vc_ver) or default
+
+    @property
+    def VCInstallDir(self):
+        """
+        Microsoft Visual C++ directory.
+        """
+        self.VSInstallDir
+
+        guess_vc = self._guess_vc() or self._guess_vc_legacy()
+
+        # Try to get "VC++ for Python" path from registry as default path
+        reg_path = os.path.join(self.ri.vc_for_python, '%0.1f' % self.vc_ver)
+        python_vc = self.ri.lookup(reg_path, 'installdir')
+        default_vc = os.path.join(python_vc, 'VC') if python_vc else guess_vc
+
+        # Try to get path from registry, if fail use default path
+        path = self.ri.lookup(self.ri.vc, '%0.1f' % self.vc_ver) or default_vc
+
+        if not os.path.isdir(path):
+            msg = 'Microsoft Visual C++ directory not found'
+            raise distutils.errors.DistutilsPlatformError(msg)
+
+        return path
+
+    def _guess_vc(self):
+        """
+        Locate Visual C for 2017
+        """
+        if self.vc_ver <= 14.0:
+            return
+
+        default = r'VC\Tools\MSVC'
+        guess_vc = os.path.join(self.VSInstallDir, default)
+        # Subdir with VC exact version as name
+        try:
+            vc_exact_ver = os.listdir(guess_vc)[-1]
+            return os.path.join(guess_vc, vc_exact_ver)
+        except (OSError, IOError, IndexError):
+            pass
+
+    def _guess_vc_legacy(self):
+        """
+        Locate Visual C for versions prior to 2017
+        """
+        default = r'Microsoft Visual Studio %0.1f\VC' % self.vc_ver
+        return os.path.join(self.ProgramFilesx86, default)
+
+    @property
+    def WindowsSdkVersion(self):
+        """
+        Microsoft Windows SDK versions for specified MSVC++ version.
+        """
+        if self.vc_ver <= 9.0:
+            return ('7.0', '6.1', '6.0a')
+        elif self.vc_ver == 10.0:
+            return ('7.1', '7.0a')
+        elif self.vc_ver == 11.0:
+            return ('8.0', '8.0a')
+        elif self.vc_ver == 12.0:
+            return ('8.1', '8.1a')
+        elif self.vc_ver >= 14.0:
+            return ('10.0', '8.1')
+
+    @property
+    def WindowsSdkLastVersion(self):
+        """
+        Microsoft Windows SDK last version
+        """
+        return self._use_last_dir_name(os.path.join(
+            self.WindowsSdkDir, 'lib'))
+
+    @property
+    def WindowsSdkDir(self):
+        """
+        Microsoft Windows SDK directory.
+        """
+        sdkdir = ''
+        for ver in self.WindowsSdkVersion:
+            # Try to get it from registry
+            loc = os.path.join(self.ri.windows_sdk, 'v%s' % ver)
+            sdkdir = self.ri.lookup(loc, 'installationfolder')
+            if sdkdir:
+                break
+        if not sdkdir or not os.path.isdir(sdkdir):
+            # Try to get "VC++ for Python" version from registry
+            path = os.path.join(self.ri.vc_for_python, '%0.1f' % self.vc_ver)
+            install_base = self.ri.lookup(path, 'installdir')
+            if install_base:
+                sdkdir = os.path.join(install_base, 'WinSDK')
+        if not sdkdir or not os.path.isdir(sdkdir):
+            # If fail, use default new path
+            for ver in self.WindowsSdkVersion:
+                intver = ver[:ver.rfind('.')]
+                path = r'Microsoft SDKs\Windows Kits\%s' % (intver)
+                d = os.path.join(self.ProgramFiles, path)
+                if os.path.isdir(d):
+                    sdkdir = d
+        if not sdkdir or not os.path.isdir(sdkdir):
+            # If fail, use default old path
+            for ver in self.WindowsSdkVersion:
+                path = r'Microsoft SDKs\Windows\v%s' % ver
+                d = os.path.join(self.ProgramFiles, path)
+                if os.path.isdir(d):
+                    sdkdir = d
+        if not sdkdir:
+            # If fail, use Platform SDK
+            sdkdir = os.path.join(self.VCInstallDir, 'PlatformSDK')
+        return sdkdir
+
+    @property
+    def WindowsSDKExecutablePath(self):
+        """
+        Microsoft Windows SDK executable directory.
+        """
+        # Find WinSDK NetFx Tools registry dir name
+        if self.vc_ver <= 11.0:
+            netfxver = 35
+            arch = ''
+        else:
+            netfxver = 40
+            hidex86 = True if self.vc_ver <= 12.0 else False
+            arch = self.pi.current_dir(x64=True, hidex86=hidex86)
+        fx = 'WinSDK-NetFx%dTools%s' % (netfxver, arch.replace('\\', '-'))
+
+        # liste all possibles registry paths
+        regpaths = []
+        if self.vc_ver >= 14.0:
+            for ver in self.NetFxSdkVersion:
+                regpaths += [os.path.join(self.ri.netfx_sdk, ver, fx)]
+
+        for ver in self.WindowsSdkVersion:
+            regpaths += [os.path.join(self.ri.windows_sdk, 'v%sA' % ver, fx)]
+
+        # Return installation folder from the more recent path
+        for path in regpaths:
+            execpath = self.ri.lookup(path, 'installationfolder')
+            if execpath:
+                break
+        return execpath
+
+    @property
+    def FSharpInstallDir(self):
+        """
+        Microsoft Visual F# directory.
+        """
+        path = r'%0.1f\Setup\F#' % self.vc_ver
+        path = os.path.join(self.ri.visualstudio, path)
+        return self.ri.lookup(path, 'productdir') or ''
+
+    @property
+    def UniversalCRTSdkDir(self):
+        """
+        Microsoft Universal CRT SDK directory.
+        """
+        # Set Kit Roots versions for specified MSVC++ version
+        if self.vc_ver >= 14.0:
+            vers = ('10', '81')
+        else:
+            vers = ()
+
+        # Find path of the more recent Kit
+        for ver in vers:
+            sdkdir = self.ri.lookup(self.ri.windows_kits_roots,
+                                    'kitsroot%s' % ver)
+            if sdkdir:
+                break
+        return sdkdir or ''
+
+    @property
+    def UniversalCRTSdkLastVersion(self):
+        """
+        Microsoft Universal C Runtime SDK last version
+        """
+        return self._use_last_dir_name(os.path.join(
+            self.UniversalCRTSdkDir, 'lib'))
+
+    @property
+    def NetFxSdkVersion(self):
+        """
+        Microsoft .NET Framework SDK versions.
+        """
+        # Set FxSdk versions for specified MSVC++ version
+        if self.vc_ver >= 14.0:
+            return ('4.6.1', '4.6')
+        else:
+            return ()
+
+    @property
+    def NetFxSdkDir(self):
+        """
+        Microsoft .NET Framework SDK directory.
+        """
+        for ver in self.NetFxSdkVersion:
+            loc = os.path.join(self.ri.netfx_sdk, ver)
+            sdkdir = self.ri.lookup(loc, 'kitsinstallationfolder')
+            if sdkdir:
+                break
+        return sdkdir or ''
+
+    @property
+    def FrameworkDir32(self):
+        """
+        Microsoft .NET Framework 32bit directory.
+        """
+        # Default path
+        guess_fw = os.path.join(self.WinDir, r'Microsoft.NET\Framework')
+
+        # Try to get path from registry, if fail use default path
+        return self.ri.lookup(self.ri.vc, 'frameworkdir32') or guess_fw
+
+    @property
+    def FrameworkDir64(self):
+        """
+        Microsoft .NET Framework 64bit directory.
+        """
+        # Default path
+        guess_fw = os.path.join(self.WinDir, r'Microsoft.NET\Framework64')
+
+        # Try to get path from registry, if fail use default path
+        return self.ri.lookup(self.ri.vc, 'frameworkdir64') or guess_fw
+
+    @property
+    def FrameworkVersion32(self):
+        """
+        Microsoft .NET Framework 32bit versions.
+        """
+        return self._find_dot_net_versions(32)
+
+    @property
+    def FrameworkVersion64(self):
+        """
+        Microsoft .NET Framework 64bit versions.
+        """
+        return self._find_dot_net_versions(64)
+
+    def _find_dot_net_versions(self, bits):
+        """
+        Find Microsoft .NET Framework versions.
+
+        Parameters
+        ----------
+        bits: int
+            Platform number of bits: 32 or 64.
+        """
+        # Find actual .NET version in registry
+        reg_ver = self.ri.lookup(self.ri.vc, 'frameworkver%d' % bits)
+        dot_net_dir = getattr(self, 'FrameworkDir%d' % bits)
+        ver = reg_ver or self._use_last_dir_name(dot_net_dir, 'v') or ''
+
+        # Set .NET versions for specified MSVC++ version
+        if self.vc_ver >= 12.0:
+            frameworkver = (ver, 'v4.0')
+        elif self.vc_ver >= 10.0:
+            frameworkver = ('v4.0.30319' if ver.lower()[:2] != 'v4' else ver,
+                            'v3.5')
+        elif self.vc_ver == 9.0:
+            frameworkver = ('v3.5', 'v2.0.50727')
+        if self.vc_ver == 8.0:
+            frameworkver = ('v3.0', 'v2.0.50727')
+        return frameworkver
+
+    def _use_last_dir_name(self, path, prefix=''):
+        """
+        Return name of the last dir in path or '' if no dir found.
+
+        Parameters
+        ----------
+        path: str
+            Use dirs in this path
+        prefix: str
+            Use only dirs startings by this prefix
+        """
+        matching_dirs = (
+            dir_name
+            for dir_name in reversed(os.listdir(path))
+            if os.path.isdir(os.path.join(path, dir_name)) and
+            dir_name.startswith(prefix)
+        )
+        return next(matching_dirs, None) or ''
+
+
+class EnvironmentInfo:
+    """
+    Return environment variables for specified Microsoft Visual C++ version
+    and platform : Lib, Include, Path and libpath.
+
+    This function is compatible with Microsoft Visual C++ 9.0 to 14.0.
+
+    Script created by analysing Microsoft environment configuration files like
+    "vcvars[...].bat", "SetEnv.Cmd", "vcbuildtools.bat", ...
+
+    Parameters
+    ----------
+    arch: str
+        Target architecture.
+    vc_ver: float
+        Required Microsoft Visual C++ version. If not set, autodetect the last
+        version.
+    vc_min_ver: float
+        Minimum Microsoft Visual C++ version.
+    """
+
+    # Variables and properties in this class use originals CamelCase variables
+    # names from Microsoft source files for more easy comparaison.
+
+    def __init__(self, arch, vc_ver=None, vc_min_ver=0):
+        self.pi = PlatformInfo(arch)
+        self.ri = RegistryInfo(self.pi)
+        self.si = SystemInfo(self.ri, vc_ver)
+
+        if self.vc_ver < vc_min_ver:
+            err = 'No suitable Microsoft Visual C++ version found'
+            raise distutils.errors.DistutilsPlatformError(err)
+
+    @property
+    def vc_ver(self):
+        """
+        Microsoft Visual C++ version.
+        """
+        return self.si.vc_ver
+
+    @property
+    def VSTools(self):
+        """
+        Microsoft Visual Studio Tools
+        """
+        paths = [r'Common7\IDE', r'Common7\Tools']
+
+        if self.vc_ver >= 14.0:
+            arch_subdir = self.pi.current_dir(hidex86=True, x64=True)
+            paths += [r'Common7\IDE\CommonExtensions\Microsoft\TestWindow']
+            paths += [r'Team Tools\Performance Tools']
+            paths += [r'Team Tools\Performance Tools%s' % arch_subdir]
+
+        return [os.path.join(self.si.VSInstallDir, path) for path in paths]
+
+    @property
+    def VCIncludes(self):
+        """
+        Microsoft Visual C++ & Microsoft Foundation Class Includes
+        """
+        return [os.path.join(self.si.VCInstallDir, 'Include'),
+                os.path.join(self.si.VCInstallDir, r'ATLMFC\Include')]
+
+    @property
+    def VCLibraries(self):
+        """
+        Microsoft Visual C++ & Microsoft Foundation Class Libraries
+        """
+        if self.vc_ver >= 15.0:
+            arch_subdir = self.pi.target_dir(x64=True)
+        else:
+            arch_subdir = self.pi.target_dir(hidex86=True)
+        paths = ['Lib%s' % arch_subdir, r'ATLMFC\Lib%s' % arch_subdir]
+
+        if self.vc_ver >= 14.0:
+            paths += [r'Lib\store%s' % arch_subdir]
+
+        return [os.path.join(self.si.VCInstallDir, path) for path in paths]
+
+    @property
+    def VCStoreRefs(self):
+        """
+        Microsoft Visual C++ store references Libraries
+        """
+        if self.vc_ver < 14.0:
+            return []
+        return [os.path.join(self.si.VCInstallDir, r'Lib\store\references')]
+
+    @property
+    def VCTools(self):
+        """
+        Microsoft Visual C++ Tools
+        """
+        si = self.si
+        tools = [os.path.join(si.VCInstallDir, 'VCPackages')]
+
+        forcex86 = True if self.vc_ver <= 10.0 else False
+        arch_subdir = self.pi.cross_dir(forcex86)
+        if arch_subdir:
+            tools += [os.path.join(si.VCInstallDir, 'Bin%s' % arch_subdir)]
+
+        if self.vc_ver == 14.0:
+            path = 'Bin%s' % self.pi.current_dir(hidex86=True)
+            tools += [os.path.join(si.VCInstallDir, path)]
+
+        elif self.vc_ver >= 15.0:
+            host_dir = (r'bin\HostX86%s' if self.pi.current_is_x86() else
+                        r'bin\HostX64%s')
+            tools += [os.path.join(
+                si.VCInstallDir, host_dir % self.pi.target_dir(x64=True))]
+
+            if self.pi.current_cpu != self.pi.target_cpu:
+                tools += [os.path.join(
+                    si.VCInstallDir, host_dir % self.pi.current_dir(x64=True))]
+
+        else:
+            tools += [os.path.join(si.VCInstallDir, 'Bin')]
+
+        return tools
+
+    @property
+    def OSLibraries(self):
+        """
+        Microsoft Windows SDK Libraries
+        """
+        if self.vc_ver <= 10.0:
+            arch_subdir = self.pi.target_dir(hidex86=True, x64=True)
+            return [os.path.join(self.si.WindowsSdkDir, 'Lib%s' % arch_subdir)]
+
+        else:
+            arch_subdir = self.pi.target_dir(x64=True)
+            lib = os.path.join(self.si.WindowsSdkDir, 'lib')
+            libver = self._sdk_subdir
+            return [os.path.join(lib, '%sum%s' % (libver , arch_subdir))]
+
+    @property
+    def OSIncludes(self):
+        """
+        Microsoft Windows SDK Include
+        """
+        include = os.path.join(self.si.WindowsSdkDir, 'include')
+
+        if self.vc_ver <= 10.0:
+            return [include, os.path.join(include, 'gl')]
+
+        else:
+            if self.vc_ver >= 14.0:
+                sdkver = self._sdk_subdir
+            else:
+                sdkver = ''
+            return [os.path.join(include, '%sshared' % sdkver),
+                    os.path.join(include, '%sum' % sdkver),
+                    os.path.join(include, '%swinrt' % sdkver)]
+
+    @property
+    def OSLibpath(self):
+        """
+        Microsoft Windows SDK Libraries Paths
+        """
+        ref = os.path.join(self.si.WindowsSdkDir, 'References')
+        libpath = []
+
+        if self.vc_ver <= 9.0:
+            libpath += self.OSLibraries
+
+        if self.vc_ver >= 11.0:
+            libpath += [os.path.join(ref, r'CommonConfiguration\Neutral')]
+
+        if self.vc_ver >= 14.0:
+            libpath += [
+                ref,
+                os.path.join(self.si.WindowsSdkDir, 'UnionMetadata'),
+                os.path.join(
+                    ref,
+                    'Windows.Foundation.UniversalApiContract',
+                    '1.0.0.0',
+                ),
+                os.path.join(
+                    ref,
+                    'Windows.Foundation.FoundationContract',
+                    '1.0.0.0',
+                ),
+                os.path.join(
+                    ref,
+                    'Windows.Networking.Connectivity.WwanContract',
+                    '1.0.0.0',
+                ),
+                os.path.join(
+                    self.si.WindowsSdkDir,
+                    'ExtensionSDKs',
+                    'Microsoft.VCLibs',
+                    '%0.1f' % self.vc_ver,
+                    'References',
+                    'CommonConfiguration',
+                    'neutral',
+                ),
+            ]
+        return libpath
+
+    @property
+    def SdkTools(self):
+        """
+        Microsoft Windows SDK Tools
+        """
+        return list(self._sdk_tools())
+
+    def _sdk_tools(self):
+        """
+        Microsoft Windows SDK Tools paths generator
+        """
+        if self.vc_ver < 15.0:
+            bin_dir = 'Bin' if self.vc_ver <= 11.0 else r'Bin\x86'
+            yield os.path.join(self.si.WindowsSdkDir, bin_dir)
+
+        if not self.pi.current_is_x86():
+            arch_subdir = self.pi.current_dir(x64=True)
+            path = 'Bin%s' % arch_subdir
+            yield os.path.join(self.si.WindowsSdkDir, path)
+
+        if self.vc_ver == 10.0 or self.vc_ver == 11.0:
+            if self.pi.target_is_x86():
+                arch_subdir = ''
+            else:
+                arch_subdir = self.pi.current_dir(hidex86=True, x64=True)
+            path = r'Bin\NETFX 4.0 Tools%s' % arch_subdir
+            yield os.path.join(self.si.WindowsSdkDir, path)
+
+        elif self.vc_ver >= 15.0:
+            path = os.path.join(self.si.WindowsSdkDir, 'Bin')
+            arch_subdir = self.pi.current_dir(x64=True)
+            sdkver = self.si.WindowsSdkLastVersion
+            yield os.path.join(path, '%s%s' % (sdkver, arch_subdir))
+
+        if self.si.WindowsSDKExecutablePath:
+            yield self.si.WindowsSDKExecutablePath
+
+    @property
+    def _sdk_subdir(self):
+        """
+        Microsoft Windows SDK version subdir
+        """
+        ucrtver = self.si.WindowsSdkLastVersion
+        return ('%s\\' % ucrtver) if ucrtver else ''
+
+    @property
+    def SdkSetup(self):
+        """
+        Microsoft Windows SDK Setup
+        """
+        if self.vc_ver > 9.0:
+            return []
+
+        return [os.path.join(self.si.WindowsSdkDir, 'Setup')]
+
+    @property
+    def FxTools(self):
+        """
+        Microsoft .NET Framework Tools
+        """
+        pi = self.pi
+        si = self.si
+
+        if self.vc_ver <= 10.0:
+            include32 = True
+            include64 = not pi.target_is_x86() and not pi.current_is_x86()
+        else:
+            include32 = pi.target_is_x86() or pi.current_is_x86()
+            include64 = pi.current_cpu == 'amd64' or pi.target_cpu == 'amd64'
+
+        tools = []
+        if include32:
+            tools += [os.path.join(si.FrameworkDir32, ver)
+                      for ver in si.FrameworkVersion32]
+        if include64:
+            tools += [os.path.join(si.FrameworkDir64, ver)
+                      for ver in si.FrameworkVersion64]
+        return tools
+
+    @property
+    def NetFxSDKLibraries(self):
+        """
+        Microsoft .Net Framework SDK Libraries
+        """
+        if self.vc_ver < 14.0 or not self.si.NetFxSdkDir:
+            return []
+
+        arch_subdir = self.pi.target_dir(x64=True)
+        return [os.path.join(self.si.NetFxSdkDir, r'lib\um%s' % arch_subdir)]
+
+    @property
+    def NetFxSDKIncludes(self):
+        """
+        Microsoft .Net Framework SDK Includes
+        """
+        if self.vc_ver < 14.0 or not self.si.NetFxSdkDir:
+            return []
+
+        return [os.path.join(self.si.NetFxSdkDir, r'include\um')]
+
+    @property
+    def VsTDb(self):
+        """
+        Microsoft Visual Studio Team System Database
+        """
+        return [os.path.join(self.si.VSInstallDir, r'VSTSDB\Deploy')]
+
+    @property
+    def MSBuild(self):
+        """
+        Microsoft Build Engine
+        """
+        if self.vc_ver < 12.0:
+            return []
+        elif self.vc_ver < 15.0:
+            base_path = self.si.ProgramFilesx86
+            arch_subdir = self.pi.current_dir(hidex86=True)
+        else:
+            base_path = self.si.VSInstallDir
+            arch_subdir = ''
+
+        path = r'MSBuild\%0.1f\bin%s' % (self.vc_ver, arch_subdir)
+        build = [os.path.join(base_path, path)]
+
+        if self.vc_ver >= 15.0:
+            # Add Roslyn C# & Visual Basic Compiler
+            build += [os.path.join(base_path, path, 'Roslyn')]
+
+        return build
+
+    @property
+    def HTMLHelpWorkshop(self):
+        """
+        Microsoft HTML Help Workshop
+        """
+        if self.vc_ver < 11.0:
+            return []
+
+        return [os.path.join(self.si.ProgramFilesx86, 'HTML Help Workshop')]
+
+    @property
+    def UCRTLibraries(self):
+        """
+        Microsoft Universal C Runtime SDK Libraries
+        """
+        if self.vc_ver < 14.0:
+            return []
+
+        arch_subdir = self.pi.target_dir(x64=True)
+        lib = os.path.join(self.si.UniversalCRTSdkDir, 'lib')
+        ucrtver = self._ucrt_subdir
+        return [os.path.join(lib, '%sucrt%s' % (ucrtver, arch_subdir))]
+
+    @property
+    def UCRTIncludes(self):
+        """
+        Microsoft Universal C Runtime SDK Include
+        """
+        if self.vc_ver < 14.0:
+            return []
+
+        include = os.path.join(self.si.UniversalCRTSdkDir, 'include')
+        return [os.path.join(include, '%sucrt' % self._ucrt_subdir)]
+
+    @property
+    def _ucrt_subdir(self):
+        """
+        Microsoft Universal C Runtime SDK version subdir
+        """
+        ucrtver = self.si.UniversalCRTSdkLastVersion
+        return ('%s\\' % ucrtver) if ucrtver else ''
+
+    @property
+    def FSharp(self):
+        """
+        Microsoft Visual F#
+        """
+        if self.vc_ver < 11.0 and self.vc_ver > 12.0:
+            return []
+
+        return self.si.FSharpInstallDir
+
+    @property
+    def VCRuntimeRedist(self):
+        """
+        Microsoft Visual C++ runtime redistribuable dll
+        """
+        arch_subdir = self.pi.target_dir(x64=True)
+        if self.vc_ver < 15:
+            redist_path = self.si.VCInstallDir
+            vcruntime = 'redist%s\\Microsoft.VC%d0.CRT\\vcruntime%d0.dll'
+        else:
+            redist_path = self.si.VCInstallDir.replace('\\Tools', '\\Redist')
+            vcruntime = 'onecore%s\\Microsoft.VC%d0.CRT\\vcruntime%d0.dll'
+
+        # Visual Studio 2017  is still Visual C++ 14.0
+        dll_ver = 14.0 if self.vc_ver == 15 else self.vc_ver
+
+        vcruntime = vcruntime % (arch_subdir, self.vc_ver, dll_ver)
+        return os.path.join(redist_path, vcruntime)
+
+    def return_env(self, exists=True):
+        """
+        Return environment dict.
+
+        Parameters
+        ----------
+        exists: bool
+            It True, only return existing paths.
+        """
+        env = dict(
+            include=self._build_paths('include',
+                                      [self.VCIncludes,
+                                       self.OSIncludes,
+                                       self.UCRTIncludes,
+                                       self.NetFxSDKIncludes],
+                                      exists),
+            lib=self._build_paths('lib',
+                                  [self.VCLibraries,
+                                   self.OSLibraries,
+                                   self.FxTools,
+                                   self.UCRTLibraries,
+                                   self.NetFxSDKLibraries],
+                                  exists),
+            libpath=self._build_paths('libpath',
+                                      [self.VCLibraries,
+                                       self.FxTools,
+                                       self.VCStoreRefs,
+                                       self.OSLibpath],
+                                      exists),
+            path=self._build_paths('path',
+                                   [self.VCTools,
+                                    self.VSTools,
+                                    self.VsTDb,
+                                    self.SdkTools,
+                                    self.SdkSetup,
+                                    self.FxTools,
+                                    self.MSBuild,
+                                    self.HTMLHelpWorkshop,
+                                    self.FSharp],
+                                   exists),
+        )
+        if self.vc_ver >= 14 and os.path.isfile(self.VCRuntimeRedist):
+            env['py_vcruntime_redist'] = self.VCRuntimeRedist
+        return env
+
+    def _build_paths(self, name, spec_path_lists, exists):
+        """
+        Given an environment variable name and specified paths,
+        return a pathsep-separated string of paths containing
+        unique, extant, directories from those paths and from
+        the environment variable. Raise an error if no paths
+        are resolved.
+        """
+        # flatten spec_path_lists
+        spec_paths = itertools.chain.from_iterable(spec_path_lists)
+        env_paths = safe_env.get(name, '').split(os.pathsep)
+        paths = itertools.chain(spec_paths, env_paths)
+        extant_paths = list(filter(os.path.isdir, paths)) if exists else paths
+        if not extant_paths:
+            msg = "%s environment variable is empty" % name.upper()
+            raise distutils.errors.DistutilsPlatformError(msg)
+        unique_paths = self._unique_everseen(extant_paths)
+        return os.pathsep.join(unique_paths)
+
+    # from Python docs
+    def _unique_everseen(self, iterable, key=None):
+        """
+        List unique elements, preserving order.
+        Remember all elements ever seen.
+
+        _unique_everseen('AAAABBBCCDAABBB') --> A B C D
+
+        _unique_everseen('ABBCcAD', str.lower) --> A B C D
+        """
+        seen = set()
+        seen_add = seen.add
+        if key is None:
+            for element in filterfalse(seen.__contains__, iterable):
+                seen_add(element)
+                yield element
+        else:
+            for element in iterable:
+                k = key(element)
+                if k not in seen:
+                    seen_add(k)
+                    yield element
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/namespaces.py b/vendor/setuptools-39.0.1/build/lib/setuptools/namespaces.py
new file mode 100644
index 00000000..dc16106d
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/namespaces.py
@@ -0,0 +1,107 @@
+import os
+from distutils import log
+import itertools
+
+from setuptools.extern.six.moves import map
+
+
+flatten = itertools.chain.from_iterable
+
+
+class Installer:
+
+    nspkg_ext = '-nspkg.pth'
+
+    def install_namespaces(self):
+        nsp = self._get_all_ns_packages()
+        if not nsp:
+            return
+        filename, ext = os.path.splitext(self._get_target())
+        filename += self.nspkg_ext
+        self.outputs.append(filename)
+        log.info("Installing %s", filename)
+        lines = map(self._gen_nspkg_line, nsp)
+
+        if self.dry_run:
+            # always generate the lines, even in dry run
+            list(lines)
+            return
+
+        with open(filename, 'wt') as f:
+            f.writelines(lines)
+
+    def uninstall_namespaces(self):
+        filename, ext = os.path.splitext(self._get_target())
+        filename += self.nspkg_ext
+        if not os.path.exists(filename):
+            return
+        log.info("Removing %s", filename)
+        os.remove(filename)
+
+    def _get_target(self):
+        return self.target
+
+    _nspkg_tmpl = (
+        "import sys, types, os",
+        "has_mfs = sys.version_info > (3, 5)",
+        "p = os.path.join(%(root)s, *%(pth)r)",
+        "importlib = has_mfs and __import__('importlib.util')",
+        "has_mfs and __import__('importlib.machinery')",
+        "m = has_mfs and "
+            "sys.modules.setdefault(%(pkg)r, "
+                "importlib.util.module_from_spec("
+                    "importlib.machinery.PathFinder.find_spec(%(pkg)r, "
+                        "[os.path.dirname(p)])))",
+        "m = m or "
+            "sys.modules.setdefault(%(pkg)r, types.ModuleType(%(pkg)r))",
+        "mp = (m or []) and m.__dict__.setdefault('__path__',[])",
+        "(p not in mp) and mp.append(p)",
+    )
+    "lines for the namespace installer"
+
+    _nspkg_tmpl_multi = (
+        'm and setattr(sys.modules[%(parent)r], %(child)r, m)',
+    )
+    "additional line(s) when a parent package is indicated"
+
+    def _get_root(self):
+        return "sys._getframe(1).f_locals['sitedir']"
+
+    def _gen_nspkg_line(self, pkg):
+        # ensure pkg is not a unicode string under Python 2.7
+        pkg = str(pkg)
+        pth = tuple(pkg.split('.'))
+        root = self._get_root()
+        tmpl_lines = self._nspkg_tmpl
+        parent, sep, child = pkg.rpartition('.')
+        if parent:
+            tmpl_lines += self._nspkg_tmpl_multi
+        return ';'.join(tmpl_lines) % locals() + '\n'
+
+    def _get_all_ns_packages(self):
+        """Return sorted list of all package namespaces"""
+        pkgs = self.distribution.namespace_packages or []
+        return sorted(flatten(map(self._pkg_names, pkgs)))
+
+    @staticmethod
+    def _pkg_names(pkg):
+        """
+        Given a namespace package, yield the components of that
+        package.
+
+        >>> names = Installer._pkg_names('a.b.c')
+        >>> set(names) == set(['a', 'a.b', 'a.b.c'])
+        True
+        """
+        parts = pkg.split('.')
+        while parts:
+            yield '.'.join(parts)
+            parts.pop()
+
+
+class DevelopInstaller(Installer):
+    def _get_root(self):
+        return repr(str(self.egg_path))
+
+    def _get_target(self):
+        return self.egg_link
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/package_index.py b/vendor/setuptools-39.0.1/build/lib/setuptools/package_index.py
new file mode 100644
index 00000000..914b5e61
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/package_index.py
@@ -0,0 +1,1119 @@
+"""PyPI and direct package downloading"""
+import sys
+import os
+import re
+import shutil
+import socket
+import base64
+import hashlib
+import itertools
+from functools import wraps
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import urllib, http_client, configparser, map
+
+import setuptools
+from pkg_resources import (
+    CHECKOUT_DIST, Distribution, BINARY_DIST, normalize_path, SOURCE_DIST,
+    Environment, find_distributions, safe_name, safe_version,
+    to_filename, Requirement, DEVELOP_DIST, EGG_DIST,
+)
+from setuptools import ssl_support
+from distutils import log
+from distutils.errors import DistutilsError
+from fnmatch import translate
+from setuptools.py27compat import get_all_headers
+from setuptools.py33compat import unescape
+from setuptools.wheel import Wheel
+
+EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.+!]+)$')
+HREF = re.compile("""href\\s*=\\s*['"]?([^'"> ]+)""", re.I)
+# this is here to fix emacs' cruddy broken syntax highlighting
+PYPI_MD5 = re.compile(
+    '<a href="([^"#]+)">([^<]+)</a>\n\\s+\\(<a (?:title="MD5 hash"\n\\s+)'
+    'href="[^?]+\\?:action=show_md5&amp;digest=([0-9a-f]{32})">md5</a>\\)'
+)
+URL_SCHEME = re.compile('([-+.a-z0-9]{2,}):', re.I).match
+EXTENSIONS = ".tar.gz .tar.bz2 .tar .zip .tgz".split()
+
+__all__ = [
+    'PackageIndex', 'distros_for_url', 'parse_bdist_wininst',
+    'interpret_distro_name',
+]
+
+_SOCKET_TIMEOUT = 15
+
+_tmpl = "setuptools/{setuptools.__version__} Python-urllib/{py_major}"
+user_agent = _tmpl.format(py_major=sys.version[:3], setuptools=setuptools)
+
+
+def parse_requirement_arg(spec):
+    try:
+        return Requirement.parse(spec)
+    except ValueError:
+        raise DistutilsError(
+            "Not a URL, existing file, or requirement spec: %r" % (spec,)
+        )
+
+
+def parse_bdist_wininst(name):
+    """Return (base,pyversion) or (None,None) for possible .exe name"""
+
+    lower = name.lower()
+    base, py_ver, plat = None, None, None
+
+    if lower.endswith('.exe'):
+        if lower.endswith('.win32.exe'):
+            base = name[:-10]
+            plat = 'win32'
+        elif lower.startswith('.win32-py', -16):
+            py_ver = name[-7:-4]
+            base = name[:-16]
+            plat = 'win32'
+        elif lower.endswith('.win-amd64.exe'):
+            base = name[:-14]
+            plat = 'win-amd64'
+        elif lower.startswith('.win-amd64-py', -20):
+            py_ver = name[-7:-4]
+            base = name[:-20]
+            plat = 'win-amd64'
+    return base, py_ver, plat
+
+
+def egg_info_for_url(url):
+    parts = urllib.parse.urlparse(url)
+    scheme, server, path, parameters, query, fragment = parts
+    base = urllib.parse.unquote(path.split('/')[-1])
+    if server == 'sourceforge.net' and base == 'download':  # XXX Yuck
+        base = urllib.parse.unquote(path.split('/')[-2])
+    if '#' in base:
+        base, fragment = base.split('#', 1)
+    return base, fragment
+
+
+def distros_for_url(url, metadata=None):
+    """Yield egg or source distribution objects that might be found at a URL"""
+    base, fragment = egg_info_for_url(url)
+    for dist in distros_for_location(url, base, metadata):
+        yield dist
+    if fragment:
+        match = EGG_FRAGMENT.match(fragment)
+        if match:
+            for dist in interpret_distro_name(
+                url, match.group(1), metadata, precedence=CHECKOUT_DIST
+            ):
+                yield dist
+
+
+def distros_for_location(location, basename, metadata=None):
+    """Yield egg or source distribution objects based on basename"""
+    if basename.endswith('.egg.zip'):
+        basename = basename[:-4]  # strip the .zip
+    if basename.endswith('.egg') and '-' in basename:
+        # only one, unambiguous interpretation
+        return [Distribution.from_location(location, basename, metadata)]
+    if basename.endswith('.whl') and '-' in basename:
+        wheel = Wheel(basename)
+        if not wheel.is_compatible():
+            return []
+        return [Distribution(
+            location=location,
+            project_name=wheel.project_name,
+            version=wheel.version,
+            # Increase priority over eggs.
+            precedence=EGG_DIST + 1,
+        )]
+    if basename.endswith('.exe'):
+        win_base, py_ver, platform = parse_bdist_wininst(basename)
+        if win_base is not None:
+            return interpret_distro_name(
+                location, win_base, metadata, py_ver, BINARY_DIST, platform
+            )
+    # Try source distro extensions (.zip, .tgz, etc.)
+    #
+    for ext in EXTENSIONS:
+        if basename.endswith(ext):
+            basename = basename[:-len(ext)]
+            return interpret_distro_name(location, basename, metadata)
+    return []  # no extension matched
+
+
+def distros_for_filename(filename, metadata=None):
+    """Yield possible egg or source distribution objects based on a filename"""
+    return distros_for_location(
+        normalize_path(filename), os.path.basename(filename), metadata
+    )
+
+
+def interpret_distro_name(
+        location, basename, metadata, py_version=None, precedence=SOURCE_DIST,
+        platform=None
+):
+    """Generate alternative interpretations of a source distro name
+
+    Note: if `location` is a filesystem filename, you should call
+    ``pkg_resources.normalize_path()`` on it before passing it to this
+    routine!
+    """
+    # Generate alternative interpretations of a source distro name
+    # Because some packages are ambiguous as to name/versions split
+    # e.g. "adns-python-1.1.0", "egenix-mx-commercial", etc.
+    # So, we generate each possible interepretation (e.g. "adns, python-1.1.0"
+    # "adns-python, 1.1.0", and "adns-python-1.1.0, no version").  In practice,
+    # the spurious interpretations should be ignored, because in the event
+    # there's also an "adns" package, the spurious "python-1.1.0" version will
+    # compare lower than any numeric version number, and is therefore unlikely
+    # to match a request for it.  It's still a potential problem, though, and
+    # in the long run PyPI and the distutils should go for "safe" names and
+    # versions in distribution archive names (sdist and bdist).
+
+    parts = basename.split('-')
+    if not py_version and any(re.match(r'py\d\.\d$', p) for p in parts[2:]):
+        # it is a bdist_dumb, not an sdist -- bail out
+        return
+
+    for p in range(1, len(parts) + 1):
+        yield Distribution(
+            location, metadata, '-'.join(parts[:p]), '-'.join(parts[p:]),
+            py_version=py_version, precedence=precedence,
+            platform=platform
+        )
+
+
+# From Python 2.7 docs
+def unique_everseen(iterable, key=None):
+    "List unique elements, preserving order. Remember all elements ever seen."
+    # unique_everseen('AAAABBBCCDAABBB') --> A B C D
+    # unique_everseen('ABBCcAD', str.lower) --> A B C D
+    seen = set()
+    seen_add = seen.add
+    if key is None:
+        for element in six.moves.filterfalse(seen.__contains__, iterable):
+            seen_add(element)
+            yield element
+    else:
+        for element in iterable:
+            k = key(element)
+            if k not in seen:
+                seen_add(k)
+                yield element
+
+
+def unique_values(func):
+    """
+    Wrap a function returning an iterable such that the resulting iterable
+    only ever yields unique items.
+    """
+
+    @wraps(func)
+    def wrapper(*args, **kwargs):
+        return unique_everseen(func(*args, **kwargs))
+
+    return wrapper
+
+
+REL = re.compile(r"""<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>""", re.I)
+# this line is here to fix emacs' cruddy broken syntax highlighting
+
+
+@unique_values
+def find_external_links(url, page):
+    """Find rel="homepage" and rel="download" links in `page`, yielding URLs"""
+
+    for match in REL.finditer(page):
+        tag, rel = match.groups()
+        rels = set(map(str.strip, rel.lower().split(',')))
+        if 'homepage' in rels or 'download' in rels:
+            for match in HREF.finditer(tag):
+                yield urllib.parse.urljoin(url, htmldecode(match.group(1)))
+
+    for tag in ("<th>Home Page", "<th>Download URL"):
+        pos = page.find(tag)
+        if pos != -1:
+            match = HREF.search(page, pos)
+            if match:
+                yield urllib.parse.urljoin(url, htmldecode(match.group(1)))
+
+
+class ContentChecker(object):
+    """
+    A null content checker that defines the interface for checking content
+    """
+
+    def feed(self, block):
+        """
+        Feed a block of data to the hash.
+        """
+        return
+
+    def is_valid(self):
+        """
+        Check the hash. Return False if validation fails.
+        """
+        return True
+
+    def report(self, reporter, template):
+        """
+        Call reporter with information about the checker (hash name)
+        substituted into the template.
+        """
+        return
+
+
+class HashChecker(ContentChecker):
+    pattern = re.compile(
+        r'(?P<hash_name>sha1|sha224|sha384|sha256|sha512|md5)='
+        r'(?P<expected>[a-f0-9]+)'
+    )
+
+    def __init__(self, hash_name, expected):
+        self.hash_name = hash_name
+        self.hash = hashlib.new(hash_name)
+        self.expected = expected
+
+    @classmethod
+    def from_url(cls, url):
+        "Construct a (possibly null) ContentChecker from a URL"
+        fragment = urllib.parse.urlparse(url)[-1]
+        if not fragment:
+            return ContentChecker()
+        match = cls.pattern.search(fragment)
+        if not match:
+            return ContentChecker()
+        return cls(**match.groupdict())
+
+    def feed(self, block):
+        self.hash.update(block)
+
+    def is_valid(self):
+        return self.hash.hexdigest() == self.expected
+
+    def report(self, reporter, template):
+        msg = template % self.hash_name
+        return reporter(msg)
+
+
+class PackageIndex(Environment):
+    """A distribution index that scans web pages for download URLs"""
+
+    def __init__(
+            self, index_url="https://pypi.python.org/simple", hosts=('*',),
+            ca_bundle=None, verify_ssl=True, *args, **kw
+    ):
+        Environment.__init__(self, *args, **kw)
+        self.index_url = index_url + "/" [:not index_url.endswith('/')]
+        self.scanned_urls = {}
+        self.fetched_urls = {}
+        self.package_pages = {}
+        self.allows = re.compile('|'.join(map(translate, hosts))).match
+        self.to_scan = []
+        use_ssl = (
+            verify_ssl
+            and ssl_support.is_available
+            and (ca_bundle or ssl_support.find_ca_bundle())
+        )
+        if use_ssl:
+            self.opener = ssl_support.opener_for(ca_bundle)
+        else:
+            self.opener = urllib.request.urlopen
+
+    def process_url(self, url, retrieve=False):
+        """Evaluate a URL as a possible download, and maybe retrieve it"""
+        if url in self.scanned_urls and not retrieve:
+            return
+        self.scanned_urls[url] = True
+        if not URL_SCHEME(url):
+            self.process_filename(url)
+            return
+        else:
+            dists = list(distros_for_url(url))
+            if dists:
+                if not self.url_ok(url):
+                    return
+                self.debug("Found link: %s", url)
+
+        if dists or not retrieve or url in self.fetched_urls:
+            list(map(self.add, dists))
+            return  # don't need the actual page
+
+        if not self.url_ok(url):
+            self.fetched_urls[url] = True
+            return
+
+        self.info("Reading %s", url)
+        self.fetched_urls[url] = True  # prevent multiple fetch attempts
+        tmpl = "Download error on %s: %%s -- Some packages may not be found!"
+        f = self.open_url(url, tmpl % url)
+        if f is None:
+            return
+        self.fetched_urls[f.url] = True
+        if 'html' not in f.headers.get('content-type', '').lower():
+            f.close()  # not html, we can't process it
+            return
+
+        base = f.url  # handle redirects
+        page = f.read()
+        if not isinstance(page, str):
+            # In Python 3 and got bytes but want str.
+            if isinstance(f, urllib.error.HTTPError):
+                # Errors have no charset, assume latin1:
+                charset = 'latin-1'
+            else:
+                charset = f.headers.get_param('charset') or 'latin-1'
+            page = page.decode(charset, "ignore")
+        f.close()
+        for match in HREF.finditer(page):
+            link = urllib.parse.urljoin(base, htmldecode(match.group(1)))
+            self.process_url(link)
+        if url.startswith(self.index_url) and getattr(f, 'code', None) != 404:
+            page = self.process_index(url, page)
+
+    def process_filename(self, fn, nested=False):
+        # process filenames or directories
+        if not os.path.exists(fn):
+            self.warn("Not found: %s", fn)
+            return
+
+        if os.path.isdir(fn) and not nested:
+            path = os.path.realpath(fn)
+            for item in os.listdir(path):
+                self.process_filename(os.path.join(path, item), True)
+
+        dists = distros_for_filename(fn)
+        if dists:
+            self.debug("Found: %s", fn)
+            list(map(self.add, dists))
+
+    def url_ok(self, url, fatal=False):
+        s = URL_SCHEME(url)
+        is_file = s and s.group(1).lower() == 'file'
+        if is_file or self.allows(urllib.parse.urlparse(url)[1]):
+            return True
+        msg = (
+            "\nNote: Bypassing %s (disallowed host; see "
+            "http://bit.ly/2hrImnY for details).\n")
+        if fatal:
+            raise DistutilsError(msg % url)
+        else:
+            self.warn(msg, url)
+
+    def scan_egg_links(self, search_path):
+        dirs = filter(os.path.isdir, search_path)
+        egg_links = (
+            (path, entry)
+            for path in dirs
+            for entry in os.listdir(path)
+            if entry.endswith('.egg-link')
+        )
+        list(itertools.starmap(self.scan_egg_link, egg_links))
+
+    def scan_egg_link(self, path, entry):
+        with open(os.path.join(path, entry)) as raw_lines:
+            # filter non-empty lines
+            lines = list(filter(None, map(str.strip, raw_lines)))
+
+        if len(lines) != 2:
+            # format is not recognized; punt
+            return
+
+        egg_path, setup_path = lines
+
+        for dist in find_distributions(os.path.join(path, egg_path)):
+            dist.location = os.path.join(path, *lines)
+            dist.precedence = SOURCE_DIST
+            self.add(dist)
+
+    def process_index(self, url, page):
+        """Process the contents of a PyPI page"""
+
+        def scan(link):
+            # Process a URL to see if it's for a package page
+            if link.startswith(self.index_url):
+                parts = list(map(
+                    urllib.parse.unquote, link[len(self.index_url):].split('/')
+                ))
+                if len(parts) == 2 and '#' not in parts[1]:
+                    # it's a package page, sanitize and index it
+                    pkg = safe_name(parts[0])
+                    ver = safe_version(parts[1])
+                    self.package_pages.setdefault(pkg.lower(), {})[link] = True
+                    return to_filename(pkg), to_filename(ver)
+            return None, None
+
+        # process an index page into the package-page index
+        for match in HREF.finditer(page):
+            try:
+                scan(urllib.parse.urljoin(url, htmldecode(match.group(1))))
+            except ValueError:
+                pass
+
+        pkg, ver = scan(url)  # ensure this page is in the page index
+        if pkg:
+            # process individual package page
+            for new_url in find_external_links(url, page):
+                # Process the found URL
+                base, frag = egg_info_for_url(new_url)
+                if base.endswith('.py') and not frag:
+                    if ver:
+                        new_url += '#egg=%s-%s' % (pkg, ver)
+                    else:
+                        self.need_version_info(url)
+                self.scan_url(new_url)
+
+            return PYPI_MD5.sub(
+                lambda m: '<a href="%s#md5=%s">%s</a>' % m.group(1, 3, 2), page
+            )
+        else:
+            return ""  # no sense double-scanning non-package pages
+
+    def need_version_info(self, url):
+        self.scan_all(
+            "Page at %s links to .py file(s) without version info; an index "
+            "scan is required.", url
+        )
+
+    def scan_all(self, msg=None, *args):
+        if self.index_url not in self.fetched_urls:
+            if msg:
+                self.warn(msg, *args)
+            self.info(
+                "Scanning index of all packages (this may take a while)"
+            )
+        self.scan_url(self.index_url)
+
+    def find_packages(self, requirement):
+        self.scan_url(self.index_url + requirement.unsafe_name + '/')
+
+        if not self.package_pages.get(requirement.key):
+            # Fall back to safe version of the name
+            self.scan_url(self.index_url + requirement.project_name + '/')
+
+        if not self.package_pages.get(requirement.key):
+            # We couldn't find the target package, so search the index page too
+            self.not_found_in_index(requirement)
+
+        for url in list(self.package_pages.get(requirement.key, ())):
+            # scan each page that might be related to the desired package
+            self.scan_url(url)
+
+    def obtain(self, requirement, installer=None):
+        self.prescan()
+        self.find_packages(requirement)
+        for dist in self[requirement.key]:
+            if dist in requirement:
+                return dist
+            self.debug("%s does not match %s", requirement, dist)
+        return super(PackageIndex, self).obtain(requirement, installer)
+
+    def check_hash(self, checker, filename, tfp):
+        """
+        checker is a ContentChecker
+        """
+        checker.report(
+            self.debug,
+            "Validating %%s checksum for %s" % filename)
+        if not checker.is_valid():
+            tfp.close()
+            os.unlink(filename)
+            raise DistutilsError(
+                "%s validation failed for %s; "
+                "possible download problem?"
+                % (checker.hash.name, os.path.basename(filename))
+            )
+
+    def add_find_links(self, urls):
+        """Add `urls` to the list that will be prescanned for searches"""
+        for url in urls:
+            if (
+                self.to_scan is None  # if we have already "gone online"
+                or not URL_SCHEME(url)  # or it's a local file/directory
+                or url.startswith('file:')
+                or list(distros_for_url(url))  # or a direct package link
+            ):
+                # then go ahead and process it now
+                self.scan_url(url)
+            else:
+                # otherwise, defer retrieval till later
+                self.to_scan.append(url)
+
+    def prescan(self):
+        """Scan urls scheduled for prescanning (e.g. --find-links)"""
+        if self.to_scan:
+            list(map(self.scan_url, self.to_scan))
+        self.to_scan = None  # from now on, go ahead and process immediately
+
+    def not_found_in_index(self, requirement):
+        if self[requirement.key]:  # we've seen at least one distro
+            meth, msg = self.info, "Couldn't retrieve index page for %r"
+        else:  # no distros seen for this name, might be misspelled
+            meth, msg = (
+                self.warn,
+                "Couldn't find index page for %r (maybe misspelled?)")
+        meth(msg, requirement.unsafe_name)
+        self.scan_all()
+
+    def download(self, spec, tmpdir):
+        """Locate and/or download `spec` to `tmpdir`, returning a local path
+
+        `spec` may be a ``Requirement`` object, or a string containing a URL,
+        an existing local filename, or a project/version requirement spec
+        (i.e. the string form of a ``Requirement`` object).  If it is the URL
+        of a .py file with an unambiguous ``#egg=name-version`` tag (i.e., one
+        that escapes ``-`` as ``_`` throughout), a trivial ``setup.py`` is
+        automatically created alongside the downloaded file.
+
+        If `spec` is a ``Requirement`` object or a string containing a
+        project/version requirement spec, this method returns the location of
+        a matching distribution (possibly after downloading it to `tmpdir`).
+        If `spec` is a locally existing file or directory name, it is simply
+        returned unchanged.  If `spec` is a URL, it is downloaded to a subpath
+        of `tmpdir`, and the local filename is returned.  Various errors may be
+        raised if a problem occurs during downloading.
+        """
+        if not isinstance(spec, Requirement):
+            scheme = URL_SCHEME(spec)
+            if scheme:
+                # It's a url, download it to tmpdir
+                found = self._download_url(scheme.group(1), spec, tmpdir)
+                base, fragment = egg_info_for_url(spec)
+                if base.endswith('.py'):
+                    found = self.gen_setup(found, fragment, tmpdir)
+                return found
+            elif os.path.exists(spec):
+                # Existing file or directory, just return it
+                return spec
+            else:
+                spec = parse_requirement_arg(spec)
+        return getattr(self.fetch_distribution(spec, tmpdir), 'location', None)
+
+    def fetch_distribution(
+            self, requirement, tmpdir, force_scan=False, source=False,
+            develop_ok=False, local_index=None):
+        """Obtain a distribution suitable for fulfilling `requirement`
+
+        `requirement` must be a ``pkg_resources.Requirement`` instance.
+        If necessary, or if the `force_scan` flag is set, the requirement is
+        searched for in the (online) package index as well as the locally
+        installed packages.  If a distribution matching `requirement` is found,
+        the returned distribution's ``location`` is the value you would have
+        gotten from calling the ``download()`` method with the matching
+        distribution's URL or filename.  If no matching distribution is found,
+        ``None`` is returned.
+
+        If the `source` flag is set, only source distributions and source
+        checkout links will be considered.  Unless the `develop_ok` flag is
+        set, development and system eggs (i.e., those using the ``.egg-info``
+        format) will be ignored.
+        """
+        # process a Requirement
+        self.info("Searching for %s", requirement)
+        skipped = {}
+        dist = None
+
+        def find(req, env=None):
+            if env is None:
+                env = self
+            # Find a matching distribution; may be called more than once
+
+            for dist in env[req.key]:
+
+                if dist.precedence == DEVELOP_DIST and not develop_ok:
+                    if dist not in skipped:
+                        self.warn(
+                            "Skipping development or system egg: %s", dist,
+                        )
+                        skipped[dist] = 1
+                    continue
+
+                test = (
+                    dist in req
+                    and (dist.precedence <= SOURCE_DIST or not source)
+                )
+                if test:
+                    loc = self.download(dist.location, tmpdir)
+                    dist.download_location = loc
+                    if os.path.exists(dist.download_location):
+                        return dist
+
+        if force_scan:
+            self.prescan()
+            self.find_packages(requirement)
+            dist = find(requirement)
+
+        if not dist and local_index is not None:
+            dist = find(requirement, local_index)
+
+        if dist is None:
+            if self.to_scan is not None:
+                self.prescan()
+            dist = find(requirement)
+
+        if dist is None and not force_scan:
+            self.find_packages(requirement)
+            dist = find(requirement)
+
+        if dist is None:
+            self.warn(
+                "No local packages or working download links found for %s%s",
+                (source and "a source distribution of " or ""),
+                requirement,
+            )
+        else:
+            self.info("Best match: %s", dist)
+            return dist.clone(location=dist.download_location)
+
+    def fetch(self, requirement, tmpdir, force_scan=False, source=False):
+        """Obtain a file suitable for fulfilling `requirement`
+
+        DEPRECATED; use the ``fetch_distribution()`` method now instead.  For
+        backward compatibility, this routine is identical but returns the
+        ``location`` of the downloaded distribution instead of a distribution
+        object.
+        """
+        dist = self.fetch_distribution(requirement, tmpdir, force_scan, source)
+        if dist is not None:
+            return dist.location
+        return None
+
+    def gen_setup(self, filename, fragment, tmpdir):
+        match = EGG_FRAGMENT.match(fragment)
+        dists = match and [
+            d for d in
+            interpret_distro_name(filename, match.group(1), None) if d.version
+        ] or []
+
+        if len(dists) == 1:  # unambiguous ``#egg`` fragment
+            basename = os.path.basename(filename)
+
+            # Make sure the file has been downloaded to the temp dir.
+            if os.path.dirname(filename) != tmpdir:
+                dst = os.path.join(tmpdir, basename)
+                from setuptools.command.easy_install import samefile
+                if not samefile(filename, dst):
+                    shutil.copy2(filename, dst)
+                    filename = dst
+
+            with open(os.path.join(tmpdir, 'setup.py'), 'w') as file:
+                file.write(
+                    "from setuptools import setup\n"
+                    "setup(name=%r, version=%r, py_modules=[%r])\n"
+                    % (
+                        dists[0].project_name, dists[0].version,
+                        os.path.splitext(basename)[0]
+                    )
+                )
+            return filename
+
+        elif match:
+            raise DistutilsError(
+                "Can't unambiguously interpret project/version identifier %r; "
+                "any dashes in the name or version should be escaped using "
+                "underscores. %r" % (fragment, dists)
+            )
+        else:
+            raise DistutilsError(
+                "Can't process plain .py files without an '#egg=name-version'"
+                " suffix to enable automatic setup script generation."
+            )
+
+    dl_blocksize = 8192
+
+    def _download_to(self, url, filename):
+        self.info("Downloading %s", url)
+        # Download the file
+        fp = None
+        try:
+            checker = HashChecker.from_url(url)
+            fp = self.open_url(url)
+            if isinstance(fp, urllib.error.HTTPError):
+                raise DistutilsError(
+                    "Can't download %s: %s %s" % (url, fp.code, fp.msg)
+                )
+            headers = fp.info()
+            blocknum = 0
+            bs = self.dl_blocksize
+            size = -1
+            if "content-length" in headers:
+                # Some servers return multiple Content-Length headers :(
+                sizes = get_all_headers(headers, 'Content-Length')
+                size = max(map(int, sizes))
+                self.reporthook(url, filename, blocknum, bs, size)
+            with open(filename, 'wb') as tfp:
+                while True:
+                    block = fp.read(bs)
+                    if block:
+                        checker.feed(block)
+                        tfp.write(block)
+                        blocknum += 1
+                        self.reporthook(url, filename, blocknum, bs, size)
+                    else:
+                        break
+                self.check_hash(checker, filename, tfp)
+            return headers
+        finally:
+            if fp:
+                fp.close()
+
+    def reporthook(self, url, filename, blocknum, blksize, size):
+        pass  # no-op
+
+    def open_url(self, url, warning=None):
+        if url.startswith('file:'):
+            return local_open(url)
+        try:
+            return open_with_auth(url, self.opener)
+        except (ValueError, http_client.InvalidURL) as v:
+            msg = ' '.join([str(arg) for arg in v.args])
+            if warning:
+                self.warn(warning, msg)
+            else:
+                raise DistutilsError('%s %s' % (url, msg))
+        except urllib.error.HTTPError as v:
+            return v
+        except urllib.error.URLError as v:
+            if warning:
+                self.warn(warning, v.reason)
+            else:
+                raise DistutilsError("Download error for %s: %s"
+                                     % (url, v.reason))
+        except http_client.BadStatusLine as v:
+            if warning:
+                self.warn(warning, v.line)
+            else:
+                raise DistutilsError(
+                    '%s returned a bad status line. The server might be '
+                    'down, %s' %
+                    (url, v.line)
+                )
+        except (http_client.HTTPException, socket.error) as v:
+            if warning:
+                self.warn(warning, v)
+            else:
+                raise DistutilsError("Download error for %s: %s"
+                                     % (url, v))
+
+    def _download_url(self, scheme, url, tmpdir):
+        # Determine download filename
+        #
+        name, fragment = egg_info_for_url(url)
+        if name:
+            while '..' in name:
+                name = name.replace('..', '.').replace('\\', '_')
+        else:
+            name = "__downloaded__"  # default if URL has no path contents
+
+        if name.endswith('.egg.zip'):
+            name = name[:-4]  # strip the extra .zip before download
+
+        filename = os.path.join(tmpdir, name)
+
+        # Download the file
+        #
+        if scheme == 'svn' or scheme.startswith('svn+'):
+            return self._download_svn(url, filename)
+        elif scheme == 'git' or scheme.startswith('git+'):
+            return self._download_git(url, filename)
+        elif scheme.startswith('hg+'):
+            return self._download_hg(url, filename)
+        elif scheme == 'file':
+            return urllib.request.url2pathname(urllib.parse.urlparse(url)[2])
+        else:
+            self.url_ok(url, True)  # raises error if not allowed
+            return self._attempt_download(url, filename)
+
+    def scan_url(self, url):
+        self.process_url(url, True)
+
+    def _attempt_download(self, url, filename):
+        headers = self._download_to(url, filename)
+        if 'html' in headers.get('content-type', '').lower():
+            return self._download_html(url, headers, filename)
+        else:
+            return filename
+
+    def _download_html(self, url, headers, filename):
+        file = open(filename)
+        for line in file:
+            if line.strip():
+                # Check for a subversion index page
+                if re.search(r'<title>([^- ]+ - )?Revision \d+:', line):
+                    # it's a subversion index page:
+                    file.close()
+                    os.unlink(filename)
+                    return self._download_svn(url, filename)
+                break  # not an index page
+        file.close()
+        os.unlink(filename)
+        raise DistutilsError("Unexpected HTML page found at " + url)
+
+    def _download_svn(self, url, filename):
+        url = url.split('#', 1)[0]  # remove any fragment for svn's sake
+        creds = ''
+        if url.lower().startswith('svn:') and '@' in url:
+            scheme, netloc, path, p, q, f = urllib.parse.urlparse(url)
+            if not netloc and path.startswith('//') and '/' in path[2:]:
+                netloc, path = path[2:].split('/', 1)
+                auth, host = urllib.parse.splituser(netloc)
+                if auth:
+                    if ':' in auth:
+                        user, pw = auth.split(':', 1)
+                        creds = " --username=%s --password=%s" % (user, pw)
+                    else:
+                        creds = " --username=" + auth
+                    netloc = host
+                    parts = scheme, netloc, url, p, q, f
+                    url = urllib.parse.urlunparse(parts)
+        self.info("Doing subversion checkout from %s to %s", url, filename)
+        os.system("svn checkout%s -q %s %s" % (creds, url, filename))
+        return filename
+
+    @staticmethod
+    def _vcs_split_rev_from_url(url, pop_prefix=False):
+        scheme, netloc, path, query, frag = urllib.parse.urlsplit(url)
+
+        scheme = scheme.split('+', 1)[-1]
+
+        # Some fragment identification fails
+        path = path.split('#', 1)[0]
+
+        rev = None
+        if '@' in path:
+            path, rev = path.rsplit('@', 1)
+
+        # Also, discard fragment
+        url = urllib.parse.urlunsplit((scheme, netloc, path, query, ''))
+
+        return url, rev
+
+    def _download_git(self, url, filename):
+        filename = filename.split('#', 1)[0]
+        url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True)
+
+        self.info("Doing git clone from %s to %s", url, filename)
+        os.system("git clone --quiet %s %s" % (url, filename))
+
+        if rev is not None:
+            self.info("Checking out %s", rev)
+            os.system("(cd %s && git checkout --quiet %s)" % (
+                filename,
+                rev,
+            ))
+
+        return filename
+
+    def _download_hg(self, url, filename):
+        filename = filename.split('#', 1)[0]
+        url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True)
+
+        self.info("Doing hg clone from %s to %s", url, filename)
+        os.system("hg clone --quiet %s %s" % (url, filename))
+
+        if rev is not None:
+            self.info("Updating to %s", rev)
+            os.system("(cd %s && hg up -C -r %s -q)" % (
+                filename,
+                rev,
+            ))
+
+        return filename
+
+    def debug(self, msg, *args):
+        log.debug(msg, *args)
+
+    def info(self, msg, *args):
+        log.info(msg, *args)
+
+    def warn(self, msg, *args):
+        log.warn(msg, *args)
+
+
+# This pattern matches a character entity reference (a decimal numeric
+# references, a hexadecimal numeric reference, or a named reference).
+entity_sub = re.compile(r'&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?').sub
+
+
+def decode_entity(match):
+    what = match.group(1)
+    return unescape(what)
+
+
+def htmldecode(text):
+    """Decode HTML entities in the given text."""
+    return entity_sub(decode_entity, text)
+
+
+def socket_timeout(timeout=15):
+    def _socket_timeout(func):
+        def _socket_timeout(*args, **kwargs):
+            old_timeout = socket.getdefaulttimeout()
+            socket.setdefaulttimeout(timeout)
+            try:
+                return func(*args, **kwargs)
+            finally:
+                socket.setdefaulttimeout(old_timeout)
+
+        return _socket_timeout
+
+    return _socket_timeout
+
+
+def _encode_auth(auth):
+    """
+    A function compatible with Python 2.3-3.3 that will encode
+    auth from a URL suitable for an HTTP header.
+    >>> str(_encode_auth('username%3Apassword'))
+    'dXNlcm5hbWU6cGFzc3dvcmQ='
+
+    Long auth strings should not cause a newline to be inserted.
+    >>> long_auth = 'username:' + 'password'*10
+    >>> chr(10) in str(_encode_auth(long_auth))
+    False
+    """
+    auth_s = urllib.parse.unquote(auth)
+    # convert to bytes
+    auth_bytes = auth_s.encode()
+    # use the legacy interface for Python 2.3 support
+    encoded_bytes = base64.encodestring(auth_bytes)
+    # convert back to a string
+    encoded = encoded_bytes.decode()
+    # strip the trailing carriage return
+    return encoded.replace('\n', '')
+
+
+class Credential(object):
+    """
+    A username/password pair. Use like a namedtuple.
+    """
+
+    def __init__(self, username, password):
+        self.username = username
+        self.password = password
+
+    def __iter__(self):
+        yield self.username
+        yield self.password
+
+    def __str__(self):
+        return '%(username)s:%(password)s' % vars(self)
+
+
+class PyPIConfig(configparser.RawConfigParser):
+    def __init__(self):
+        """
+        Load from ~/.pypirc
+        """
+        defaults = dict.fromkeys(['username', 'password', 'repository'], '')
+        configparser.RawConfigParser.__init__(self, defaults)
+
+        rc = os.path.join(os.path.expanduser('~'), '.pypirc')
+        if os.path.exists(rc):
+            self.read(rc)
+
+    @property
+    def creds_by_repository(self):
+        sections_with_repositories = [
+            section for section in self.sections()
+            if self.get(section, 'repository').strip()
+        ]
+
+        return dict(map(self._get_repo_cred, sections_with_repositories))
+
+    def _get_repo_cred(self, section):
+        repo = self.get(section, 'repository').strip()
+        return repo, Credential(
+            self.get(section, 'username').strip(),
+            self.get(section, 'password').strip(),
+        )
+
+    def find_credential(self, url):
+        """
+        If the URL indicated appears to be a repository defined in this
+        config, return the credential for that repository.
+        """
+        for repository, cred in self.creds_by_repository.items():
+            if url.startswith(repository):
+                return cred
+
+
+def open_with_auth(url, opener=urllib.request.urlopen):
+    """Open a urllib2 request, handling HTTP authentication"""
+
+    scheme, netloc, path, params, query, frag = urllib.parse.urlparse(url)
+
+    # Double scheme does not raise on Mac OS X as revealed by a
+    # failing test. We would expect "nonnumeric port". Refs #20.
+    if netloc.endswith(':'):
+        raise http_client.InvalidURL("nonnumeric port: ''")
+
+    if scheme in ('http', 'https'):
+        auth, host = urllib.parse.splituser(netloc)
+    else:
+        auth = None
+
+    if not auth:
+        cred = PyPIConfig().find_credential(url)
+        if cred:
+            auth = str(cred)
+            info = cred.username, url
+            log.info('Authenticating as %s for %s (from .pypirc)', *info)
+
+    if auth:
+        auth = "Basic " + _encode_auth(auth)
+        parts = scheme, host, path, params, query, frag
+        new_url = urllib.parse.urlunparse(parts)
+        request = urllib.request.Request(new_url)
+        request.add_header("Authorization", auth)
+    else:
+        request = urllib.request.Request(url)
+
+    request.add_header('User-Agent', user_agent)
+    fp = opener(request)
+
+    if auth:
+        # Put authentication info back into request URL if same host,
+        # so that links found on the page will work
+        s2, h2, path2, param2, query2, frag2 = urllib.parse.urlparse(fp.url)
+        if s2 == scheme and h2 == host:
+            parts = s2, netloc, path2, param2, query2, frag2
+            fp.url = urllib.parse.urlunparse(parts)
+
+    return fp
+
+
+# adding a timeout to avoid freezing package_index
+open_with_auth = socket_timeout(_SOCKET_TIMEOUT)(open_with_auth)
+
+
+def fix_sf_url(url):
+    return url  # backward compatibility
+
+
+def local_open(url):
+    """Read a local path, with special support for directories"""
+    scheme, server, path, param, query, frag = urllib.parse.urlparse(url)
+    filename = urllib.request.url2pathname(path)
+    if os.path.isfile(filename):
+        return urllib.request.urlopen(url)
+    elif path.endswith('/') and os.path.isdir(filename):
+        files = []
+        for f in os.listdir(filename):
+            filepath = os.path.join(filename, f)
+            if f == 'index.html':
+                with open(filepath, 'r') as fp:
+                    body = fp.read()
+                break
+            elif os.path.isdir(filepath):
+                f += '/'
+            files.append('<a href="{name}">{name}</a>'.format(name=f))
+        else:
+            tmpl = (
+                "<html><head><title>{url}</title>"
+                "</head><body>{files}</body></html>")
+            body = tmpl.format(url=url, files='\n'.join(files))
+        status, message = 200, "OK"
+    else:
+        status, message, body = 404, "Path not found", "Not found"
+
+    headers = {'content-type': 'text/html'}
+    body_stream = six.StringIO(body)
+    return urllib.error.HTTPError(url, status, message, headers, body_stream)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/pep425tags.py b/vendor/setuptools-39.0.1/build/lib/setuptools/pep425tags.py
new file mode 100644
index 00000000..dfe55d58
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/pep425tags.py
@@ -0,0 +1,316 @@
+# This file originally from pip:
+# https://github.com/pypa/pip/blob/8f4f15a5a95d7d5b511ceaee9ed261176c181970/src/pip/_internal/pep425tags.py
+"""Generate and work with PEP 425 Compatibility Tags."""
+from __future__ import absolute_import
+
+import distutils.util
+import platform
+import re
+import sys
+import sysconfig
+import warnings
+from collections import OrderedDict
+
+from . import glibc
+
+_osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)')
+
+
+def get_config_var(var):
+    try:
+        return sysconfig.get_config_var(var)
+    except IOError as e:  # Issue #1074
+        warnings.warn("{}".format(e), RuntimeWarning)
+        return None
+
+
+def get_abbr_impl():
+    """Return abbreviated implementation name."""
+    if hasattr(sys, 'pypy_version_info'):
+        pyimpl = 'pp'
+    elif sys.platform.startswith('java'):
+        pyimpl = 'jy'
+    elif sys.platform == 'cli':
+        pyimpl = 'ip'
+    else:
+        pyimpl = 'cp'
+    return pyimpl
+
+
+def get_impl_ver():
+    """Return implementation version."""
+    impl_ver = get_config_var("py_version_nodot")
+    if not impl_ver or get_abbr_impl() == 'pp':
+        impl_ver = ''.join(map(str, get_impl_version_info()))
+    return impl_ver
+
+
+def get_impl_version_info():
+    """Return sys.version_info-like tuple for use in decrementing the minor
+    version."""
+    if get_abbr_impl() == 'pp':
+        # as per https://github.com/pypa/pip/issues/2882
+        return (sys.version_info[0], sys.pypy_version_info.major,
+                sys.pypy_version_info.minor)
+    else:
+        return sys.version_info[0], sys.version_info[1]
+
+
+def get_impl_tag():
+    """
+    Returns the Tag for this specific implementation.
+    """
+    return "{}{}".format(get_abbr_impl(), get_impl_ver())
+
+
+def get_flag(var, fallback, expected=True, warn=True):
+    """Use a fallback method for determining SOABI flags if the needed config
+    var is unset or unavailable."""
+    val = get_config_var(var)
+    if val is None:
+        if warn:
+            warnings.warn("Config variable '{0}' is unset, Python ABI tag may "
+                          "be incorrect".format(var), RuntimeWarning, 2)
+        return fallback()
+    return val == expected
+
+
+def get_abi_tag():
+    """Return the ABI tag based on SOABI (if available) or emulate SOABI
+    (CPython 2, PyPy)."""
+    soabi = get_config_var('SOABI')
+    impl = get_abbr_impl()
+    if not soabi and impl in {'cp', 'pp'} and hasattr(sys, 'maxunicode'):
+        d = ''
+        m = ''
+        u = ''
+        if get_flag('Py_DEBUG',
+                    lambda: hasattr(sys, 'gettotalrefcount'),
+                    warn=(impl == 'cp')):
+            d = 'd'
+        if get_flag('WITH_PYMALLOC',
+                    lambda: impl == 'cp',
+                    warn=(impl == 'cp')):
+            m = 'm'
+        if get_flag('Py_UNICODE_SIZE',
+                    lambda: sys.maxunicode == 0x10ffff,
+                    expected=4,
+                    warn=(impl == 'cp' and
+                          sys.version_info < (3, 3))) \
+                and sys.version_info < (3, 3):
+            u = 'u'
+        abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u)
+    elif soabi and soabi.startswith('cpython-'):
+        abi = 'cp' + soabi.split('-')[1]
+    elif soabi:
+        abi = soabi.replace('.', '_').replace('-', '_')
+    else:
+        abi = None
+    return abi
+
+
+def _is_running_32bit():
+    return sys.maxsize == 2147483647
+
+
+def get_platform():
+    """Return our platform name 'win32', 'linux_x86_64'"""
+    if sys.platform == 'darwin':
+        # distutils.util.get_platform() returns the release based on the value
+        # of MACOSX_DEPLOYMENT_TARGET on which Python was built, which may
+        # be significantly older than the user's current machine.
+        release, _, machine = platform.mac_ver()
+        split_ver = release.split('.')
+
+        if machine == "x86_64" and _is_running_32bit():
+            machine = "i386"
+        elif machine == "ppc64" and _is_running_32bit():
+            machine = "ppc"
+
+        return 'macosx_{}_{}_{}'.format(split_ver[0], split_ver[1], machine)
+
+    # XXX remove distutils dependency
+    result = distutils.util.get_platform().replace('.', '_').replace('-', '_')
+    if result == "linux_x86_64" and _is_running_32bit():
+        # 32 bit Python program (running on a 64 bit Linux): pip should only
+        # install and run 32 bit compiled extensions in that case.
+        result = "linux_i686"
+
+    return result
+
+
+def is_manylinux1_compatible():
+    # Only Linux, and only x86-64 / i686
+    if get_platform() not in {"linux_x86_64", "linux_i686"}:
+        return False
+
+    # Check for presence of _manylinux module
+    try:
+        import _manylinux
+        return bool(_manylinux.manylinux1_compatible)
+    except (ImportError, AttributeError):
+        # Fall through to heuristic check below
+        pass
+
+    # Check glibc version. CentOS 5 uses glibc 2.5.
+    return glibc.have_compatible_glibc(2, 5)
+
+
+def get_darwin_arches(major, minor, machine):
+    """Return a list of supported arches (including group arches) for
+    the given major, minor and machine architecture of an macOS machine.
+    """
+    arches = []
+
+    def _supports_arch(major, minor, arch):
+        # Looking at the application support for macOS versions in the chart
+        # provided by https://en.wikipedia.org/wiki/OS_X#Versions it appears
+        # our timeline looks roughly like:
+        #
+        # 10.0 - Introduces ppc support.
+        # 10.4 - Introduces ppc64, i386, and x86_64 support, however the ppc64
+        #        and x86_64 support is CLI only, and cannot be used for GUI
+        #        applications.
+        # 10.5 - Extends ppc64 and x86_64 support to cover GUI applications.
+        # 10.6 - Drops support for ppc64
+        # 10.7 - Drops support for ppc
+        #
+        # Given that we do not know if we're installing a CLI or a GUI
+        # application, we must be conservative and assume it might be a GUI
+        # application and behave as if ppc64 and x86_64 support did not occur
+        # until 10.5.
+        #
+        # Note: The above information is taken from the "Application support"
+        #       column in the chart not the "Processor support" since I believe
+        #       that we care about what instruction sets an application can use
+        #       not which processors the OS supports.
+        if arch == 'ppc':
+            return (major, minor) <= (10, 5)
+        if arch == 'ppc64':
+            return (major, minor) == (10, 5)
+        if arch == 'i386':
+            return (major, minor) >= (10, 4)
+        if arch == 'x86_64':
+            return (major, minor) >= (10, 5)
+        if arch in groups:
+            for garch in groups[arch]:
+                if _supports_arch(major, minor, garch):
+                    return True
+        return False
+
+    groups = OrderedDict([
+        ("fat", ("i386", "ppc")),
+        ("intel", ("x86_64", "i386")),
+        ("fat64", ("x86_64", "ppc64")),
+        ("fat32", ("x86_64", "i386", "ppc")),
+    ])
+
+    if _supports_arch(major, minor, machine):
+        arches.append(machine)
+
+    for garch in groups:
+        if machine in groups[garch] and _supports_arch(major, minor, garch):
+            arches.append(garch)
+
+    arches.append('universal')
+
+    return arches
+
+
+def get_supported(versions=None, noarch=False, platform=None,
+                  impl=None, abi=None):
+    """Return a list of supported tags for each version specified in
+    `versions`.
+
+    :param versions: a list of string versions, of the form ["33", "32"],
+        or None. The first version will be assumed to support our ABI.
+    :param platform: specify the exact platform you want valid
+        tags for, or None. If None, use the local system platform.
+    :param impl: specify the exact implementation you want valid
+        tags for, or None. If None, use the local interpreter impl.
+    :param abi: specify the exact abi you want valid
+        tags for, or None. If None, use the local interpreter abi.
+    """
+    supported = []
+
+    # Versions must be given with respect to the preference
+    if versions is None:
+        versions = []
+        version_info = get_impl_version_info()
+        major = version_info[:-1]
+        # Support all previous minor Python versions.
+        for minor in range(version_info[-1], -1, -1):
+            versions.append(''.join(map(str, major + (minor,))))
+
+    impl = impl or get_abbr_impl()
+
+    abis = []
+
+    abi = abi or get_abi_tag()
+    if abi:
+        abis[0:0] = [abi]
+
+    abi3s = set()
+    import imp
+    for suffix in imp.get_suffixes():
+        if suffix[0].startswith('.abi'):
+            abi3s.add(suffix[0].split('.', 2)[1])
+
+    abis.extend(sorted(list(abi3s)))
+
+    abis.append('none')
+
+    if not noarch:
+        arch = platform or get_platform()
+        if arch.startswith('macosx'):
+            # support macosx-10.6-intel on macosx-10.9-x86_64
+            match = _osx_arch_pat.match(arch)
+            if match:
+                name, major, minor, actual_arch = match.groups()
+                tpl = '{}_{}_%i_%s'.format(name, major)
+                arches = []
+                for m in reversed(range(int(minor) + 1)):
+                    for a in get_darwin_arches(int(major), m, actual_arch):
+                        arches.append(tpl % (m, a))
+            else:
+                # arch pattern didn't match (?!)
+                arches = [arch]
+        elif platform is None and is_manylinux1_compatible():
+            arches = [arch.replace('linux', 'manylinux1'), arch]
+        else:
+            arches = [arch]
+
+        # Current version, current API (built specifically for our Python):
+        for abi in abis:
+            for arch in arches:
+                supported.append(('%s%s' % (impl, versions[0]), abi, arch))
+
+        # abi3 modules compatible with older version of Python
+        for version in versions[1:]:
+            # abi3 was introduced in Python 3.2
+            if version in {'31', '30'}:
+                break
+            for abi in abi3s:   # empty set if not Python 3
+                for arch in arches:
+                    supported.append(("%s%s" % (impl, version), abi, arch))
+
+        # Has binaries, does not use the Python API:
+        for arch in arches:
+            supported.append(('py%s' % (versions[0][0]), 'none', arch))
+
+    # No abi / arch, but requires our implementation:
+    supported.append(('%s%s' % (impl, versions[0]), 'none', 'any'))
+    # Tagged specifically as being cross-version compatible
+    # (with just the major version specified)
+    supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any'))
+
+    # No abi / arch, generic Python
+    for i, version in enumerate(versions):
+        supported.append(('py%s' % (version,), 'none', 'any'))
+        if i == 0:
+            supported.append(('py%s' % (version[0]), 'none', 'any'))
+
+    return supported
+
+
+implementation_tag = get_impl_tag()
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/py27compat.py b/vendor/setuptools-39.0.1/build/lib/setuptools/py27compat.py
new file mode 100644
index 00000000..2985011b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/py27compat.py
@@ -0,0 +1,28 @@
+"""
+Compatibility Support for Python 2.7 and earlier
+"""
+
+import platform
+
+from setuptools.extern import six
+
+
+def get_all_headers(message, key):
+    """
+    Given an HTTPMessage, return all headers matching a given key.
+    """
+    return message.get_all(key)
+
+
+if six.PY2:
+    def get_all_headers(message, key):
+        return message.getheaders(key)
+
+
+linux_py2_ascii = (
+    platform.system() == 'Linux' and
+    six.PY2
+)
+
+rmtree_safe = str if linux_py2_ascii else lambda x: x
+"""Workaround for http://bugs.python.org/issue24672"""
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/py31compat.py b/vendor/setuptools-39.0.1/build/lib/setuptools/py31compat.py
new file mode 100644
index 00000000..4ea95320
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/py31compat.py
@@ -0,0 +1,41 @@
+__all__ = ['get_config_vars', 'get_path']
+
+try:
+    # Python 2.7 or >=3.2
+    from sysconfig import get_config_vars, get_path
+except ImportError:
+    from distutils.sysconfig import get_config_vars, get_python_lib
+
+    def get_path(name):
+        if name not in ('platlib', 'purelib'):
+            raise ValueError("Name must be purelib or platlib")
+        return get_python_lib(name == 'platlib')
+
+
+try:
+    # Python >=3.2
+    from tempfile import TemporaryDirectory
+except ImportError:
+    import shutil
+    import tempfile
+
+    class TemporaryDirectory(object):
+        """
+        Very simple temporary directory context manager.
+        Will try to delete afterward, but will also ignore OS and similar
+        errors on deletion.
+        """
+
+        def __init__(self):
+            self.name = None  # Handle mkdtemp raising an exception
+            self.name = tempfile.mkdtemp()
+
+        def __enter__(self):
+            return self.name
+
+        def __exit__(self, exctype, excvalue, exctrace):
+            try:
+                shutil.rmtree(self.name, True)
+            except OSError:  # removal errors are not the only possible
+                pass
+            self.name = None
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/py33compat.py b/vendor/setuptools-39.0.1/build/lib/setuptools/py33compat.py
new file mode 100644
index 00000000..2a73ebb3
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/py33compat.py
@@ -0,0 +1,54 @@
+import dis
+import array
+import collections
+
+try:
+    import html
+except ImportError:
+    html = None
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import html_parser
+
+
+OpArg = collections.namedtuple('OpArg', 'opcode arg')
+
+
+class Bytecode_compat(object):
+    def __init__(self, code):
+        self.code = code
+
+    def __iter__(self):
+        """Yield '(op,arg)' pair for each operation in code object 'code'"""
+
+        bytes = array.array('b', self.code.co_code)
+        eof = len(self.code.co_code)
+
+        ptr = 0
+        extended_arg = 0
+
+        while ptr < eof:
+
+            op = bytes[ptr]
+
+            if op >= dis.HAVE_ARGUMENT:
+
+                arg = bytes[ptr + 1] + bytes[ptr + 2] * 256 + extended_arg
+                ptr += 3
+
+                if op == dis.EXTENDED_ARG:
+                    long_type = six.integer_types[-1]
+                    extended_arg = arg * long_type(65536)
+                    continue
+
+            else:
+                arg = None
+                ptr += 1
+
+            yield OpArg(op, arg)
+
+
+Bytecode = getattr(dis, 'Bytecode', Bytecode_compat)
+
+
+unescape = getattr(html, 'unescape', html_parser.HTMLParser().unescape)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/py36compat.py b/vendor/setuptools-39.0.1/build/lib/setuptools/py36compat.py
new file mode 100644
index 00000000..f5279696
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/py36compat.py
@@ -0,0 +1,82 @@
+import sys
+from distutils.errors import DistutilsOptionError
+from distutils.util import strtobool
+from distutils.debug import DEBUG
+
+
+class Distribution_parse_config_files:
+    """
+    Mix-in providing forward-compatibility for functionality to be
+    included by default on Python 3.7.
+
+    Do not edit the code in this class except to update functionality
+    as implemented in distutils.
+    """
+    def parse_config_files(self, filenames=None):
+        from configparser import ConfigParser
+
+        # Ignore install directory options if we have a venv
+        if sys.prefix != sys.base_prefix:
+            ignore_options = [
+                'install-base', 'install-platbase', 'install-lib',
+                'install-platlib', 'install-purelib', 'install-headers',
+                'install-scripts', 'install-data', 'prefix', 'exec-prefix',
+                'home', 'user', 'root']
+        else:
+            ignore_options = []
+
+        ignore_options = frozenset(ignore_options)
+
+        if filenames is None:
+            filenames = self.find_config_files()
+
+        if DEBUG:
+            self.announce("Distribution.parse_config_files():")
+
+        parser = ConfigParser(interpolation=None)
+        for filename in filenames:
+            if DEBUG:
+                self.announce("  reading %s" % filename)
+            parser.read(filename)
+            for section in parser.sections():
+                options = parser.options(section)
+                opt_dict = self.get_option_dict(section)
+
+                for opt in options:
+                    if opt != '__name__' and opt not in ignore_options:
+                        val = parser.get(section,opt)
+                        opt = opt.replace('-', '_')
+                        opt_dict[opt] = (filename, val)
+
+            # Make the ConfigParser forget everything (so we retain
+            # the original filenames that options come from)
+            parser.__init__()
+
+        # If there was a "global" section in the config file, use it
+        # to set Distribution options.
+
+        if 'global' in self.command_options:
+            for (opt, (src, val)) in self.command_options['global'].items():
+                alias = self.negative_opt.get(opt)
+                try:
+                    if alias:
+                        setattr(self, alias, not strtobool(val))
+                    elif opt in ('verbose', 'dry_run'): # ugh!
+                        setattr(self, opt, strtobool(val))
+                    else:
+                        setattr(self, opt, val)
+                except ValueError as msg:
+                    raise DistutilsOptionError(msg)
+
+
+if sys.version_info < (3,):
+    # Python 2 behavior is sufficient
+    class Distribution_parse_config_files:
+        pass
+
+
+if False:
+    # When updated behavior is available upstream,
+    # disable override here.
+    class Distribution_parse_config_files:
+        pass
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/sandbox.py b/vendor/setuptools-39.0.1/build/lib/setuptools/sandbox.py
new file mode 100644
index 00000000..685f3f72
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/sandbox.py
@@ -0,0 +1,491 @@
+import os
+import sys
+import tempfile
+import operator
+import functools
+import itertools
+import re
+import contextlib
+import pickle
+import textwrap
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import builtins, map
+
+import pkg_resources.py31compat
+
+if sys.platform.startswith('java'):
+    import org.python.modules.posix.PosixModule as _os
+else:
+    _os = sys.modules[os.name]
+try:
+    _file = file
+except NameError:
+    _file = None
+_open = open
+from distutils.errors import DistutilsError
+from pkg_resources import working_set
+
+
+__all__ = [
+    "AbstractSandbox", "DirectorySandbox", "SandboxViolation", "run_setup",
+]
+
+
+def _execfile(filename, globals, locals=None):
+    """
+    Python 3 implementation of execfile.
+    """
+    mode = 'rb'
+    with open(filename, mode) as stream:
+        script = stream.read()
+    if locals is None:
+        locals = globals
+    code = compile(script, filename, 'exec')
+    exec(code, globals, locals)
+
+
+@contextlib.contextmanager
+def save_argv(repl=None):
+    saved = sys.argv[:]
+    if repl is not None:
+        sys.argv[:] = repl
+    try:
+        yield saved
+    finally:
+        sys.argv[:] = saved
+
+
+@contextlib.contextmanager
+def save_path():
+    saved = sys.path[:]
+    try:
+        yield saved
+    finally:
+        sys.path[:] = saved
+
+
+@contextlib.contextmanager
+def override_temp(replacement):
+    """
+    Monkey-patch tempfile.tempdir with replacement, ensuring it exists
+    """
+    pkg_resources.py31compat.makedirs(replacement, exist_ok=True)
+
+    saved = tempfile.tempdir
+
+    tempfile.tempdir = replacement
+
+    try:
+        yield
+    finally:
+        tempfile.tempdir = saved
+
+
+@contextlib.contextmanager
+def pushd(target):
+    saved = os.getcwd()
+    os.chdir(target)
+    try:
+        yield saved
+    finally:
+        os.chdir(saved)
+
+
+class UnpickleableException(Exception):
+    """
+    An exception representing another Exception that could not be pickled.
+    """
+
+    @staticmethod
+    def dump(type, exc):
+        """
+        Always return a dumped (pickled) type and exc. If exc can't be pickled,
+        wrap it in UnpickleableException first.
+        """
+        try:
+            return pickle.dumps(type), pickle.dumps(exc)
+        except Exception:
+            # get UnpickleableException inside the sandbox
+            from setuptools.sandbox import UnpickleableException as cls
+            return cls.dump(cls, cls(repr(exc)))
+
+
+class ExceptionSaver:
+    """
+    A Context Manager that will save an exception, serialized, and restore it
+    later.
+    """
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, exc, tb):
+        if not exc:
+            return
+
+        # dump the exception
+        self._saved = UnpickleableException.dump(type, exc)
+        self._tb = tb
+
+        # suppress the exception
+        return True
+
+    def resume(self):
+        "restore and re-raise any exception"
+
+        if '_saved' not in vars(self):
+            return
+
+        type, exc = map(pickle.loads, self._saved)
+        six.reraise(type, exc, self._tb)
+
+
+@contextlib.contextmanager
+def save_modules():
+    """
+    Context in which imported modules are saved.
+
+    Translates exceptions internal to the context into the equivalent exception
+    outside the context.
+    """
+    saved = sys.modules.copy()
+    with ExceptionSaver() as saved_exc:
+        yield saved
+
+    sys.modules.update(saved)
+    # remove any modules imported since
+    del_modules = (
+        mod_name for mod_name in sys.modules
+        if mod_name not in saved
+        # exclude any encodings modules. See #285
+        and not mod_name.startswith('encodings.')
+    )
+    _clear_modules(del_modules)
+
+    saved_exc.resume()
+
+
+def _clear_modules(module_names):
+    for mod_name in list(module_names):
+        del sys.modules[mod_name]
+
+
+@contextlib.contextmanager
+def save_pkg_resources_state():
+    saved = pkg_resources.__getstate__()
+    try:
+        yield saved
+    finally:
+        pkg_resources.__setstate__(saved)
+
+
+@contextlib.contextmanager
+def setup_context(setup_dir):
+    temp_dir = os.path.join(setup_dir, 'temp')
+    with save_pkg_resources_state():
+        with save_modules():
+            hide_setuptools()
+            with save_path():
+                with save_argv():
+                    with override_temp(temp_dir):
+                        with pushd(setup_dir):
+                            # ensure setuptools commands are available
+                            __import__('setuptools')
+                            yield
+
+
+def _needs_hiding(mod_name):
+    """
+    >>> _needs_hiding('setuptools')
+    True
+    >>> _needs_hiding('pkg_resources')
+    True
+    >>> _needs_hiding('setuptools_plugin')
+    False
+    >>> _needs_hiding('setuptools.__init__')
+    True
+    >>> _needs_hiding('distutils')
+    True
+    >>> _needs_hiding('os')
+    False
+    >>> _needs_hiding('Cython')
+    True
+    """
+    pattern = re.compile(r'(setuptools|pkg_resources|distutils|Cython)(\.|$)')
+    return bool(pattern.match(mod_name))
+
+
+def hide_setuptools():
+    """
+    Remove references to setuptools' modules from sys.modules to allow the
+    invocation to import the most appropriate setuptools. This technique is
+    necessary to avoid issues such as #315 where setuptools upgrading itself
+    would fail to find a function declared in the metadata.
+    """
+    modules = filter(_needs_hiding, sys.modules)
+    _clear_modules(modules)
+
+
+def run_setup(setup_script, args):
+    """Run a distutils setup script, sandboxed in its directory"""
+    setup_dir = os.path.abspath(os.path.dirname(setup_script))
+    with setup_context(setup_dir):
+        try:
+            sys.argv[:] = [setup_script] + list(args)
+            sys.path.insert(0, setup_dir)
+            # reset to include setup dir, w/clean callback list
+            working_set.__init__()
+            working_set.callbacks.append(lambda dist: dist.activate())
+
+            # __file__ should be a byte string on Python 2 (#712)
+            dunder_file = (
+                setup_script
+                if isinstance(setup_script, str) else
+                setup_script.encode(sys.getfilesystemencoding())
+            )
+
+            with DirectorySandbox(setup_dir):
+                ns = dict(__file__=dunder_file, __name__='__main__')
+                _execfile(setup_script, ns)
+        except SystemExit as v:
+            if v.args and v.args[0]:
+                raise
+            # Normal exit, just return
+
+
+class AbstractSandbox:
+    """Wrap 'os' module and 'open()' builtin for virtualizing setup scripts"""
+
+    _active = False
+
+    def __init__(self):
+        self._attrs = [
+            name for name in dir(_os)
+            if not name.startswith('_') and hasattr(self, name)
+        ]
+
+    def _copy(self, source):
+        for name in self._attrs:
+            setattr(os, name, getattr(source, name))
+
+    def __enter__(self):
+        self._copy(self)
+        if _file:
+            builtins.file = self._file
+        builtins.open = self._open
+        self._active = True
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        self._active = False
+        if _file:
+            builtins.file = _file
+        builtins.open = _open
+        self._copy(_os)
+
+    def run(self, func):
+        """Run 'func' under os sandboxing"""
+        with self:
+            return func()
+
+    def _mk_dual_path_wrapper(name):
+        original = getattr(_os, name)
+
+        def wrap(self, src, dst, *args, **kw):
+            if self._active:
+                src, dst = self._remap_pair(name, src, dst, *args, **kw)
+            return original(src, dst, *args, **kw)
+
+        return wrap
+
+    for name in ["rename", "link", "symlink"]:
+        if hasattr(_os, name):
+            locals()[name] = _mk_dual_path_wrapper(name)
+
+    def _mk_single_path_wrapper(name, original=None):
+        original = original or getattr(_os, name)
+
+        def wrap(self, path, *args, **kw):
+            if self._active:
+                path = self._remap_input(name, path, *args, **kw)
+            return original(path, *args, **kw)
+
+        return wrap
+
+    if _file:
+        _file = _mk_single_path_wrapper('file', _file)
+    _open = _mk_single_path_wrapper('open', _open)
+    for name in [
+        "stat", "listdir", "chdir", "open", "chmod", "chown", "mkdir",
+        "remove", "unlink", "rmdir", "utime", "lchown", "chroot", "lstat",
+        "startfile", "mkfifo", "mknod", "pathconf", "access"
+    ]:
+        if hasattr(_os, name):
+            locals()[name] = _mk_single_path_wrapper(name)
+
+    def _mk_single_with_return(name):
+        original = getattr(_os, name)
+
+        def wrap(self, path, *args, **kw):
+            if self._active:
+                path = self._remap_input(name, path, *args, **kw)
+                return self._remap_output(name, original(path, *args, **kw))
+            return original(path, *args, **kw)
+
+        return wrap
+
+    for name in ['readlink', 'tempnam']:
+        if hasattr(_os, name):
+            locals()[name] = _mk_single_with_return(name)
+
+    def _mk_query(name):
+        original = getattr(_os, name)
+
+        def wrap(self, *args, **kw):
+            retval = original(*args, **kw)
+            if self._active:
+                return self._remap_output(name, retval)
+            return retval
+
+        return wrap
+
+    for name in ['getcwd', 'tmpnam']:
+        if hasattr(_os, name):
+            locals()[name] = _mk_query(name)
+
+    def _validate_path(self, path):
+        """Called to remap or validate any path, whether input or output"""
+        return path
+
+    def _remap_input(self, operation, path, *args, **kw):
+        """Called for path inputs"""
+        return self._validate_path(path)
+
+    def _remap_output(self, operation, path):
+        """Called for path outputs"""
+        return self._validate_path(path)
+
+    def _remap_pair(self, operation, src, dst, *args, **kw):
+        """Called for path pairs like rename, link, and symlink operations"""
+        return (
+            self._remap_input(operation + '-from', src, *args, **kw),
+            self._remap_input(operation + '-to', dst, *args, **kw)
+        )
+
+
+if hasattr(os, 'devnull'):
+    _EXCEPTIONS = [os.devnull,]
+else:
+    _EXCEPTIONS = []
+
+
+class DirectorySandbox(AbstractSandbox):
+    """Restrict operations to a single subdirectory - pseudo-chroot"""
+
+    write_ops = dict.fromkeys([
+        "open", "chmod", "chown", "mkdir", "remove", "unlink", "rmdir",
+        "utime", "lchown", "chroot", "mkfifo", "mknod", "tempnam",
+    ])
+
+    _exception_patterns = [
+        # Allow lib2to3 to attempt to save a pickled grammar object (#121)
+        r'.*lib2to3.*\.pickle$',
+    ]
+    "exempt writing to paths that match the pattern"
+
+    def __init__(self, sandbox, exceptions=_EXCEPTIONS):
+        self._sandbox = os.path.normcase(os.path.realpath(sandbox))
+        self._prefix = os.path.join(self._sandbox, '')
+        self._exceptions = [
+            os.path.normcase(os.path.realpath(path))
+            for path in exceptions
+        ]
+        AbstractSandbox.__init__(self)
+
+    def _violation(self, operation, *args, **kw):
+        from setuptools.sandbox import SandboxViolation
+        raise SandboxViolation(operation, args, kw)
+
+    if _file:
+
+        def _file(self, path, mode='r', *args, **kw):
+            if mode not in ('r', 'rt', 'rb', 'rU', 'U') and not self._ok(path):
+                self._violation("file", path, mode, *args, **kw)
+            return _file(path, mode, *args, **kw)
+
+    def _open(self, path, mode='r', *args, **kw):
+        if mode not in ('r', 'rt', 'rb', 'rU', 'U') and not self._ok(path):
+            self._violation("open", path, mode, *args, **kw)
+        return _open(path, mode, *args, **kw)
+
+    def tmpnam(self):
+        self._violation("tmpnam")
+
+    def _ok(self, path):
+        active = self._active
+        try:
+            self._active = False
+            realpath = os.path.normcase(os.path.realpath(path))
+            return (
+                self._exempted(realpath)
+                or realpath == self._sandbox
+                or realpath.startswith(self._prefix)
+            )
+        finally:
+            self._active = active
+
+    def _exempted(self, filepath):
+        start_matches = (
+            filepath.startswith(exception)
+            for exception in self._exceptions
+        )
+        pattern_matches = (
+            re.match(pattern, filepath)
+            for pattern in self._exception_patterns
+        )
+        candidates = itertools.chain(start_matches, pattern_matches)
+        return any(candidates)
+
+    def _remap_input(self, operation, path, *args, **kw):
+        """Called for path inputs"""
+        if operation in self.write_ops and not self._ok(path):
+            self._violation(operation, os.path.realpath(path), *args, **kw)
+        return path
+
+    def _remap_pair(self, operation, src, dst, *args, **kw):
+        """Called for path pairs like rename, link, and symlink operations"""
+        if not self._ok(src) or not self._ok(dst):
+            self._violation(operation, src, dst, *args, **kw)
+        return (src, dst)
+
+    def open(self, file, flags, mode=0o777, *args, **kw):
+        """Called for low-level os.open()"""
+        if flags & WRITE_FLAGS and not self._ok(file):
+            self._violation("os.open", file, flags, mode, *args, **kw)
+        return _os.open(file, flags, mode, *args, **kw)
+
+
+WRITE_FLAGS = functools.reduce(
+    operator.or_, [getattr(_os, a, 0) for a in
+        "O_WRONLY O_RDWR O_APPEND O_CREAT O_TRUNC O_TEMPORARY".split()]
+)
+
+
+class SandboxViolation(DistutilsError):
+    """A setup script attempted to modify the filesystem outside the sandbox"""
+
+    tmpl = textwrap.dedent("""
+        SandboxViolation: {cmd}{args!r} {kwargs}
+
+        The package setup script has attempted to modify files on your system
+        that are not within the EasyInstall build area, and has been aborted.
+
+        This package cannot be safely installed by EasyInstall, and may not
+        support alternate installation locations even if you run its setup
+        script by hand.  Please inform the package's author and the EasyInstall
+        maintainers to find out if a fix or workaround is available.
+        """).lstrip()
+
+    def __str__(self):
+        cmd, args, kwargs = self.args
+        return self.tmpl.format(**locals())
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/script (dev).tmpl b/vendor/setuptools-39.0.1/build/lib/setuptools/script (dev).tmpl
new file mode 100644
index 00000000..d58b1bb5
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/script (dev).tmpl	
@@ -0,0 +1,5 @@
+# EASY-INSTALL-DEV-SCRIPT: %(spec)r,%(script_name)r
+__requires__ = %(spec)r
+__import__('pkg_resources').require(%(spec)r)
+__file__ = %(dev_path)r
+exec(compile(open(__file__).read(), __file__, 'exec'))
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/script.tmpl b/vendor/setuptools-39.0.1/build/lib/setuptools/script.tmpl
new file mode 100644
index 00000000..ff5efbca
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/script.tmpl
@@ -0,0 +1,3 @@
+# EASY-INSTALL-SCRIPT: %(spec)r,%(script_name)r
+__requires__ = %(spec)r
+__import__('pkg_resources').run_script(%(spec)r, %(script_name)r)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/site-patch.py b/vendor/setuptools-39.0.1/build/lib/setuptools/site-patch.py
new file mode 100644
index 00000000..0d2d2ff8
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/site-patch.py
@@ -0,0 +1,74 @@
+def __boot():
+    import sys
+    import os
+    PYTHONPATH = os.environ.get('PYTHONPATH')
+    if PYTHONPATH is None or (sys.platform == 'win32' and not PYTHONPATH):
+        PYTHONPATH = []
+    else:
+        PYTHONPATH = PYTHONPATH.split(os.pathsep)
+
+    pic = getattr(sys, 'path_importer_cache', {})
+    stdpath = sys.path[len(PYTHONPATH):]
+    mydir = os.path.dirname(__file__)
+
+    for item in stdpath:
+        if item == mydir or not item:
+            continue  # skip if current dir. on Windows, or my own directory
+        importer = pic.get(item)
+        if importer is not None:
+            loader = importer.find_module('site')
+            if loader is not None:
+                # This should actually reload the current module
+                loader.load_module('site')
+                break
+        else:
+            try:
+                import imp  # Avoid import loop in Python >= 3.3
+                stream, path, descr = imp.find_module('site', [item])
+            except ImportError:
+                continue
+            if stream is None:
+                continue
+            try:
+                # This should actually reload the current module
+                imp.load_module('site', stream, path, descr)
+            finally:
+                stream.close()
+            break
+    else:
+        raise ImportError("Couldn't find the real 'site' module")
+
+    known_paths = dict([(makepath(item)[1], 1) for item in sys.path])  # 2.2 comp
+
+    oldpos = getattr(sys, '__egginsert', 0)  # save old insertion position
+    sys.__egginsert = 0  # and reset the current one
+
+    for item in PYTHONPATH:
+        addsitedir(item)
+
+    sys.__egginsert += oldpos  # restore effective old position
+
+    d, nd = makepath(stdpath[0])
+    insert_at = None
+    new_path = []
+
+    for item in sys.path:
+        p, np = makepath(item)
+
+        if np == nd and insert_at is None:
+            # We've hit the first 'system' path entry, so added entries go here
+            insert_at = len(new_path)
+
+        if np in known_paths or insert_at is None:
+            new_path.append(item)
+        else:
+            # new path after the insert point, back-insert it
+            new_path.insert(insert_at, item)
+            insert_at += 1
+
+    sys.path[:] = new_path
+
+
+if __name__ == 'site':
+    __boot()
+    del __boot
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/ssl_support.py b/vendor/setuptools-39.0.1/build/lib/setuptools/ssl_support.py
new file mode 100644
index 00000000..6362f1f4
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/ssl_support.py
@@ -0,0 +1,260 @@
+import os
+import socket
+import atexit
+import re
+import functools
+
+from setuptools.extern.six.moves import urllib, http_client, map, filter
+
+from pkg_resources import ResolutionError, ExtractionError
+
+try:
+    import ssl
+except ImportError:
+    ssl = None
+
+__all__ = [
+    'VerifyingHTTPSHandler', 'find_ca_bundle', 'is_available', 'cert_paths',
+    'opener_for'
+]
+
+cert_paths = """
+/etc/pki/tls/certs/ca-bundle.crt
+/etc/ssl/certs/ca-certificates.crt
+/usr/share/ssl/certs/ca-bundle.crt
+/usr/local/share/certs/ca-root.crt
+/etc/ssl/cert.pem
+/System/Library/OpenSSL/certs/cert.pem
+/usr/local/share/certs/ca-root-nss.crt
+/etc/ssl/ca-bundle.pem
+""".strip().split()
+
+try:
+    HTTPSHandler = urllib.request.HTTPSHandler
+    HTTPSConnection = http_client.HTTPSConnection
+except AttributeError:
+    HTTPSHandler = HTTPSConnection = object
+
+is_available = ssl is not None and object not in (HTTPSHandler, HTTPSConnection)
+
+
+try:
+    from ssl import CertificateError, match_hostname
+except ImportError:
+    try:
+        from backports.ssl_match_hostname import CertificateError
+        from backports.ssl_match_hostname import match_hostname
+    except ImportError:
+        CertificateError = None
+        match_hostname = None
+
+if not CertificateError:
+
+    class CertificateError(ValueError):
+        pass
+
+
+if not match_hostname:
+
+    def _dnsname_match(dn, hostname, max_wildcards=1):
+        """Matching according to RFC 6125, section 6.4.3
+
+        http://tools.ietf.org/html/rfc6125#section-6.4.3
+        """
+        pats = []
+        if not dn:
+            return False
+
+        # Ported from python3-syntax:
+        # leftmost, *remainder = dn.split(r'.')
+        parts = dn.split(r'.')
+        leftmost = parts[0]
+        remainder = parts[1:]
+
+        wildcards = leftmost.count('*')
+        if wildcards > max_wildcards:
+            # Issue #17980: avoid denials of service by refusing more
+            # than one wildcard per fragment.  A survey of established
+            # policy among SSL implementations showed it to be a
+            # reasonable choice.
+            raise CertificateError(
+                "too many wildcards in certificate DNS name: " + repr(dn))
+
+        # speed up common case w/o wildcards
+        if not wildcards:
+            return dn.lower() == hostname.lower()
+
+        # RFC 6125, section 6.4.3, subitem 1.
+        # The client SHOULD NOT attempt to match a presented identifier in which
+        # the wildcard character comprises a label other than the left-most label.
+        if leftmost == '*':
+            # When '*' is a fragment by itself, it matches a non-empty dotless
+            # fragment.
+            pats.append('[^.]+')
+        elif leftmost.startswith('xn--') or hostname.startswith('xn--'):
+            # RFC 6125, section 6.4.3, subitem 3.
+            # The client SHOULD NOT attempt to match a presented identifier
+            # where the wildcard character is embedded within an A-label or
+            # U-label of an internationalized domain name.
+            pats.append(re.escape(leftmost))
+        else:
+            # Otherwise, '*' matches any dotless string, e.g. www*
+            pats.append(re.escape(leftmost).replace(r'\*', '[^.]*'))
+
+        # add the remaining fragments, ignore any wildcards
+        for frag in remainder:
+            pats.append(re.escape(frag))
+
+        pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
+        return pat.match(hostname)
+
+    def match_hostname(cert, hostname):
+        """Verify that *cert* (in decoded format as returned by
+        SSLSocket.getpeercert()) matches the *hostname*.  RFC 2818 and RFC 6125
+        rules are followed, but IP addresses are not accepted for *hostname*.
+
+        CertificateError is raised on failure. On success, the function
+        returns nothing.
+        """
+        if not cert:
+            raise ValueError("empty or no certificate")
+        dnsnames = []
+        san = cert.get('subjectAltName', ())
+        for key, value in san:
+            if key == 'DNS':
+                if _dnsname_match(value, hostname):
+                    return
+                dnsnames.append(value)
+        if not dnsnames:
+            # The subject is only checked when there is no dNSName entry
+            # in subjectAltName
+            for sub in cert.get('subject', ()):
+                for key, value in sub:
+                    # XXX according to RFC 2818, the most specific Common Name
+                    # must be used.
+                    if key == 'commonName':
+                        if _dnsname_match(value, hostname):
+                            return
+                        dnsnames.append(value)
+        if len(dnsnames) > 1:
+            raise CertificateError("hostname %r "
+                "doesn't match either of %s"
+                % (hostname, ', '.join(map(repr, dnsnames))))
+        elif len(dnsnames) == 1:
+            raise CertificateError("hostname %r "
+                "doesn't match %r"
+                % (hostname, dnsnames[0]))
+        else:
+            raise CertificateError("no appropriate commonName or "
+                "subjectAltName fields were found")
+
+
+class VerifyingHTTPSHandler(HTTPSHandler):
+    """Simple verifying handler: no auth, subclasses, timeouts, etc."""
+
+    def __init__(self, ca_bundle):
+        self.ca_bundle = ca_bundle
+        HTTPSHandler.__init__(self)
+
+    def https_open(self, req):
+        return self.do_open(
+            lambda host, **kw: VerifyingHTTPSConn(host, self.ca_bundle, **kw), req
+        )
+
+
+class VerifyingHTTPSConn(HTTPSConnection):
+    """Simple verifying connection: no auth, subclasses, timeouts, etc."""
+
+    def __init__(self, host, ca_bundle, **kw):
+        HTTPSConnection.__init__(self, host, **kw)
+        self.ca_bundle = ca_bundle
+
+    def connect(self):
+        sock = socket.create_connection(
+            (self.host, self.port), getattr(self, 'source_address', None)
+        )
+
+        # Handle the socket if a (proxy) tunnel is present
+        if hasattr(self, '_tunnel') and getattr(self, '_tunnel_host', None):
+            self.sock = sock
+            self._tunnel()
+            # http://bugs.python.org/issue7776: Python>=3.4.1 and >=2.7.7
+            # change self.host to mean the proxy server host when tunneling is
+            # being used. Adapt, since we are interested in the destination
+            # host for the match_hostname() comparison.
+            actual_host = self._tunnel_host
+        else:
+            actual_host = self.host
+
+        if hasattr(ssl, 'create_default_context'):
+            ctx = ssl.create_default_context(cafile=self.ca_bundle)
+            self.sock = ctx.wrap_socket(sock, server_hostname=actual_host)
+        else:
+            # This is for python < 2.7.9 and < 3.4?
+            self.sock = ssl.wrap_socket(
+                sock, cert_reqs=ssl.CERT_REQUIRED, ca_certs=self.ca_bundle
+            )
+        try:
+            match_hostname(self.sock.getpeercert(), actual_host)
+        except CertificateError:
+            self.sock.shutdown(socket.SHUT_RDWR)
+            self.sock.close()
+            raise
+
+
+def opener_for(ca_bundle=None):
+    """Get a urlopen() replacement that uses ca_bundle for verification"""
+    return urllib.request.build_opener(
+        VerifyingHTTPSHandler(ca_bundle or find_ca_bundle())
+    ).open
+
+
+# from jaraco.functools
+def once(func):
+    @functools.wraps(func)
+    def wrapper(*args, **kwargs):
+        if not hasattr(func, 'always_returns'):
+            func.always_returns = func(*args, **kwargs)
+        return func.always_returns
+    return wrapper
+
+
+@once
+def get_win_certfile():
+    try:
+        import wincertstore
+    except ImportError:
+        return None
+
+    class CertFile(wincertstore.CertFile):
+        def __init__(self):
+            super(CertFile, self).__init__()
+            atexit.register(self.close)
+
+        def close(self):
+            try:
+                super(CertFile, self).close()
+            except OSError:
+                pass
+
+    _wincerts = CertFile()
+    _wincerts.addstore('CA')
+    _wincerts.addstore('ROOT')
+    return _wincerts.name
+
+
+def find_ca_bundle():
+    """Return an existing CA bundle path, or None"""
+    extant_cert_paths = filter(os.path.isfile, cert_paths)
+    return (
+        get_win_certfile()
+        or next(extant_cert_paths, None)
+        or _certifi_where()
+    )
+
+
+def _certifi_where():
+    try:
+        return __import__('certifi').where()
+    except (ImportError, ResolutionError, ExtractionError):
+        pass
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/unicode_utils.py b/vendor/setuptools-39.0.1/build/lib/setuptools/unicode_utils.py
new file mode 100644
index 00000000..7c63efd2
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/unicode_utils.py
@@ -0,0 +1,44 @@
+import unicodedata
+import sys
+
+from setuptools.extern import six
+
+
+# HFS Plus uses decomposed UTF-8
+def decompose(path):
+    if isinstance(path, six.text_type):
+        return unicodedata.normalize('NFD', path)
+    try:
+        path = path.decode('utf-8')
+        path = unicodedata.normalize('NFD', path)
+        path = path.encode('utf-8')
+    except UnicodeError:
+        pass  # Not UTF-8
+    return path
+
+
+def filesys_decode(path):
+    """
+    Ensure that the given path is decoded,
+    NONE when no expected encoding works
+    """
+
+    if isinstance(path, six.text_type):
+        return path
+
+    fs_enc = sys.getfilesystemencoding() or 'utf-8'
+    candidates = fs_enc, 'utf-8'
+
+    for enc in candidates:
+        try:
+            return path.decode(enc)
+        except UnicodeDecodeError:
+            continue
+
+
+def try_encode(string, enc):
+    "turn unicode encoding into a functional routine"
+    try:
+        return string.encode(enc)
+    except UnicodeEncodeError:
+        return None
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/version.py b/vendor/setuptools-39.0.1/build/lib/setuptools/version.py
new file mode 100644
index 00000000..95e18696
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/version.py
@@ -0,0 +1,6 @@
+import pkg_resources
+
+try:
+    __version__ = pkg_resources.get_distribution('setuptools').version
+except Exception:
+    __version__ = 'unknown'
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/wheel.py b/vendor/setuptools-39.0.1/build/lib/setuptools/wheel.py
new file mode 100644
index 00000000..37dfa531
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/wheel.py
@@ -0,0 +1,163 @@
+'''Wheels support.'''
+
+from distutils.util import get_platform
+import email
+import itertools
+import os
+import re
+import zipfile
+
+from pkg_resources import Distribution, PathMetadata, parse_version
+from setuptools.extern.six import PY3
+from setuptools import Distribution as SetuptoolsDistribution
+from setuptools import pep425tags
+from setuptools.command.egg_info import write_requirements
+
+
+WHEEL_NAME = re.compile(
+    r"""^(?P<project_name>.+?)-(?P<version>\d.*?)
+    ((-(?P<build>\d.*?))?-(?P<py_version>.+?)-(?P<abi>.+?)-(?P<platform>.+?)
+    )\.whl$""",
+re.VERBOSE).match
+
+NAMESPACE_PACKAGE_INIT = '''\
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    __path__ = __import__('pkgutil').extend_path(__path__, __name__)
+'''
+
+
+def unpack(src_dir, dst_dir):
+    '''Move everything under `src_dir` to `dst_dir`, and delete the former.'''
+    for dirpath, dirnames, filenames in os.walk(src_dir):
+        subdir = os.path.relpath(dirpath, src_dir)
+        for f in filenames:
+            src = os.path.join(dirpath, f)
+            dst = os.path.join(dst_dir, subdir, f)
+            os.renames(src, dst)
+        for n, d in reversed(list(enumerate(dirnames))):
+            src = os.path.join(dirpath, d)
+            dst = os.path.join(dst_dir, subdir, d)
+            if not os.path.exists(dst):
+                # Directory does not exist in destination,
+                # rename it and prune it from os.walk list.
+                os.renames(src, dst)
+                del dirnames[n]
+    # Cleanup.
+    for dirpath, dirnames, filenames in os.walk(src_dir, topdown=True):
+        assert not filenames
+        os.rmdir(dirpath)
+
+
+class Wheel(object):
+
+    def __init__(self, filename):
+        match = WHEEL_NAME(os.path.basename(filename))
+        if match is None:
+            raise ValueError('invalid wheel name: %r' % filename)
+        self.filename = filename
+        for k, v in match.groupdict().items():
+            setattr(self, k, v)
+
+    def tags(self):
+        '''List tags (py_version, abi, platform) supported by this wheel.'''
+        return itertools.product(self.py_version.split('.'),
+                                 self.abi.split('.'),
+                                 self.platform.split('.'))
+
+    def is_compatible(self):
+        '''Is the wheel is compatible with the current platform?'''
+        supported_tags = pep425tags.get_supported()
+        return next((True for t in self.tags() if t in supported_tags), False)
+
+    def egg_name(self):
+        return Distribution(
+            project_name=self.project_name, version=self.version,
+            platform=(None if self.platform == 'any' else get_platform()),
+        ).egg_name() + '.egg'
+
+    def install_as_egg(self, destination_eggdir):
+        '''Install wheel as an egg directory.'''
+        with zipfile.ZipFile(self.filename) as zf:
+            dist_basename = '%s-%s' % (self.project_name, self.version)
+            dist_info = '%s.dist-info' % dist_basename
+            dist_data = '%s.data' % dist_basename
+            def get_metadata(name):
+                with zf.open('%s/%s' % (dist_info, name)) as fp:
+                    value = fp.read().decode('utf-8') if PY3 else fp.read()
+                    return email.parser.Parser().parsestr(value)
+            wheel_metadata = get_metadata('WHEEL')
+            dist_metadata = get_metadata('METADATA')
+            # Check wheel format version is supported.
+            wheel_version = parse_version(wheel_metadata.get('Wheel-Version'))
+            if not parse_version('1.0') <= wheel_version < parse_version('2.0dev0'):
+                raise ValueError('unsupported wheel format version: %s' % wheel_version)
+            # Extract to target directory.
+            os.mkdir(destination_eggdir)
+            zf.extractall(destination_eggdir)
+            # Convert metadata.
+            dist_info = os.path.join(destination_eggdir, dist_info)
+            dist = Distribution.from_location(
+                destination_eggdir, dist_info,
+                metadata=PathMetadata(destination_eggdir, dist_info)
+            )
+            # Note: we need to evaluate and strip markers now,
+            # as we can't easily convert back from the syntax:
+            # foobar; "linux" in sys_platform and extra == 'test'
+            def raw_req(req):
+                req.marker = None
+                return str(req)
+            install_requires = list(sorted(map(raw_req, dist.requires())))
+            extras_require = {
+                extra: list(sorted(
+                    req
+                    for req in map(raw_req, dist.requires((extra,)))
+                    if req not in install_requires
+                ))
+                for extra in dist.extras
+            }
+            egg_info = os.path.join(destination_eggdir, 'EGG-INFO')
+            os.rename(dist_info, egg_info)
+            os.rename(os.path.join(egg_info, 'METADATA'),
+                      os.path.join(egg_info, 'PKG-INFO'))
+            setup_dist = SetuptoolsDistribution(attrs=dict(
+                install_requires=install_requires,
+                extras_require=extras_require,
+            ))
+            write_requirements(setup_dist.get_command_obj('egg_info'),
+                               None, os.path.join(egg_info, 'requires.txt'))
+            # Move data entries to their correct location.
+            dist_data = os.path.join(destination_eggdir, dist_data)
+            dist_data_scripts = os.path.join(dist_data, 'scripts')
+            if os.path.exists(dist_data_scripts):
+                egg_info_scripts = os.path.join(destination_eggdir,
+                                                'EGG-INFO', 'scripts')
+                os.mkdir(egg_info_scripts)
+                for entry in os.listdir(dist_data_scripts):
+                    # Remove bytecode, as it's not properly handled
+                    # during easy_install scripts install phase.
+                    if entry.endswith('.pyc'):
+                        os.unlink(os.path.join(dist_data_scripts, entry))
+                    else:
+                        os.rename(os.path.join(dist_data_scripts, entry),
+                                  os.path.join(egg_info_scripts, entry))
+                os.rmdir(dist_data_scripts)
+            for subdir in filter(os.path.exists, (
+                os.path.join(dist_data, d)
+                for d in ('data', 'headers', 'purelib', 'platlib')
+            )):
+                unpack(subdir, destination_eggdir)
+            if os.path.exists(dist_data):
+                os.rmdir(dist_data)
+            # Fix namespace packages.
+            namespace_packages = os.path.join(egg_info, 'namespace_packages.txt')
+            if os.path.exists(namespace_packages):
+                with open(namespace_packages) as fp:
+                    namespace_packages = fp.read().split()
+                for mod in namespace_packages:
+                    mod_dir = os.path.join(destination_eggdir, *mod.split('.'))
+                    mod_init = os.path.join(mod_dir, '__init__.py')
+                    if os.path.exists(mod_dir) and not os.path.exists(mod_init):
+                        with open(mod_init, 'w') as fp:
+                            fp.write(NAMESPACE_PACKAGE_INIT)
diff --git a/vendor/setuptools-39.0.1/build/lib/setuptools/windows_support.py b/vendor/setuptools-39.0.1/build/lib/setuptools/windows_support.py
new file mode 100644
index 00000000..cb977cff
--- /dev/null
+++ b/vendor/setuptools-39.0.1/build/lib/setuptools/windows_support.py
@@ -0,0 +1,29 @@
+import platform
+import ctypes
+
+
+def windows_only(func):
+    if platform.system() != 'Windows':
+        return lambda *args, **kwargs: None
+    return func
+
+
+@windows_only
+def hide_file(path):
+    """
+    Set the hidden attribute on a file or directory.
+
+    From http://stackoverflow.com/questions/19622133/
+
+    `path` must be text.
+    """
+    __import__('ctypes.wintypes')
+    SetFileAttributes = ctypes.windll.kernel32.SetFileAttributesW
+    SetFileAttributes.argtypes = ctypes.wintypes.LPWSTR, ctypes.wintypes.DWORD
+    SetFileAttributes.restype = ctypes.wintypes.BOOL
+
+    FILE_ATTRIBUTE_HIDDEN = 0x02
+
+    ret = SetFileAttributes(path, FILE_ATTRIBUTE_HIDDEN)
+    if not ret:
+        raise ctypes.WinError()
diff --git a/vendor/setuptools-39.0.1/conftest.py b/vendor/setuptools-39.0.1/conftest.py
new file mode 100644
index 00000000..3cccfe1a
--- /dev/null
+++ b/vendor/setuptools-39.0.1/conftest.py
@@ -0,0 +1,8 @@
+pytest_plugins = 'setuptools.tests.fixtures'
+
+
+def pytest_addoption(parser):
+    parser.addoption(
+        "--package_name", action="append", default=[],
+        help="list of package_name to pass to test functions",
+    )
diff --git a/vendor/setuptools-39.0.1/dist/setuptools-39.0.1-py2.7.egg b/vendor/setuptools-39.0.1/dist/setuptools-39.0.1-py2.7.egg
new file mode 100644
index 0000000000000000000000000000000000000000..ec8e3d52ce7932caaf3a191067940cedf74dcad6
GIT binary patch
literal 563427
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%0AbBVWk
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
a;oxo3q5zH-2xJ2MIRHYD32z`K0sS8(iPCrg

literal 0
HcmV?d00001

diff --git a/vendor/setuptools-39.0.1/docs/Makefile b/vendor/setuptools-39.0.1/docs/Makefile
new file mode 100644
index 00000000..30bf10a9
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/Makefile
@@ -0,0 +1,75 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html      to make standalone HTML files"
+	@echo "  pickle    to make pickle files"
+	@echo "  json      to make JSON files"
+	@echo "  htmlhelp  to make HTML files and a HTML help project"
+	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  changes   to make an overview over all changed/added/deprecated items"
+	@echo "  linkcheck to check all external links for integrity"
+
+clean:
+	-rm -rf build/*
+
+html:
+	mkdir -p build/html build/doctrees
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
+	@echo
+	@echo "Build finished. The HTML pages are in build/html."
+
+pickle:
+	mkdir -p build/pickle build/doctrees
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+web: pickle
+
+json:
+	mkdir -p build/json build/doctrees
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) build/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	mkdir -p build/htmlhelp build/doctrees
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in build/htmlhelp."
+
+latex:
+	mkdir -p build/latex build/doctrees
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in build/latex."
+	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+	      "run these through (pdf)latex."
+
+changes:
+	mkdir -p build/changes build/doctrees
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
+	@echo
+	@echo "The overview file is in build/changes."
+
+linkcheck:
+	mkdir -p build/linkcheck build/doctrees
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in build/linkcheck/output.txt."
diff --git a/vendor/setuptools-39.0.1/docs/_templates/indexsidebar.html b/vendor/setuptools-39.0.1/docs/_templates/indexsidebar.html
new file mode 100644
index 00000000..3b127602
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/_templates/indexsidebar.html
@@ -0,0 +1,8 @@
+<h3>Download</h3>
+
+<p>Current version: <b>{{ version }}</b></p>
+<p>Get Setuptools from the <a href="https://pypi.python.org/pypi/setuptools"> Python Package Index</a>
+
+<h3>Questions? Suggestions? Contributions?</h3>
+
+<p>Visit the <a href="https://github.com/pypa/setuptools">Setuptools project page</a> </p>
diff --git a/vendor/setuptools-39.0.1/docs/_theme/nature/static/nature.css_t b/vendor/setuptools-39.0.1/docs/_theme/nature/static/nature.css_t
new file mode 100644
index 00000000..1a654264
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/_theme/nature/static/nature.css_t
@@ -0,0 +1,237 @@
+/**
+ * Sphinx stylesheet -- default theme
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+ 
+@import url("basic.css");
+ 
+/* -- page layout ----------------------------------------------------------- */
+ 
+body {
+    font-family: Arial, sans-serif;
+    font-size: 100%;
+    background-color: #111111;
+    color: #555555;
+    margin: 0;
+    padding: 0;
+}
+
+div.documentwrapper {
+    float: left;
+    width: 100%;
+}
+
+div.bodywrapper {
+    margin: 0 0 0 300px;
+}
+
+hr{
+    border: 1px solid #B1B4B6;
+}
+ 
+div.document {
+    background-color: #fafafa;
+}
+ 
+div.body {
+    background-color: #ffffff;
+    color: #3E4349;
+    padding: 1em 30px 30px 30px;
+    font-size: 0.9em;
+}
+ 
+div.footer {
+    color: #555;
+    width: 100%;
+    padding: 13px 0;
+    text-align: center;
+    font-size: 75%;
+}
+ 
+div.footer a {
+    color: #444444;
+}
+ 
+div.related {
+    background-color: #6BA81E;
+    line-height: 36px;
+    color: #ffffff;
+    text-shadow: 0px 1px 0 #444444;
+    font-size: 1.1em;
+}
+ 
+div.related a {
+    color: #E2F3CC;
+}
+
+div.related .right {
+    font-size: 0.9em;
+}
+
+div.sphinxsidebar {
+    font-size: 0.9em;
+    line-height: 1.5em;
+    width: 300px;
+}
+
+div.sphinxsidebarwrapper{
+    padding: 20px 0;
+}
+ 
+div.sphinxsidebar h3,
+div.sphinxsidebar h4 {
+    font-family: Arial, sans-serif;
+    color: #222222;
+    font-size: 1.2em;
+    font-weight: bold;
+    margin: 0;
+    padding: 5px 10px;
+    text-shadow: 1px 1px 0 white
+}
+
+div.sphinxsidebar h3 a {
+    color: #444444;
+}
+
+div.sphinxsidebar p {
+    color: #888888;
+    padding: 5px 20px;
+    margin: 0.5em 0px;
+}
+ 
+div.sphinxsidebar p.topless {
+}
+ 
+div.sphinxsidebar ul {
+    margin: 10px 10px 10px 20px;
+    padding: 0;
+    color: #000000;
+}
+ 
+div.sphinxsidebar a {
+    color: #444444;
+}
+
+div.sphinxsidebar a:hover {
+    color: #E32E00;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #cccccc;
+    font-family: sans-serif;
+    font-size: 1.1em;
+    padding: 0.15em 0.3em;
+}
+
+div.sphinxsidebar input[type=text]{
+    margin-left: 20px;
+}
+ 
+/* -- body styles ----------------------------------------------------------- */
+ 
+a {
+    color: #005B81;
+    text-decoration: none;
+}
+ 
+a:hover {
+    color: #E32E00;
+}
+ 
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+    font-family: Arial, sans-serif;
+    font-weight: normal;
+    color: #212224;
+    margin: 30px 0px 10px 0px;
+    padding: 5px 0 5px 0px;
+    text-shadow: 0px 1px 0 white;
+    border-bottom: 1px solid #C8D5E3;
+}
+ 
+div.body h1 { margin-top: 0; font-size: 200%; }
+div.body h2 { font-size: 150%; }
+div.body h3 { font-size: 120%; }
+div.body h4 { font-size: 110%; }
+div.body h5 { font-size: 100%; }
+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 {
+    line-height: 1.8em;
+}
+ 
+div.admonition p.admonition-title + p {
+    display: inline;
+}
+
+div.highlight{
+    background-color: white;
+}
+
+div.note {
+    background-color: #eeeeee;
+    border: 1px solid #cccccc;
+}
+ 
+div.seealso {
+    background-color: #ffffcc;
+    border: 1px solid #ffff66;
+}
+ 
+div.topic {
+    background-color: #fafafa;
+    border-width: 0;
+}
+ 
+div.warning {
+    background-color: #ffe4e4;
+    border: 1px solid #ff6666;
+}
+ 
+p.admonition-title {
+    display: inline;
+}
+ 
+p.admonition-title:after {
+    content: ":";
+}
+ 
+pre {
+    padding: 10px;
+    background-color: #fafafa;
+    color: #222222;
+    line-height: 1.5em;
+    font-size: 1.1em;
+    margin: 1.5em 0 1.5em 0;
+    -webkit-box-shadow: 0px 0px 4px #d8d8d8;
+    -moz-box-shadow: 0px 0px 4px #d8d8d8;
+    box-shadow: 0px 0px 4px #d8d8d8;
+}
+ 
+tt {
+    color: #222222;
+    padding: 1px 2px;
+    font-size: 1.2em;
+    font-family: monospace;
+}
+
+#table-of-contents ul {
+    padding-left: 2em;
+}
+
diff --git a/vendor/setuptools-39.0.1/docs/_theme/nature/static/pygments.css b/vendor/setuptools-39.0.1/docs/_theme/nature/static/pygments.css
new file mode 100644
index 00000000..652b7612
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/_theme/nature/static/pygments.css
@@ -0,0 +1,54 @@
+.c { color: #999988; font-style: italic } /* Comment */
+.k { font-weight: bold } /* Keyword */
+.o { font-weight: bold } /* Operator */
+.cm { color: #999988; font-style: italic } /* Comment.Multiline */
+.cp { color: #999999; font-weight: bold } /* Comment.preproc */
+.c1 { color: #999988; font-style: italic } /* Comment.Single */
+.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
+.ge { font-style: italic } /* Generic.Emph */
+.gr { color: #aa0000 } /* Generic.Error */
+.gh { color: #999999 } /* Generic.Heading */
+.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
+.go { color: #111 } /* Generic.Output */
+.gp { color: #555555 } /* Generic.Prompt */
+.gs { font-weight: bold } /* Generic.Strong */
+.gu { color: #aaaaaa } /* Generic.Subheading */
+.gt { color: #aa0000 } /* Generic.Traceback */
+.kc { font-weight: bold } /* Keyword.Constant */
+.kd { font-weight: bold } /* Keyword.Declaration */
+.kp { font-weight: bold } /* Keyword.Pseudo */
+.kr { font-weight: bold } /* Keyword.Reserved */
+.kt { color: #445588; font-weight: bold } /* Keyword.Type */
+.m { color: #009999 } /* Literal.Number */
+.s { color: #bb8844 } /* Literal.String */
+.na { color: #008080 } /* Name.Attribute */
+.nb { color: #999999 } /* Name.Builtin */
+.nc { color: #445588; font-weight: bold } /* Name.Class */
+.no { color: #ff99ff } /* Name.Constant */
+.ni { color: #800080 } /* Name.Entity */
+.ne { color: #990000; font-weight: bold } /* Name.Exception */
+.nf { color: #990000; font-weight: bold } /* Name.Function */
+.nn { color: #555555 } /* Name.Namespace */
+.nt { color: #000080 } /* Name.Tag */
+.nv { color: purple } /* Name.Variable */
+.ow { font-weight: bold } /* Operator.Word */
+.mf { color: #009999 } /* Literal.Number.Float */
+.mh { color: #009999 } /* Literal.Number.Hex */
+.mi { color: #009999 } /* Literal.Number.Integer */
+.mo { color: #009999 } /* Literal.Number.Oct */
+.sb { color: #bb8844 } /* Literal.String.Backtick */
+.sc { color: #bb8844 } /* Literal.String.Char */
+.sd { color: #bb8844 } /* Literal.String.Doc */
+.s2 { color: #bb8844 } /* Literal.String.Double */
+.se { color: #bb8844 } /* Literal.String.Escape */
+.sh { color: #bb8844 } /* Literal.String.Heredoc */
+.si { color: #bb8844 } /* Literal.String.Interpol */
+.sx { color: #bb8844 } /* Literal.String.Other */
+.sr { color: #808000 } /* Literal.String.Regex */
+.s1 { color: #bb8844 } /* Literal.String.Single */
+.ss { color: #bb8844 } /* Literal.String.Symbol */
+.bp { color: #999999 } /* Name.Builtin.Pseudo */
+.vc { color: #ff99ff } /* Name.Variable.Class */
+.vg { color: #ff99ff } /* Name.Variable.Global */
+.vi { color: #ff99ff } /* Name.Variable.Instance */
+.il { color: #009999 } /* Literal.Number.Integer.Long */
\ No newline at end of file
diff --git a/vendor/setuptools-39.0.1/docs/_theme/nature/theme.conf b/vendor/setuptools-39.0.1/docs/_theme/nature/theme.conf
new file mode 100644
index 00000000..1cc40044
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/_theme/nature/theme.conf
@@ -0,0 +1,4 @@
+[theme]
+inherit = basic
+stylesheet = nature.css
+pygments_style = tango
diff --git a/vendor/setuptools-39.0.1/docs/conf.py b/vendor/setuptools-39.0.1/docs/conf.py
new file mode 100644
index 00000000..f7d02303
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/conf.py
@@ -0,0 +1,151 @@
+# -*- coding: utf-8 -*-
+#
+# Setuptools documentation build configuration file, created by
+# sphinx-quickstart on Fri Jul 17 14:22:37 2009.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# The contents of this file are pickled, so don't put values in the namespace
+# that aren't pickleable (module imports are okay, they're removed automatically).
+#
+# 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
+
+# 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.
+
+import subprocess
+import sys
+import os
+
+
+# hack to run the bootstrap script so that jaraco.packaging.sphinx
+# can invoke setup.py
+'READTHEDOCS' in os.environ and subprocess.check_call(
+    [sys.executable, 'bootstrap.py'],
+    cwd=os.path.join(os.path.dirname(__file__), os.path.pardir),
+)
+
+# -- 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 = ['jaraco.packaging.sphinx', 'rst.linker', 'sphinx.ext.autosectionlabel']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.txt'
+
+# The master toctree document.
+master_doc = 'index'
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_trees = []
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# -- 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 = 'nature'
+
+# Add any paths that contain custom themes here, relative to this directory.
+html_theme_path = ['_theme']
+
+# 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 = {'index': 'indexsidebar.html'}
+
+# If false, no module index is generated.
+html_use_modindex = False
+
+# If false, no index is generated.
+html_use_index = False
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'Setuptools.tex', 'Setuptools Documentation',
+   'The fellowship of the packaging', 'manual'),
+]
+
+link_files = {
+    '../CHANGES.rst': dict(
+        using=dict(
+            BB='https://bitbucket.org',
+            GH='https://github.com',
+        ),
+        replace=[
+            dict(
+                pattern=r'(Issue )?#(?P<issue>\d+)',
+                url='{package_url}/issues/{issue}',
+            ),
+            dict(
+                pattern=r'BB Pull Request ?#(?P<bb_pull_request>\d+)',
+                url='{BB}/pypa/setuptools/pull-request/{bb_pull_request}',
+            ),
+            dict(
+                pattern=r'Distribute #(?P<distribute>\d+)',
+                url='{BB}/tarek/distribute/issue/{distribute}',
+            ),
+            dict(
+                pattern=r'Buildout #(?P<buildout>\d+)',
+                url='{GH}/buildout/buildout/issues/{buildout}',
+            ),
+            dict(
+                pattern=r'Old Setuptools #(?P<old_setuptools>\d+)',
+                url='http://bugs.python.org/setuptools/issue{old_setuptools}',
+            ),
+            dict(
+                pattern=r'Jython #(?P<jython>\d+)',
+                url='http://bugs.jython.org/issue{jython}',
+            ),
+            dict(
+                pattern=r'Python #(?P<python>\d+)',
+                url='http://bugs.python.org/issue{python}',
+            ),
+            dict(
+                pattern=r'Interop #(?P<interop>\d+)',
+                url='{GH}/pypa/interoperability-peps/issues/{interop}',
+            ),
+            dict(
+                pattern=r'Pip #(?P<pip>\d+)',
+                url='{GH}/pypa/pip/issues/{pip}',
+            ),
+            dict(
+                pattern=r'Packaging #(?P<packaging>\d+)',
+                url='{GH}/pypa/packaging/issues/{packaging}',
+            ),
+            dict(
+                pattern=r'[Pp]ackaging (?P<packaging_ver>\d+(\.\d+)+)',
+                url='{GH}/pypa/packaging/blob/{packaging_ver}/CHANGELOG.rst',
+            ),
+            dict(
+                pattern=r'PEP[- ](?P<pep_number>\d+)',
+                url='https://www.python.org/dev/peps/pep-{pep_number:0>4}/',
+            ),
+            dict(
+                pattern=r'setuptools_svn #(?P<setuptools_svn>\d+)',
+                url='{GH}/jaraco/setuptools_svn/issues/{setuptools_svn}',
+            ),
+            dict(
+                pattern=r'^(?m)((?P<scm_version>v?\d+(\.\d+){1,2}))\n[-=]+\n',
+                with_scm='{text}\n{rev[timestamp]:%d %b %Y}\n',
+            ),
+        ],
+    ),
+}
diff --git a/vendor/setuptools-39.0.1/docs/developer-guide.txt b/vendor/setuptools-39.0.1/docs/developer-guide.txt
new file mode 100644
index 00000000..b2c1a0ce
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/developer-guide.txt
@@ -0,0 +1,115 @@
+================================
+Developer's Guide for Setuptools
+================================
+
+If you want to know more about contributing on Setuptools, this is the place.
+
+
+.. contents:: **Table of Contents**
+
+
+-------------------
+Recommended Reading
+-------------------
+
+Please read `How to write the perfect pull request
+<https://blog.jaraco.com/how-to-write-perfect-pull-request/>`_ for some tips
+on contributing to open source projects. Although the article is not
+authoritative, it was authored by the maintainer of Setuptools, so reflects
+his opinions and will improve the likelihood of acceptance and quality of
+contribution.
+
+------------------
+Project Management
+------------------
+
+Setuptools is maintained primarily in Github at `this home
+<https://github.com/pypa/setuptools>`_. Setuptools is maintained under the
+Python Packaging Authority (PyPA) with several core contributors. All bugs
+for Setuptools are filed and the canonical source is maintained in Github.
+
+User support and discussions are done through the issue tracker (for specific)
+issues, through the distutils-sig mailing list, or on IRC (Freenode) at
+#pypa.
+
+Discussions about development happen on the pypa-dev mailing list or on
+`Gitter <https://gitter.im/pypa/setuptools>`_.
+
+-----------------
+Authoring Tickets
+-----------------
+
+Before authoring any source code, it's often prudent to file a ticket
+describing the motivation behind making changes. First search to see if a
+ticket already exists for your issue. If not, create one. Try to think from
+the perspective of the reader. Explain what behavior you expected, what you
+got instead, and what factors might have contributed to the unexpected
+behavior. In Github, surround a block of code or traceback with the triple
+backtick "\`\`\`" so that it is formatted nicely.
+
+Filing a ticket provides a forum for justification, discussion, and
+clarification. The ticket provides a record of the purpose for the change and
+any hard decisions that were made. It provides a single place for others to
+reference when trying to understand why the software operates the way it does
+or why certain changes were made.
+
+Setuptools makes extensive use of hyperlinks to tickets in the changelog so
+that system integrators and other users can get a quick summary, but then
+jump to the in-depth discussion about any subject referenced.
+
+-----------
+Source Code
+-----------
+
+Grab the code at Github::
+
+    $ git checkout https://github.com/pypa/setuptools
+
+If you want to contribute changes, we recommend you fork the repository on
+Github, commit the changes to your repository, and then make a pull request
+on Github. If you make some changes, don't forget to:
+
+- add a note in CHANGES.rst
+
+Please commit all changes in the 'master' branch against the latest available
+commit or for bug-fixes, against an earlier commit or release in which the
+bug occurred.
+
+If you find yourself working on more than one issue at a time, Setuptools
+generally prefers Git-style branches, so use Mercurial bookmarks or Git
+branches or multiple forks to maintain separate efforts.
+
+The Continuous Integration tests that validate every release are run
+from this repository.
+
+-------
+Testing
+-------
+
+The primary tests are run using tox. To run the tests, first make
+sure you have tox installed, then invoke it::
+
+    $ tox
+
+Under continuous integration, additional tests may be run. See the
+``.travis.yml`` file for full details on the tests run under Travis-CI.
+
+-------------------
+Semantic Versioning
+-------------------
+
+Setuptools follows ``semver``.
+
+.. explain value of reflecting meaning in versions.
+
+----------------------
+Building Documentation
+----------------------
+
+Setuptools relies on the Sphinx system for building documentation.
+To accommodate RTD, docs must be built from the docs/ directory.
+
+To build them, you need to have installed the requirements specified
+in docs/requirements.txt. One way to do this is to use rwt:
+
+    setuptools/docs$ python -m rwt -r requirements.txt -- -m sphinx . html
diff --git a/vendor/setuptools-39.0.1/docs/development.txt b/vendor/setuptools-39.0.1/docs/development.txt
new file mode 100644
index 00000000..455f038a
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/development.txt
@@ -0,0 +1,35 @@
+-------------------------
+Development on Setuptools
+-------------------------
+
+Setuptools is maintained by the Python community under the Python Packaging
+Authority (PyPA) and led by Jason R. Coombs.
+
+This document describes the process by which Setuptools is developed.
+This document assumes the reader has some passing familiarity with
+*using* setuptools, the ``pkg_resources`` module, and EasyInstall.  It
+does not attempt to explain basic concepts like inter-project
+dependencies, nor does it contain detailed lexical syntax for most
+file formats.  Neither does it explain concepts like "namespace
+packages" or "resources" in any detail, as all of these subjects are
+covered at length in the setuptools developer's guide and the
+``pkg_resources`` reference manual.
+
+Instead, this is **internal** documentation for how those concepts and
+features are *implemented* in concrete terms.  It is intended for people
+who are working on the setuptools code base, who want to be able to
+troubleshoot setuptools problems, want to write code that reads the file
+formats involved, or want to otherwise tinker with setuptools-generated
+files and directories.
+
+Note, however, that these are all internal implementation details and
+are therefore subject to change; stick to the published API if you don't
+want to be responsible for keeping your code from breaking when
+setuptools changes.  You have been warned.
+
+.. toctree::
+   :maxdepth: 1
+
+   developer-guide
+   formats
+   releases
diff --git a/vendor/setuptools-39.0.1/docs/easy_install.txt b/vendor/setuptools-39.0.1/docs/easy_install.txt
new file mode 100644
index 00000000..56b16672
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/easy_install.txt
@@ -0,0 +1,1623 @@
+============
+Easy Install
+============
+
+Easy Install is a python module (``easy_install``) bundled with ``setuptools``
+that lets you automatically download, build, install, and manage Python
+packages.
+
+Please share your experiences with us! If you encounter difficulty installing
+a package, please contact us via the `distutils mailing list
+<http://mail.python.org/pipermail/distutils-sig/>`_.  (Note: please DO NOT send
+private email directly to the author of setuptools; it will be discarded.  The
+mailing list is a searchable archive of previously-asked and answered
+questions; you should begin your research there before reporting something as a
+bug -- and then do so via list discussion first.)
+
+(Also, if you'd like to learn about how you can use ``setuptools`` to make your
+own packages work better with EasyInstall, or provide EasyInstall-like features
+without requiring your users to use EasyInstall directly, you'll probably want
+to check out the full `setuptools`_ documentation as well.)
+
+.. contents:: **Table of Contents**
+
+
+Using "Easy Install"
+====================
+
+
+.. _installation instructions:
+
+Installing "Easy Install"
+-------------------------
+
+Please see the `setuptools PyPI page <https://pypi.python.org/pypi/setuptools>`_
+for download links and basic installation instructions for each of the
+supported platforms.
+
+You will need at least Python 3.3 or 2.7.  An ``easy_install`` script will be
+installed in the normal location for Python scripts on your platform.
+
+Note that the instructions on the setuptools PyPI page assume that you are
+are installing to Python's primary ``site-packages`` directory.  If this is
+not the case, you should consult the section below on `Custom Installation
+Locations`_ before installing.  (And, on Windows, you should not use the
+``.exe`` installer when installing to an alternate location.)
+
+Note that ``easy_install`` normally works by downloading files from the
+internet.  If you are behind an NTLM-based firewall that prevents Python
+programs from accessing the net directly, you may wish to first install and use
+the `APS proxy server <http://ntlmaps.sf.net/>`_, which lets you get past such
+firewalls in the same way that your web browser(s) do.
+
+(Alternately, if you do not wish easy_install to actually download anything, you
+can restrict it from doing so with the ``--allow-hosts`` option; see the
+sections on `restricting downloads with --allow-hosts`_ and `command-line
+options`_ for more details.)
+
+
+Troubleshooting
+~~~~~~~~~~~~~~~
+
+If EasyInstall/setuptools appears to install correctly, and you can run the
+``easy_install`` command but it fails with an ``ImportError``, the most likely
+cause is that you installed to a location other than ``site-packages``,
+without taking any of the steps described in the `Custom Installation
+Locations`_ section below.  Please see that section and follow the steps to
+make sure that your custom location will work correctly.  Then re-install.
+
+Similarly, if you can run ``easy_install``, and it appears to be installing
+packages, but then you can't import them, the most likely issue is that you
+installed EasyInstall correctly but are using it to install packages to a
+non-standard location that hasn't been properly prepared.  Again, see the
+section on `Custom Installation Locations`_ for more details.
+
+
+Windows Notes
+~~~~~~~~~~~~~
+
+Installing setuptools will provide an ``easy_install`` command according to
+the techniques described in `Executables and Launchers`_. If the
+``easy_install`` command is not available after installation, that section
+provides details on how to configure Windows to make the commands available.
+
+
+Downloading and Installing a Package
+------------------------------------
+
+For basic use of ``easy_install``, you need only supply the filename or URL of
+a source distribution or .egg file (`Python Egg`__).
+
+__ http://peak.telecommunity.com/DevCenter/PythonEggs
+
+**Example 1**. Install a package by name, searching PyPI for the latest
+version, and automatically downloading, building, and installing it::
+
+    easy_install SQLObject
+
+**Example 2**. Install or upgrade a package by name and version by finding
+links on a given "download page"::
+
+    easy_install -f http://pythonpaste.org/package_index.html SQLObject
+
+**Example 3**. Download a source distribution from a specified URL,
+automatically building and installing it::
+
+    easy_install http://example.com/path/to/MyPackage-1.2.3.tgz
+
+**Example 4**. Install an already-downloaded .egg file::
+
+    easy_install /my_downloads/OtherPackage-3.2.1-py2.3.egg
+
+**Example 5**.  Upgrade an already-installed package to the latest version
+listed on PyPI::
+
+    easy_install --upgrade PyProtocols
+
+**Example 6**.  Install a source distribution that's already downloaded and
+extracted in the current directory (New in 0.5a9)::
+
+    easy_install .
+
+**Example 7**.  (New in 0.6a1) Find a source distribution or Subversion
+checkout URL for a package, and extract it or check it out to
+``~/projects/sqlobject`` (the name will always be in all-lowercase), where it
+can be examined or edited.  (The package will not be installed, but it can
+easily be installed with ``easy_install ~/projects/sqlobject``.  See `Editing
+and Viewing Source Packages`_ below for more info.)::
+
+    easy_install --editable --build-directory ~/projects SQLObject
+
+**Example 7**. (New in 0.6.11) Install a distribution within your home dir::
+
+    easy_install --user SQLAlchemy
+
+Easy Install accepts URLs, filenames, PyPI package names (i.e., ``distutils``
+"distribution" names), and package+version specifiers.  In each case, it will
+attempt to locate the latest available version that meets your criteria.
+
+When downloading or processing downloaded files, Easy Install recognizes
+distutils source distribution files with extensions of .tgz, .tar, .tar.gz,
+.tar.bz2, or .zip.  And of course it handles already-built .egg
+distributions as well as ``.win32.exe`` installers built using distutils.
+
+By default, packages are installed to the running Python installation's
+``site-packages`` directory, unless you provide the ``-d`` or ``--install-dir``
+option to specify an alternative directory, or specify an alternate location
+using distutils configuration files.  (See `Configuration Files`_, below.)
+
+By default, any scripts included with the package are installed to the running
+Python installation's standard script installation location.  However, if you
+specify an installation directory via the command line or a config file, then
+the default directory for installing scripts will be the same as the package
+installation directory, to ensure that the script will have access to the
+installed package.  You can override this using the ``-s`` or ``--script-dir``
+option.
+
+Installed packages are added to an ``easy-install.pth`` file in the install
+directory, so that Python will always use the most-recently-installed version
+of the package.  If you would like to be able to select which version to use at
+runtime, you should use the ``-m`` or ``--multi-version`` option.
+
+
+Upgrading a Package
+-------------------
+
+You don't need to do anything special to upgrade a package: just install the
+new version, either by requesting a specific version, e.g.::
+
+    easy_install "SomePackage==2.0"
+
+a version greater than the one you have now::
+
+    easy_install "SomePackage>2.0"
+
+using the upgrade flag, to find the latest available version on PyPI::
+
+    easy_install --upgrade SomePackage
+
+or by using a download page, direct download URL, or package filename::
+
+    easy_install -f http://example.com/downloads ExamplePackage
+
+    easy_install http://example.com/downloads/ExamplePackage-2.0-py2.4.egg
+
+    easy_install my_downloads/ExamplePackage-2.0.tgz
+
+If you're using ``-m`` or ``--multi-version`` , using the ``require()``
+function at runtime automatically selects the newest installed version of a
+package that meets your version criteria.  So, installing a newer version is
+the only step needed to upgrade such packages.
+
+If you're installing to a directory on PYTHONPATH, or a configured "site"
+directory (and not using ``-m``), installing a package automatically replaces
+any previous version in the ``easy-install.pth`` file, so that Python will
+import the most-recently installed version by default.  So, again, installing
+the newer version is the only upgrade step needed.
+
+If you haven't suppressed script installation (using ``--exclude-scripts`` or
+``-x``), then the upgraded version's scripts will be installed, and they will
+be automatically patched to ``require()`` the corresponding version of the
+package, so that you can use them even if they are installed in multi-version
+mode.
+
+``easy_install`` never actually deletes packages (unless you're installing a
+package with the same name and version number as an existing package), so if
+you want to get rid of older versions of a package, please see `Uninstalling
+Packages`_, below.
+
+
+Changing the Active Version
+---------------------------
+
+If you've upgraded a package, but need to revert to a previously-installed
+version, you can do so like this::
+
+    easy_install PackageName==1.2.3
+
+Where ``1.2.3`` is replaced by the exact version number you wish to switch to.
+If a package matching the requested name and version is not already installed
+in a directory on ``sys.path``, it will be located via PyPI and installed.
+
+If you'd like to switch to the latest installed version of ``PackageName``, you
+can do so like this::
+
+    easy_install PackageName
+
+This will activate the latest installed version.  (Note: if you have set any
+``find_links`` via distutils configuration files, those download pages will be
+checked for the latest available version of the package, and it will be
+downloaded and installed if it is newer than your current version.)
+
+Note that changing the active version of a package will install the newly
+active version's scripts, unless the ``--exclude-scripts`` or ``-x`` option is
+specified.
+
+
+Uninstalling Packages
+---------------------
+
+If you have replaced a package with another version, then you can just delete
+the package(s) you don't need by deleting the PackageName-versioninfo.egg file
+or directory (found in the installation directory).
+
+If you want to delete the currently installed version of a package (or all
+versions of a package), you should first run::
+
+    easy_install -m PackageName
+
+This will ensure that Python doesn't continue to search for a package you're
+planning to remove. After you've done this, you can safely delete the .egg
+files or directories, along with any scripts you wish to remove.
+
+
+Managing Scripts
+----------------
+
+Whenever you install, upgrade, or change versions of a package, EasyInstall
+automatically installs the scripts for the selected package version, unless
+you tell it not to with ``-x`` or ``--exclude-scripts``.  If any scripts in
+the script directory have the same name, they are overwritten.
+
+Thus, you do not normally need to manually delete scripts for older versions of
+a package, unless the newer version of the package does not include a script
+of the same name.  However, if you are completely uninstalling a package, you
+may wish to manually delete its scripts.
+
+EasyInstall's default behavior means that you can normally only run scripts
+from one version of a package at a time.  If you want to keep multiple versions
+of a script available, however, you can simply use the ``--multi-version`` or
+``-m`` option, and rename the scripts that EasyInstall creates.  This works
+because EasyInstall installs scripts as short code stubs that ``require()`` the
+matching version of the package the script came from, so renaming the script
+has no effect on what it executes.
+
+For example, suppose you want to use two versions of the ``rst2html`` tool
+provided by the `docutils <http://docutils.sf.net/>`_ package.  You might
+first install one version::
+
+    easy_install -m docutils==0.3.9
+
+then rename the ``rst2html.py`` to ``r2h_039``, and install another version::
+
+    easy_install -m docutils==0.3.10
+
+This will create another ``rst2html.py`` script, this one using docutils
+version 0.3.10 instead of 0.3.9.  You now have two scripts, each using a
+different version of the package.  (Notice that we used ``-m`` for both
+installations, so that Python won't lock us out of using anything but the most
+recently-installed version of the package.)
+
+
+Executables and Launchers
+-------------------------
+
+On Unix systems, scripts are installed with as natural files with a "#!"
+header and no extension and they launch under the Python version indicated in
+the header.
+
+On Windows, there is no mechanism to "execute" files without extensions, so
+EasyInstall provides two techniques to mirror the Unix behavior. The behavior
+is indicated by the SETUPTOOLS_LAUNCHER environment variable, which may be
+"executable" (default) or "natural".
+
+Regardless of the technique used, the script(s) will be installed to a Scripts
+directory (by default in the Python installation directory). It is recommended
+for EasyInstall that you ensure this directory is in the PATH environment
+variable. The easiest way to ensure the Scripts directory is in the PATH is
+to run ``Tools\Scripts\win_add2path.py`` from the Python directory.
+
+Note that instead of changing your ``PATH`` to include the Python scripts
+directory, you can also retarget the installation location for scripts so they
+go on a directory that's already on the ``PATH``.  For more information see
+`Command-Line Options`_ and `Configuration Files`_.  During installation,
+pass command line options (such as ``--script-dir``) to
+``ez_setup.py`` to control where ``easy_install.exe`` will be installed.
+
+
+Windows Executable Launcher
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If the "executable" launcher is used, EasyInstall will create a '.exe'
+launcher of the same name beside each installed script (including
+``easy_install`` itself). These small .exe files launch the script of the
+same name using the Python version indicated in the '#!' header.
+
+This behavior is currently default. To force
+the use of executable launchers, set ``SETUPTOOLS_LAUNCHER`` to "executable".
+
+Natural Script Launcher
+~~~~~~~~~~~~~~~~~~~~~~~
+
+EasyInstall also supports deferring to an external launcher such as
+`pylauncher <https://bitbucket.org/pypa/pylauncher>`_ for launching scripts.
+Enable this experimental functionality by setting the
+``SETUPTOOLS_LAUNCHER`` environment variable to "natural". EasyInstall will
+then install scripts as simple
+scripts with a .pya (or .pyw) extension appended. If these extensions are
+associated with the pylauncher and listed in the PATHEXT environment variable,
+these scripts can then be invoked simply and directly just like any other
+executable. This behavior may become default in a future version.
+
+EasyInstall uses the .pya extension instead of simply
+the typical '.py' extension. This distinct extension is necessary to prevent
+Python
+from treating the scripts as importable modules (where name conflicts exist).
+Current releases of pylauncher do not yet associate with .pya files by
+default, but future versions should do so.
+
+
+Tips & Techniques
+-----------------
+
+Multiple Python Versions
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+EasyInstall installs itself under two names:
+``easy_install`` and ``easy_install-N.N``, where ``N.N`` is the Python version
+used to install it.  Thus, if you install EasyInstall for both Python 3.2 and
+2.7, you can use the ``easy_install-3.2`` or ``easy_install-2.7`` scripts to
+install packages for the respective Python version.
+
+Setuptools also supplies easy_install as a runnable module which may be
+invoked using ``python -m easy_install`` for any Python with Setuptools
+installed.
+
+Restricting Downloads with ``--allow-hosts``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can use the ``--allow-hosts`` (``-H``) option to restrict what domains
+EasyInstall will look for links and downloads on.  ``--allow-hosts=None``
+prevents downloading altogether.  You can also use wildcards, for example
+to restrict downloading to hosts in your own intranet.  See the section below
+on `Command-Line Options`_ for more details on the ``--allow-hosts`` option.
+
+By default, there are no host restrictions in effect, but you can change this
+default by editing the appropriate `configuration files`_ and adding:
+
+.. code-block:: ini
+
+    [easy_install]
+    allow_hosts = *.myintranet.example.com,*.python.org
+
+The above example would then allow downloads only from hosts in the
+``python.org`` and ``myintranet.example.com`` domains, unless overridden on the
+command line.
+
+
+Installing on Un-networked Machines
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Just copy the eggs or source packages you need to a directory on the target
+machine, then use the ``-f`` or ``--find-links`` option to specify that
+directory's location.  For example::
+
+    easy_install -H None -f somedir SomePackage
+
+will attempt to install SomePackage using only eggs and source packages found
+in ``somedir`` and disallowing all remote access.  You should of course make
+sure you have all of SomePackage's dependencies available in somedir.
+
+If you have another machine of the same operating system and library versions
+(or if the packages aren't platform-specific), you can create the directory of
+eggs using a command like this::
+
+    easy_install -zmaxd somedir SomePackage
+
+This will tell EasyInstall to put zipped eggs or source packages for
+SomePackage and all its dependencies into ``somedir``, without creating any
+scripts or .pth files.  You can then copy the contents of ``somedir`` to the
+target machine.  (``-z`` means zipped eggs, ``-m`` means multi-version, which
+prevents .pth files from being used, ``-a`` means to copy all the eggs needed,
+even if they're installed elsewhere on the machine, and ``-d`` indicates the
+directory to place the eggs in.)
+
+You can also build the eggs from local development packages that were installed
+with the ``setup.py develop`` command, by including the ``-l`` option, e.g.::
+
+    easy_install -zmaxld somedir SomePackage
+
+This will use locally-available source distributions to build the eggs.
+
+
+Packaging Others' Projects As Eggs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Need to distribute a package that isn't published in egg form?  You can use
+EasyInstall to build eggs for a project.  You'll want to use the ``--zip-ok``,
+``--exclude-scripts``, and possibly ``--no-deps`` options (``-z``, ``-x`` and
+``-N``, respectively).  Use ``-d`` or ``--install-dir`` to specify the location
+where you'd like the eggs placed.  By placing them in a directory that is
+published to the web, you can then make the eggs available for download, either
+in an intranet or to the internet at large.
+
+If someone distributes a package in the form of a single ``.py`` file, you can
+wrap it in an egg by tacking an ``#egg=name-version`` suffix on the file's URL.
+So, something like this::
+
+    easy_install -f "http://some.example.com/downloads/foo.py#egg=foo-1.0" foo
+
+will install the package as an egg, and this::
+
+    easy_install -zmaxd. \
+        -f "http://some.example.com/downloads/foo.py#egg=foo-1.0" foo
+
+will create a ``.egg`` file in the current directory.
+
+
+Creating your own Package Index
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In addition to local directories and the Python Package Index, EasyInstall can
+find download links on most any web page whose URL is given to the ``-f``
+(``--find-links``) option.  In the simplest case, you can simply have a web
+page with links to eggs or Python source packages, even an automatically
+generated directory listing (such as the Apache web server provides).
+
+If you are setting up an intranet site for package downloads, you may want to
+configure the target machines to use your download site by default, adding
+something like this to their `configuration files`_:
+
+.. code-block:: ini
+
+    [easy_install]
+    find_links = http://mypackages.example.com/somedir/
+                 http://turbogears.org/download/
+                 http://peak.telecommunity.com/dist/
+
+As you can see, you can list multiple URLs separated by whitespace, continuing
+on multiple lines if necessary (as long as the subsequent lines are indented.
+
+If you are more ambitious, you can also create an entirely custom package index
+or PyPI mirror.  See the ``--index-url`` option under `Command-Line Options`_,
+below, and also the section on `Package Index "API"`_.
+
+
+Password-Protected Sites
+------------------------
+
+If a site you want to download from is password-protected using HTTP "Basic"
+authentication, you can specify your credentials in the URL, like so::
+
+    http://some_userid:some_password@some.example.com/some_path/
+
+You can do this with both index page URLs and direct download URLs.  As long
+as any HTML pages read by easy_install use *relative* links to point to the
+downloads, the same user ID and password will be used to do the downloading.
+
+Using .pypirc Credentials
+-------------------------
+
+In additional to supplying credentials in the URL, ``easy_install`` will also
+honor credentials if present in the .pypirc file. Teams maintaining a private
+repository of packages may already have defined access credentials for
+uploading packages according to the distutils documentation. ``easy_install``
+will attempt to honor those if present. Refer to the distutils documentation
+for Python 2.5 or later for details on the syntax.
+
+Controlling Build Options
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+EasyInstall respects standard distutils `Configuration Files`_, so you can use
+them to configure build options for packages that it installs from source.  For
+example, if you are on Windows using the MinGW compiler, you can configure the
+default compiler by putting something like this:
+
+.. code-block:: ini
+
+    [build]
+    compiler = mingw32
+
+into the appropriate distutils configuration file.  In fact, since this is just
+normal distutils configuration, it will affect any builds using that config
+file, not just ones done by EasyInstall.  For example, if you add those lines
+to ``distutils.cfg`` in the ``distutils`` package directory, it will be the
+default compiler for *all* packages you build.  See `Configuration Files`_
+below for a list of the standard configuration file locations, and links to
+more documentation on using distutils configuration files.
+
+
+Editing and Viewing Source Packages
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Sometimes a package's source distribution  contains additional documentation,
+examples, configuration files, etc., that are not part of its actual code.  If
+you want to be able to examine these files, you can use the ``--editable``
+option to EasyInstall, and EasyInstall will look for a source distribution
+or Subversion URL for the package, then download and extract it or check it out
+as a subdirectory of the ``--build-directory`` you specify.  If you then wish
+to install the package after editing or configuring it, you can do so by
+rerunning EasyInstall with that directory as the target.
+
+Note that using ``--editable`` stops EasyInstall from actually building or
+installing the package; it just finds, obtains, and possibly unpacks it for
+you.  This allows you to make changes to the package if necessary, and to
+either install it in development mode using ``setup.py develop`` (if the
+package uses setuptools, that is), or by running ``easy_install projectdir``
+(where ``projectdir`` is the subdirectory EasyInstall created for the
+downloaded package.
+
+In order to use ``--editable`` (``-e`` for short), you *must* also supply a
+``--build-directory`` (``-b`` for short).  The project will be placed in a
+subdirectory of the build directory.  The subdirectory will have the same
+name as the project itself, but in all-lowercase.  If a file or directory of
+that name already exists, EasyInstall will print an error message and exit.
+
+Also, when using ``--editable``, you cannot use URLs or filenames as arguments.
+You *must* specify project names (and optional version requirements) so that
+EasyInstall knows what directory name(s) to create.  If you need to force
+EasyInstall to use a particular URL or filename, you should specify it as a
+``--find-links`` item (``-f`` for short), and then also specify
+the project name, e.g.::
+
+    easy_install -eb ~/projects \
+     -fhttp://prdownloads.sourceforge.net/ctypes/ctypes-0.9.6.tar.gz?download \
+     ctypes==0.9.6
+
+
+Dealing with Installation Conflicts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(NOTE: As of 0.6a11, this section is obsolete; it is retained here only so that
+people using older versions of EasyInstall can consult it.  As of version
+0.6a11, installation conflicts are handled automatically without deleting the
+old or system-installed packages, and without ignoring the issue.  Instead,
+eggs are automatically shifted to the front of ``sys.path`` using special
+code added to the ``easy-install.pth`` file.  So, if you are using version
+0.6a11 or better of setuptools, you do not need to worry about conflicts,
+and the following issues do not apply to you.)
+
+EasyInstall installs distributions in a "managed" way, such that each
+distribution can be independently activated or deactivated on ``sys.path``.
+However, packages that were not installed by EasyInstall are "unmanaged",
+in that they usually live all in one directory and cannot be independently
+activated or deactivated.
+
+As a result, if you are using EasyInstall to upgrade an existing package, or
+to install a package with the same name as an existing package, EasyInstall
+will warn you of the conflict.  (This is an improvement over ``setup.py
+install``, because the ``distutils`` just install new packages on top of old
+ones, possibly combining two unrelated packages or leaving behind modules that
+have been deleted in the newer version of the package.)
+
+EasyInstall will stop the installation if it detects a conflict
+between an existing, "unmanaged" package, and a module or package in any of
+the distributions you're installing.  It will display a list of all of the
+existing files and directories that would need to be deleted for the new
+package to be able to function correctly.  To proceed, you must manually
+delete these conflicting files and directories and re-run EasyInstall.
+
+Of course, once you've replaced all of your existing "unmanaged" packages with
+versions managed by EasyInstall, you won't have any more conflicts to worry
+about!
+
+
+Compressed Installation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+EasyInstall tries to install packages in zipped form, if it can.  Zipping
+packages can improve Python's overall import performance if you're not using
+the ``--multi-version`` option, because Python processes zipfile entries on
+``sys.path`` much faster than it does directories.
+
+As of version 0.5a9, EasyInstall analyzes packages to determine whether they
+can be safely installed as a zipfile, and then acts on its analysis.  (Previous
+versions would not install a package as a zipfile unless you used the
+``--zip-ok`` option.)
+
+The current analysis approach is fairly conservative; it currently looks for:
+
+ * Any use of the ``__file__`` or ``__path__`` variables (which should be
+   replaced with ``pkg_resources`` API calls)
+
+ * Possible use of ``inspect`` functions that expect to manipulate source files
+   (e.g. ``inspect.getsource()``)
+
+ * Top-level modules that might be scripts used with ``python -m`` (Python 2.4)
+
+If any of the above are found in the package being installed, EasyInstall will
+assume that the package cannot be safely run from a zipfile, and unzip it to
+a directory instead.  You can override this analysis with the ``-zip-ok`` flag,
+which will tell EasyInstall to install the package as a zipfile anyway.  Or,
+you can use the ``--always-unzip`` flag, in which case EasyInstall will always
+unzip, even if its analysis says the package is safe to run as a zipfile.
+
+Normally, however, it is simplest to let EasyInstall handle the determination
+of whether to zip or unzip, and only specify overrides when needed to work
+around a problem.  If you find you need to override EasyInstall's guesses, you
+may want to contact the package author and the EasyInstall maintainers, so that
+they can make appropriate changes in future versions.
+
+(Note: If a package uses ``setuptools`` in its setup script, the package author
+has the option to declare the package safe or unsafe for zipped usage via the
+``zip_safe`` argument to ``setup()``.  If the package author makes such a
+declaration, EasyInstall believes the package's author and does not perform its
+own analysis.  However, your command-line option, if any, will still override
+the package author's choice.)
+
+
+Reference Manual
+================
+
+Configuration Files
+-------------------
+
+(New in 0.4a2)
+
+You may specify default options for EasyInstall using the standard
+distutils configuration files, under the command heading ``easy_install``.
+EasyInstall will look first for a ``setup.cfg`` file in the current directory,
+then a ``~/.pydistutils.cfg`` or ``$HOME\\pydistutils.cfg`` (on Unix-like OSes
+and Windows, respectively), and finally a ``distutils.cfg`` file in the
+``distutils`` package directory.  Here's a simple example:
+
+.. code-block:: ini
+
+    [easy_install]
+
+    # set the default location to install packages
+    install_dir = /home/me/lib/python
+
+    # Notice that indentation can be used to continue an option
+    # value; this is especially useful for the "--find-links"
+    # option, which tells easy_install to use download links on
+    # these pages before consulting PyPI:
+    #
+    find_links = http://sqlobject.org/
+                 http://peak.telecommunity.com/dist/
+
+In addition to accepting configuration for its own options under
+``[easy_install]``, EasyInstall also respects defaults specified for other
+distutils commands.  For example, if you don't set an ``install_dir`` for
+``[easy_install]``, but *have* set an ``install_lib`` for the ``[install]``
+command, this will become EasyInstall's default installation directory.  Thus,
+if you are already using distutils configuration files to set default install
+locations, build options, etc., EasyInstall will respect your existing settings
+until and unless you override them explicitly in an ``[easy_install]`` section.
+
+For more information, see also the current Python documentation on the `use and
+location of distutils configuration files <https://docs.python.org/install/index.html#inst-config-files>`_.
+
+Notice that ``easy_install`` will use the ``setup.cfg`` from the current
+working directory only if it was triggered from ``setup.py`` through the
+``install_requires`` option. The standalone command will not use that file.
+
+Command-Line Options
+--------------------
+
+``--zip-ok, -z``
+    Install all packages as zip files, even if they are marked as unsafe for
+    running as a zipfile.  This can be useful when EasyInstall's analysis
+    of a non-setuptools package is too conservative, but keep in mind that
+    the package may not work correctly.  (Changed in 0.5a9; previously this
+    option was required in order for zipped installation to happen at all.)
+
+``--always-unzip, -Z``
+    Don't install any packages as zip files, even if the packages are marked
+    as safe for running as a zipfile.  This can be useful if a package does
+    something unsafe, but not in a way that EasyInstall can easily detect.
+    EasyInstall's default analysis is currently very conservative, however, so
+    you should only use this option if you've had problems with a particular
+    package, and *after* reporting the problem to the package's maintainer and
+    to the EasyInstall maintainers.
+
+    (Note: the ``-z/-Z`` options only affect the installation of newly-built
+    or downloaded packages that are not already installed in the target
+    directory; if you want to convert an existing installed version from
+    zipped to unzipped or vice versa, you'll need to delete the existing
+    version first, and re-run EasyInstall.)
+
+``--multi-version, -m``
+    "Multi-version" mode. Specifying this option prevents ``easy_install`` from
+    adding an ``easy-install.pth`` entry for the package being installed, and
+    if an entry for any version the package already exists, it will be removed
+    upon successful installation. In multi-version mode, no specific version of
+    the package is available for importing, unless you use
+    ``pkg_resources.require()`` to put it on ``sys.path``. This can be as
+    simple as::
+
+        from pkg_resources import require
+        require("SomePackage", "OtherPackage", "MyPackage")
+
+    which will put the latest installed version of the specified packages on
+    ``sys.path`` for you. (For more advanced uses, like selecting specific
+    versions and enabling optional dependencies, see the ``pkg_resources`` API
+    doc.)
+
+    Changed in 0.6a10: this option is no longer silently enabled when
+    installing to a non-PYTHONPATH, non-"site" directory.  You must always
+    explicitly use this option if you want it to be active.
+
+``--upgrade, -U``   (New in 0.5a4)
+    By default, EasyInstall only searches online if a project/version
+    requirement can't be met by distributions already installed
+    on sys.path or the installation directory.  However, if you supply the
+    ``--upgrade`` or ``-U`` flag, EasyInstall will always check the package
+    index and ``--find-links`` URLs before selecting a version to install.  In
+    this way, you can force EasyInstall to use the latest available version of
+    any package it installs (subject to any version requirements that might
+    exclude such later versions).
+
+``--install-dir=DIR, -d DIR``
+    Set the installation directory. It is up to you to ensure that this
+    directory is on ``sys.path`` at runtime, and to use
+    ``pkg_resources.require()`` to enable the installed package(s) that you
+    need.
+
+    (New in 0.4a2) If this option is not directly specified on the command line
+    or in a distutils configuration file, the distutils default installation
+    location is used.  Normally, this would be the ``site-packages`` directory,
+    but if you are using distutils configuration files, setting things like
+    ``prefix`` or ``install_lib``, then those settings are taken into
+    account when computing the default installation directory, as is the
+    ``--prefix`` option.
+
+``--script-dir=DIR, -s DIR``
+    Set the script installation directory.  If you don't supply this option
+    (via the command line or a configuration file), but you *have* supplied
+    an ``--install-dir`` (via command line or config file), then this option
+    defaults to the same directory, so that the scripts will be able to find
+    their associated package installation.  Otherwise, this setting defaults
+    to the location where the distutils would normally install scripts, taking
+    any distutils configuration file settings into account.
+
+``--exclude-scripts, -x``
+    Don't install scripts.  This is useful if you need to install multiple
+    versions of a package, but do not want to reset the version that will be
+    run by scripts that are already installed.
+
+``--user`` (New in 0.6.11)
+    Use the user-site-packages as specified in :pep:`370`
+    instead of the global site-packages.
+
+``--always-copy, -a``   (New in 0.5a4)
+    Copy all needed distributions to the installation directory, even if they
+    are already present in a directory on sys.path.  In older versions of
+    EasyInstall, this was the default behavior, but now you must explicitly
+    request it.  By default, EasyInstall will no longer copy such distributions
+    from other sys.path directories to the installation directory, unless you
+    explicitly gave the distribution's filename on the command line.
+
+    Note that as of 0.6a10, using this option excludes "system" and
+    "development" eggs from consideration because they can't be reliably
+    copied.  This may cause EasyInstall to choose an older version of a package
+    than what you expected, or it may cause downloading and installation of a
+    fresh copy of something that's already installed.  You will see warning
+    messages for any eggs that EasyInstall skips, before it falls back to an
+    older version or attempts to download a fresh copy.
+
+``--find-links=URLS_OR_FILENAMES, -f URLS_OR_FILENAMES``
+    Scan the specified "download pages" or directories for direct links to eggs
+    or other distributions.  Any existing file or directory names or direct
+    download URLs are immediately added to EasyInstall's search cache, and any
+    indirect URLs (ones that don't point to eggs or other recognized archive
+    formats) are added to a list of additional places to search for download
+    links.  As soon as EasyInstall has to go online to find a package (either
+    because it doesn't exist locally, or because ``--upgrade`` or ``-U`` was
+    used), the specified URLs will be downloaded and scanned for additional
+    direct links.
+
+    Eggs and archives found by way of ``--find-links`` are only downloaded if
+    they are needed to meet a requirement specified on the command line; links
+    to unneeded packages are ignored.
+
+    If all requested packages can be found using links on the specified
+    download pages, the Python Package Index will not be consulted unless you
+    also specified the ``--upgrade`` or ``-U`` option.
+
+    (Note: if you want to refer to a local HTML file containing links, you must
+    use a ``file:`` URL, as filenames that do not refer to a directory, egg, or
+    archive are ignored.)
+
+    You may specify multiple URLs or file/directory names with this option,
+    separated by whitespace.  Note that on the command line, you will probably
+    have to surround the URL list with quotes, so that it is recognized as a
+    single option value.  You can also specify URLs in a configuration file;
+    see `Configuration Files`_, above.
+
+    Changed in 0.6a10: previously all URLs and directories passed to this
+    option were scanned as early as possible, but from 0.6a10 on, only
+    directories and direct archive links are scanned immediately; URLs are not
+    retrieved unless a package search was already going to go online due to a
+    package not being available locally, or due to the use of the ``--update``
+    or ``-U`` option.
+
+``--no-find-links`` Blocks the addition of any link.
+    This parameter is useful if you want to avoid adding links defined in a
+    project easy_install is installing (whether it's a requested project or a
+    dependency). When used, ``--find-links`` is ignored.
+
+    Added in Distribute 0.6.11 and Setuptools 0.7.
+
+``--index-url=URL, -i URL`` (New in 0.4a1; default changed in 0.6c7)
+    Specifies the base URL of the Python Package Index.  The default is
+    https://pypi.python.org/simple if not specified.  When a package is requested
+    that is not locally available or linked from a ``--find-links`` download
+    page, the package index will be searched for download pages for the needed
+    package, and those download pages will be searched for links to download
+    an egg or source distribution.
+
+``--editable, -e`` (New in 0.6a1)
+    Only find and download source distributions for the specified projects,
+    unpacking them to subdirectories of the specified ``--build-directory``.
+    EasyInstall will not actually build or install the requested projects or
+    their dependencies; it will just find and extract them for you.  See
+    `Editing and Viewing Source Packages`_ above for more details.
+
+``--build-directory=DIR, -b DIR`` (UPDATED in 0.6a1)
+    Set the directory used to build source packages.  If a package is built
+    from a source distribution or checkout, it will be extracted to a
+    subdirectory of the specified directory.  The subdirectory will have the
+    same name as the extracted distribution's project, but in all-lowercase.
+    If a file or directory of that name already exists in the given directory,
+    a warning will be printed to the console, and the build will take place in
+    a temporary directory instead.
+
+    This option is most useful in combination with the ``--editable`` option,
+    which forces EasyInstall to *only* find and extract (but not build and
+    install) source distributions.  See `Editing and Viewing Source Packages`_,
+    above, for more information.
+
+``--verbose, -v, --quiet, -q`` (New in 0.4a4)
+    Control the level of detail of EasyInstall's progress messages.  The
+    default detail level is "info", which prints information only about
+    relatively time-consuming operations like running a setup script, unpacking
+    an archive, or retrieving a URL.  Using ``-q`` or ``--quiet`` drops the
+    detail level to "warn", which will only display installation reports,
+    warnings, and errors.  Using ``-v`` or ``--verbose`` increases the detail
+    level to include individual file-level operations, link analysis messages,
+    and distutils messages from any setup scripts that get run.  If you include
+    the ``-v`` option more than once, the second and subsequent uses are passed
+    down to any setup scripts, increasing the verbosity of their reporting as
+    well.
+
+``--dry-run, -n`` (New in 0.4a4)
+    Don't actually install the package or scripts.  This option is passed down
+    to any setup scripts run, so packages should not actually build either.
+    This does *not* skip downloading, nor does it skip extracting source
+    distributions to a temporary/build directory.
+
+``--optimize=LEVEL``, ``-O LEVEL`` (New in 0.4a4)
+    If you are installing from a source distribution, and are *not* using the
+    ``--zip-ok`` option, this option controls the optimization level for
+    compiling installed ``.py`` files to ``.pyo`` files.  It does not affect
+    the compilation of modules contained in ``.egg`` files, only those in
+    ``.egg`` directories.  The optimization level can be set to 0, 1, or 2;
+    the default is 0 (unless it's set under ``install`` or ``install_lib`` in
+    one of your distutils configuration files).
+
+``--record=FILENAME``  (New in 0.5a4)
+    Write a record of all installed files to FILENAME.  This is basically the
+    same as the same option for the standard distutils "install" command, and
+    is included for compatibility with tools that expect to pass this option
+    to "setup.py install".
+
+``--site-dirs=DIRLIST, -S DIRLIST``   (New in 0.6a1)
+    Specify one or more custom "site" directories (separated by commas).
+    "Site" directories are directories where ``.pth`` files are processed, such
+    as the main Python ``site-packages`` directory.  As of 0.6a10, EasyInstall
+    automatically detects whether a given directory processes ``.pth`` files
+    (or can be made to do so), so you should not normally need to use this
+    option.  It is is now only necessary if you want to override EasyInstall's
+    judgment and force an installation directory to be treated as if it
+    supported ``.pth`` files.
+
+``--no-deps, -N``  (New in 0.6a6)
+    Don't install any dependencies.  This is intended as a convenience for
+    tools that wrap eggs in a platform-specific packaging system.  (We don't
+    recommend that you use it for anything else.)
+
+``--allow-hosts=PATTERNS, -H PATTERNS``   (New in 0.6a6)
+    Restrict downloading and spidering to hosts matching the specified glob
+    patterns.  E.g. ``-H *.python.org`` restricts web access so that only
+    packages listed and downloadable from machines in the ``python.org``
+    domain.  The glob patterns must match the *entire* user/host/port section of
+    the target URL(s).  For example, ``*.python.org`` will NOT accept a URL
+    like ``http://python.org/foo`` or ``http://www.python.org:8080/``.
+    Multiple patterns can be specified by separating them with commas.  The
+    default pattern is ``*``, which matches anything.
+
+    In general, this option is mainly useful for blocking EasyInstall's web
+    access altogether (e.g. ``-Hlocalhost``), or to restrict it to an intranet
+    or other trusted site.  EasyInstall will do the best it can to satisfy
+    dependencies given your host restrictions, but of course can fail if it
+    can't find suitable packages.  EasyInstall displays all blocked URLs, so
+    that you can adjust your ``--allow-hosts`` setting if it is more strict
+    than you intended.  Some sites may wish to define a restrictive default
+    setting for this option in their `configuration files`_, and then manually
+    override the setting on the command line as needed.
+
+``--prefix=DIR`` (New in 0.6a10)
+    Use the specified directory as a base for computing the default
+    installation and script directories.  On Windows, the resulting default
+    directories will be ``prefix\\Lib\\site-packages`` and ``prefix\\Scripts``,
+    while on other platforms the defaults will be
+    ``prefix/lib/python2.X/site-packages`` (with the appropriate version
+    substituted) for libraries and ``prefix/bin`` for scripts.
+
+    Note that the ``--prefix`` option only sets the *default* installation and
+    script directories, and does not override the ones set on the command line
+    or in a configuration file.
+
+``--local-snapshots-ok, -l`` (New in 0.6c6)
+    Normally, EasyInstall prefers to only install *released* versions of
+    projects, not in-development ones, because such projects may not
+    have a currently-valid version number.  So, it usually only installs them
+    when their ``setup.py`` directory is explicitly passed on the command line.
+
+    However, if this option is used, then any in-development projects that were
+    installed using the ``setup.py develop`` command, will be used to build
+    eggs, effectively upgrading the "in-development" project to a snapshot
+    release.  Normally, this option is used only in conjunction with the
+    ``--always-copy`` option to create a distributable snapshot of every egg
+    needed to run an application.
+
+    Note that if you use this option, you must make sure that there is a valid
+    version number (such as an SVN revision number tag) for any in-development
+    projects that may be used, as otherwise EasyInstall may not be able to tell
+    what version of the project is "newer" when future installations or
+    upgrades are attempted.
+
+
+.. _non-root installation:
+
+Custom Installation Locations
+-----------------------------
+
+By default, EasyInstall installs python packages into Python's main ``site-packages`` directory,
+and manages them using a custom ``.pth`` file in that same directory.
+
+Very often though, a user or developer wants ``easy_install`` to install and manage python packages
+in an alternative location, usually for one of 3 reasons:
+
+1. They don't have access to write to the main Python site-packages directory.
+
+2. They want a user-specific stash of packages, that is not visible to other users.
+
+3. They want to isolate a set of packages to a specific python application, usually to minimize
+   the possibility of version conflicts.
+
+Historically, there have been many approaches to achieve custom installation.
+The following section lists only the easiest and most relevant approaches [1]_.
+
+`Use the "--user" option`_
+
+`Use the "--user" option and customize "PYTHONUSERBASE"`_
+
+`Use "virtualenv"`_
+
+.. [1] There are older ways to achieve custom installation using various ``easy_install`` and ``setup.py install`` options, combined with ``PYTHONPATH`` and/or ``PYTHONUSERBASE`` alterations, but all of these are effectively deprecated by the User scheme brought in by `PEP-370`_.
+
+.. _PEP-370: http://www.python.org/dev/peps/pep-0370/
+
+
+Use the "--user" option
+~~~~~~~~~~~~~~~~~~~~~~~
+Python provides a User scheme for installation, which means that all
+python distributions support an alternative install location that is specific to a user [3]_.
+The Default location for each OS is explained in the python documentation
+for the ``site.USER_BASE`` variable.  This mode of installation can be turned on by
+specifying the ``--user`` option to ``setup.py install`` or ``easy_install``.
+This approach serves the need to have a user-specific stash of packages.
+
+.. [3] Prior to the User scheme, there was the Home scheme, which is still available, but requires more effort than the User scheme to get packages recognized.
+
+Use the "--user" option and customize "PYTHONUSERBASE"
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The User scheme install location can be customized by setting the ``PYTHONUSERBASE`` environment
+variable, which updates the value of ``site.USER_BASE``.  To isolate packages to a specific
+application, simply set the OS environment of that application to a specific value of
+``PYTHONUSERBASE``, that contains just those packages.
+
+Use "virtualenv"
+~~~~~~~~~~~~~~~~
+"virtualenv" is a 3rd-party python package that effectively "clones" a python installation, thereby
+creating an isolated location to install packages.  The evolution of "virtualenv" started before the existence
+of the User installation scheme.  "virtualenv" provides a version of ``easy_install`` that is
+scoped to the cloned python install and is used in the normal way. "virtualenv" does offer various features
+that the User installation scheme alone does not provide, e.g. the ability to hide the main python site-packages.
+
+Please refer to the `virtualenv`_ documentation for more details.
+
+.. _virtualenv: https://pypi.python.org/pypi/virtualenv
+
+
+
+Package Index "API"
+-------------------
+
+Custom package indexes (and PyPI) must follow the following rules for
+EasyInstall to be able to look up and download packages:
+
+1. Except where stated otherwise, "pages" are HTML or XHTML, and "links"
+   refer to ``href`` attributes.
+
+2. Individual project version pages' URLs must be of the form
+   ``base/projectname/version``, where ``base`` is the package index's base URL.
+
+3. Omitting the ``/version`` part of a project page's URL (but keeping the
+   trailing ``/``) should result in a page that is either:
+
+   a) The single active version of that project, as though the version had been
+      explicitly included, OR
+
+   b) A page with links to all of the active version pages for that project.
+
+4. Individual project version pages should contain direct links to downloadable
+   distributions where possible.  It is explicitly permitted for a project's
+   "long_description" to include URLs, and these should be formatted as HTML
+   links by the package index, as EasyInstall does no special processing to
+   identify what parts of a page are index-specific and which are part of the
+   project's supplied description.
+
+5. Where available, MD5 information should be added to download URLs by
+   appending a fragment identifier of the form ``#md5=...``, where ``...`` is
+   the 32-character hex MD5 digest.  EasyInstall will verify that the
+   downloaded file's MD5 digest matches the given value.
+
+6. Individual project version pages should identify any "homepage" or
+   "download" URLs using ``rel="homepage"`` and ``rel="download"`` attributes
+   on the HTML elements linking to those URLs. Use of these attributes will
+   cause EasyInstall to always follow the provided links, unless it can be
+   determined by inspection that they are downloadable distributions. If the
+   links are not to downloadable distributions, they are retrieved, and if they
+   are HTML, they are scanned for download links. They are *not* scanned for
+   additional "homepage" or "download" links, as these are only processed for
+   pages that are part of a package index site.
+
+7. The root URL of the index, if retrieved with a trailing ``/``, must result
+   in a page containing links to *all* projects' active version pages.
+
+   (Note: This requirement is a workaround for the absence of case-insensitive
+   ``safe_name()`` matching of project names in URL paths. If project names are
+   matched in this fashion (e.g. via the PyPI server, mod_rewrite, or a similar
+   mechanism), then it is not necessary to include this all-packages listing
+   page.)
+
+8. If a package index is accessed via a ``file://`` URL, then EasyInstall will
+   automatically use ``index.html`` files, if present, when trying to read a
+   directory with a trailing ``/`` on the URL.
+
+
+Backward Compatibility
+~~~~~~~~~~~~~~~~~~~~~~
+
+Package indexes that wish to support setuptools versions prior to 0.6b4 should
+also follow these rules:
+
+* Homepage and download links must be preceded with ``"<th>Home Page"`` or
+  ``"<th>Download URL"``, in addition to (or instead of) the ``rel=""``
+  attributes on the actual links.  These marker strings do not need to be
+  visible, or uncommented, however!  For example, the following is a valid
+  homepage link that will work with any version of setuptools::
+
+    <li>
+     <strong>Home Page:</strong>
+     <!-- <th>Home Page -->
+     <a rel="homepage" href="http://sqlobject.org">http://sqlobject.org</a>
+    </li>
+
+  Even though the marker string is in an HTML comment, older versions of
+  EasyInstall will still "see" it and know that the link that follows is the
+  project's home page URL.
+
+* The pages described by paragraph 3(b) of the preceding section *must*
+  contain the string ``"Index of Packages</title>"`` somewhere in their text.
+  This can be inside of an HTML comment, if desired, and it can be anywhere
+  in the page.  (Note: this string MUST NOT appear on normal project pages, as
+  described in paragraphs 2 and 3(a)!)
+
+In addition, for compatibility with PyPI versions that do not use ``#md5=``
+fragment IDs, EasyInstall uses the following regular expression to match PyPI's
+displayed MD5 info (broken onto two lines for readability)::
+
+    <a href="([^"#]+)">([^<]+)</a>\n\s+\(<a href="[^?]+\?:action=show_md5
+    &amp;digest=([0-9a-f]{32})">md5</a>\)
+
+History
+=======
+
+0.6c9
+ * Fixed ``win32.exe`` support for .pth files, so unnecessary directory nesting
+   is flattened out in the resulting egg.  (There was a case-sensitivity
+   problem that affected some distributions, notably ``pywin32``.)
+
+ * Prevent ``--help-commands`` and other junk from showing under Python 2.5
+   when running ``easy_install --help``.
+
+ * Fixed GUI scripts sometimes not executing on Windows
+
+ * Fixed not picking up dependency links from recursive dependencies.
+
+ * Only make ``.py``, ``.dll`` and ``.so`` files executable when unpacking eggs
+
+ * Changes for Jython compatibility
+
+ * Improved error message when a requirement is also a directory name, but the
+   specified directory is not a source package.
+
+ * Fixed ``--allow-hosts`` option blocking ``file:`` URLs
+
+ * Fixed HTTP SVN detection failing when the page title included a project
+   name (e.g. on SourceForge-hosted SVN)
+
+ * Fix Jython script installation to handle ``#!`` lines better when
+   ``sys.executable`` is a script.
+
+ * Removed use of deprecated ``md5`` module if ``hashlib`` is available
+
+ * Keep site directories (e.g. ``site-packages``) from being included in
+   ``.pth`` files.
+
+0.6c7
+ * ``ftp:`` download URLs now work correctly.
+
+ * The default ``--index-url`` is now ``https://pypi.python.org/simple``, to use
+   the Python Package Index's new simpler (and faster!) REST API.
+
+0.6c6
+ * EasyInstall no longer aborts the installation process if a URL it wants to
+   retrieve can't be downloaded, unless the URL is an actual package download.
+   Instead, it issues a warning and tries to keep going.
+
+ * Fixed distutils-style scripts originally built on Windows having their line
+   endings doubled when installed on any platform.
+
+ * Added ``--local-snapshots-ok`` flag, to allow building eggs from projects
+   installed using ``setup.py develop``.
+
+ * Fixed not HTML-decoding URLs scraped from web pages
+
+0.6c5
+ * Fixed ``.dll`` files on Cygwin not having executable permissions when an egg
+   is installed unzipped.
+
+0.6c4
+ * Added support for HTTP "Basic" authentication using ``http://user:pass@host``
+   URLs.  If a password-protected page contains links to the same host (and
+   protocol), those links will inherit the credentials used to access the
+   original page.
+
+ * Removed all special support for Sourceforge mirrors, as Sourceforge's
+   mirror system now works well for non-browser downloads.
+
+ * Fixed not recognizing ``win32.exe`` installers that included a custom
+   bitmap.
+
+ * Fixed not allowing ``os.open()`` of paths outside the sandbox, even if they
+   are opened read-only (e.g. reading ``/dev/urandom`` for random numbers, as
+   is done by ``os.urandom()`` on some platforms).
+
+ * Fixed a problem with ``.pth`` testing on Windows when ``sys.executable``
+   has a space in it (e.g., the user installed Python to a ``Program Files``
+   directory).
+
+0.6c3
+ * You can once again use "python -m easy_install" with Python 2.4 and above.
+
+ * Python 2.5 compatibility fixes added.
+
+0.6c2
+ * Windows script wrappers now support quoted arguments and arguments
+   containing spaces.  (Patch contributed by Jim Fulton.)
+
+ * The ``ez_setup.py`` script now actually works when you put a setuptools
+   ``.egg`` alongside it for bootstrapping an offline machine.
+
+ * A writable installation directory on ``sys.path`` is no longer required to
+   download and extract a source distribution using ``--editable``.
+
+ * Generated scripts now use ``-x`` on the ``#!`` line when ``sys.executable``
+   contains non-ASCII characters, to prevent deprecation warnings about an
+   unspecified encoding when the script is run.
+
+0.6c1
+ * EasyInstall now includes setuptools version information in the
+   ``User-Agent`` string sent to websites it visits.
+
+0.6b4
+ * Fix creating Python wrappers for non-Python scripts
+
+ * Fix ``ftp://`` directory listing URLs from causing a crash when used in the
+   "Home page" or "Download URL" slots on PyPI.
+
+ * Fix ``sys.path_importer_cache`` not being updated when an existing zipfile
+   or directory is deleted/overwritten.
+
+ * Fix not recognizing HTML 404 pages from package indexes.
+
+ * Allow ``file://`` URLs to be used as a package index.  URLs that refer to
+   directories will use an internally-generated directory listing if there is
+   no ``index.html`` file in the directory.
+
+ * Allow external links in a package index to be specified using
+   ``rel="homepage"`` or ``rel="download"``, without needing the old
+   PyPI-specific visible markup.
+
+ * Suppressed warning message about possibly-misspelled project name, if an egg
+   or link for that project name has already been seen.
+
+0.6b3
+ * Fix local ``--find-links`` eggs not being copied except with
+   ``--always-copy``.
+
+ * Fix sometimes not detecting local packages installed outside of "site"
+   directories.
+
+ * Fix mysterious errors during initial ``setuptools`` install, caused by
+   ``ez_setup`` trying to run ``easy_install`` twice, due to a code fallthru
+   after deleting the egg from which it's running.
+
+0.6b2
+ * Don't install or update a ``site.py`` patch when installing to a
+   ``PYTHONPATH`` directory with ``--multi-version``, unless an
+   ``easy-install.pth`` file is already in use there.
+
+ * Construct ``.pth`` file paths in such a way that installing an egg whose
+   name begins with ``import`` doesn't cause a syntax error.
+
+ * Fixed a bogus warning message that wasn't updated since the 0.5 versions.
+
+0.6b1
+ * Better ambiguity management: accept ``#egg`` name/version even if processing
+   what appears to be a correctly-named distutils file, and ignore ``.egg``
+   files with no ``-``, since valid Python ``.egg`` files always have a version
+   number (but Scheme eggs often don't).
+
+ * Support ``file://`` links to directories in ``--find-links``, so that
+   easy_install can build packages from local source checkouts.
+
+ * Added automatic retry for Sourceforge mirrors.  The new download process is
+   to first just try dl.sourceforge.net, then randomly select mirror IPs and
+   remove ones that fail, until something works.  The removed IPs stay removed
+   for the remainder of the run.
+
+ * Ignore bdist_dumb distributions when looking at download URLs.
+
+0.6a11
+ * Process ``dependency_links.txt`` if found in a distribution, by adding the
+   URLs to the list for scanning.
+
+ * Use relative paths in ``.pth`` files when eggs are being installed to the
+   same directory as the ``.pth`` file.  This maximizes portability of the
+   target directory when building applications that contain eggs.
+
+ * Added ``easy_install-N.N`` script(s) for convenience when using multiple
+   Python versions.
+
+ * Added automatic handling of installation conflicts.  Eggs are now shifted to
+   the front of sys.path, in an order consistent with where they came from,
+   making EasyInstall seamlessly co-operate with system package managers.
+
+   The ``--delete-conflicting`` and ``--ignore-conflicts-at-my-risk`` options
+   are now no longer necessary, and will generate warnings at the end of a
+   run if you use them.
+
+ * Don't recursively traverse subdirectories given to ``--find-links``.
+
+0.6a10
+ * Added exhaustive testing of the install directory, including a spawn test
+   for ``.pth`` file support, and directory writability/existence checks.  This
+   should virtually eliminate the need to set or configure ``--site-dirs``.
+
+ * Added ``--prefix`` option for more do-what-I-mean-ishness in the absence of
+   RTFM-ing.  :)
+
+ * Enhanced ``PYTHONPATH`` support so that you don't have to put any eggs on it
+   manually to make it work.  ``--multi-version`` is no longer a silent
+   default; you must explicitly use it if installing to a non-PYTHONPATH,
+   non-"site" directory.
+
+ * Expand ``$variables`` used in the ``--site-dirs``, ``--build-directory``,
+   ``--install-dir``, and ``--script-dir`` options, whether on the command line
+   or in configuration files.
+
+ * Improved SourceForge mirror processing to work faster and be less affected
+   by transient HTML changes made by SourceForge.
+
+ * PyPI searches now use the exact spelling of requirements specified on the
+   command line or in a project's ``install_requires``.  Previously, a
+   normalized form of the name was used, which could lead to unnecessary
+   full-index searches when a project's name had an underscore (``_``) in it.
+
+ * EasyInstall can now download bare ``.py`` files and wrap them in an egg,
+   as long as you include an ``#egg=name-version`` suffix on the URL, or if
+   the ``.py`` file is listed as the "Download URL" on the project's PyPI page.
+   This allows third parties to "package" trivial Python modules just by
+   linking to them (e.g. from within their own PyPI page or download links
+   page).
+
+ * The ``--always-copy`` option now skips "system" and "development" eggs since
+   they can't be reliably copied.  Note that this may cause EasyInstall to
+   choose an older version of a package than what you expected, or it may cause
+   downloading and installation of a fresh version of what's already installed.
+
+ * The ``--find-links`` option previously scanned all supplied URLs and
+   directories as early as possible, but now only directories and direct
+   archive links are scanned immediately.  URLs are not retrieved unless a
+   package search was already going to go online due to a package not being
+   available locally, or due to the use of the ``--update`` or ``-U`` option.
+
+ * Fixed the annoying ``--help-commands`` wart.
+
+0.6a9
+ * Fixed ``.pth`` file processing picking up nested eggs (i.e. ones inside
+   "baskets") when they weren't explicitly listed in the ``.pth`` file.
+
+ * If more than one URL appears to describe the exact same distribution, prefer
+   the shortest one.  This helps to avoid "table of contents" CGI URLs like the
+   ones on effbot.org.
+
+ * Quote arguments to python.exe (including python's path) to avoid problems
+   when Python (or a script) is installed in a directory whose name contains
+   spaces on Windows.
+
+ * Support full roundtrip translation of eggs to and from ``bdist_wininst``
+   format.  Running ``bdist_wininst`` on a setuptools-based package wraps the
+   egg in an .exe that will safely install it as an egg (i.e., with metadata
+   and entry-point wrapper scripts), and ``easy_install`` can turn the .exe
+   back into an ``.egg`` file or directory and install it as such.
+
+0.6a8
+ * Update for changed SourceForge mirror format
+
+ * Fixed not installing dependencies for some packages fetched via Subversion
+
+ * Fixed dependency installation with ``--always-copy`` not using the same
+   dependency resolution procedure as other operations.
+
+ * Fixed not fully removing temporary directories on Windows, if a Subversion
+   checkout left read-only files behind
+
+ * Fixed some problems building extensions when Pyrex was installed, especially
+   with Python 2.4 and/or packages using SWIG.
+
+0.6a7
+ * Fixed not being able to install Windows script wrappers using Python 2.3
+
+0.6a6
+ * Added support for "traditional" PYTHONPATH-based non-root installation, and
+   also the convenient ``virtual-python.py`` script, based on a contribution
+   by Ian Bicking.  The setuptools egg now contains a hacked ``site`` module
+   that makes the PYTHONPATH-based approach work with .pth files, so that you
+   can get the full EasyInstall feature set on such installations.
+
+ * Added ``--no-deps`` and ``--allow-hosts`` options.
+
+ * Improved Windows ``.exe`` script wrappers so that the script can have the
+   same name as a module without confusing Python.
+
+ * Changed dependency processing so that it's breadth-first, allowing a
+   depender's preferences to override those of a dependee, to prevent conflicts
+   when a lower version is acceptable to the dependee, but not the depender.
+   Also, ensure that currently installed/selected packages aren't given
+   precedence over ones desired by a package being installed, which could
+   cause conflict errors.
+
+0.6a3
+ * Improved error message when trying to use old ways of running
+   ``easy_install``.  Removed the ability to run via ``python -m`` or by
+   running ``easy_install.py``; ``easy_install`` is the command to run on all
+   supported platforms.
+
+ * Improved wrapper script generation and runtime initialization so that a
+   VersionConflict doesn't occur if you later install a competing version of a
+   needed package as the default version of that package.
+
+ * Fixed a problem parsing version numbers in ``#egg=`` links.
+
+0.6a2
+ * EasyInstall can now install "console_scripts" defined by packages that use
+   ``setuptools`` and define appropriate entry points.  On Windows, console
+   scripts get an ``.exe`` wrapper so you can just type their name.  On other
+   platforms, the scripts are installed without a file extension.
+
+ * Using ``python -m easy_install`` or running ``easy_install.py`` is now
+   DEPRECATED, since an ``easy_install`` wrapper is now available on all
+   platforms.
+
+0.6a1
+ * EasyInstall now does MD5 validation of downloads from PyPI, or from any link
+   that has an "#md5=..." trailer with a 32-digit lowercase hex md5 digest.
+
+ * EasyInstall now handles symlinks in target directories by removing the link,
+   rather than attempting to overwrite the link's destination.  This makes it
+   easier to set up an alternate Python "home" directory (as described above in
+   the `Non-Root Installation`_ section).
+
+ * Added support for handling MacOS platform information in ``.egg`` filenames,
+   based on a contribution by Kevin Dangoor.  You may wish to delete and
+   reinstall any eggs whose filename includes "darwin" and "Power_Macintosh",
+   because the format for this platform information has changed so that minor
+   OS X upgrades (such as 10.4.1 to 10.4.2) do not cause eggs built with a
+   previous OS version to become obsolete.
+
+ * easy_install's dependency processing algorithms have changed.  When using
+   ``--always-copy``, it now ensures that dependencies are copied too.  When
+   not using ``--always-copy``, it tries to use a single resolution loop,
+   rather than recursing.
+
+ * Fixed installing extra ``.pyc`` or ``.pyo`` files for scripts with ``.py``
+   extensions.
+
+ * Added ``--site-dirs`` option to allow adding custom "site" directories.
+   Made ``easy-install.pth`` work in platform-specific alternate site
+   directories (e.g. ``~/Library/Python/2.x/site-packages`` on Mac OS X).
+
+ * If you manually delete the current version of a package, the next run of
+   EasyInstall against the target directory will now remove the stray entry
+   from the ``easy-install.pth`` file.
+
+ * EasyInstall now recognizes URLs with a ``#egg=project_name`` fragment ID
+   as pointing to the named project's source checkout.  Such URLs have a lower
+   match precedence than any other kind of distribution, so they'll only be
+   used if they have a higher version number than any other available
+   distribution, or if you use the ``--editable`` option.  The ``#egg``
+   fragment can contain a version if it's formatted as ``#egg=proj-ver``,
+   where ``proj`` is the project name, and ``ver`` is the version number.  You
+   *must* use the format for these values that the ``bdist_egg`` command uses;
+   i.e., all non-alphanumeric runs must be condensed to single underscore
+   characters.
+
+ * Added the ``--editable`` option; see `Editing and Viewing Source Packages`_
+   above for more info.  Also, slightly changed the behavior of the
+   ``--build-directory`` option.
+
+ * Fixed the setup script sandbox facility not recognizing certain paths as
+   valid on case-insensitive platforms.
+
+0.5a12
+ * Fix ``python -m easy_install`` not working due to setuptools being installed
+   as a zipfile.  Update safety scanner to check for modules that might be used
+   as ``python -m`` scripts.
+
+ * Misc. fixes for win32.exe support, including changes to support Python 2.4's
+   changed ``bdist_wininst`` format.
+
+0.5a10
+ * Put the ``easy_install`` module back in as a module, as it's needed for
+   ``python -m`` to run it!
+
+ * Allow ``--find-links/-f`` to accept local directories or filenames as well
+   as URLs.
+
+0.5a9
+ * EasyInstall now automatically detects when an "unmanaged" package or
+   module is going to be on ``sys.path`` ahead of a package you're installing,
+   thereby preventing the newer version from being imported.  By default, it
+   will abort installation to alert you of the problem, but there are also
+   new options (``--delete-conflicting`` and ``--ignore-conflicts-at-my-risk``)
+   available to change the default behavior.  (Note: this new feature doesn't
+   take effect for egg files that were built with older ``setuptools``
+   versions, because they lack the new metadata file required to implement it.)
+
+ * The ``easy_install`` distutils command now uses ``DistutilsError`` as its
+   base error type for errors that should just issue a message to stderr and
+   exit the program without a traceback.
+
+ * EasyInstall can now be given a path to a directory containing a setup
+   script, and it will attempt to build and install the package there.
+
+ * EasyInstall now performs a safety analysis on module contents to determine
+   whether a package is likely to run in zipped form, and displays
+   information about what modules may be doing introspection that would break
+   when running as a zipfile.
+
+ * Added the ``--always-unzip/-Z`` option, to force unzipping of packages that
+   would ordinarily be considered safe to unzip, and changed the meaning of
+   ``--zip-ok/-z`` to "always leave everything zipped".
+
+0.5a8
+ * There is now a separate documentation page for `setuptools`_; revision
+   history that's not specific to EasyInstall has been moved to that page.
+
+ .. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools
+
+0.5a5
+ * Made ``easy_install`` a standard ``setuptools`` command, moving it from
+   the ``easy_install`` module to ``setuptools.command.easy_install``.  Note
+   that if you were importing or extending it, you must now change your imports
+   accordingly.  ``easy_install.py`` is still installed as a script, but not as
+   a module.
+
+0.5a4
+ * Added ``--always-copy/-a`` option to always copy needed packages to the
+   installation directory, even if they're already present elsewhere on
+   sys.path. (In previous versions, this was the default behavior, but now
+   you must request it.)
+
+ * Added ``--upgrade/-U`` option to force checking PyPI for latest available
+   version(s) of all packages requested by name and version, even if a matching
+   version is available locally.
+
+ * Added automatic installation of dependencies declared by a distribution
+   being installed.  These dependencies must be listed in the distribution's
+   ``EGG-INFO`` directory, so the distribution has to have declared its
+   dependencies by using setuptools.  If a package has requirements it didn't
+   declare, you'll still have to deal with them yourself.  (E.g., by asking
+   EasyInstall to find and install them.)
+
+ * Added the ``--record`` option to ``easy_install`` for the benefit of tools
+   that run ``setup.py install --record=filename`` on behalf of another
+   packaging system.)
+
+0.5a3
+ * Fixed not setting script permissions to allow execution.
+
+ * Improved sandboxing so that setup scripts that want a temporary directory
+   (e.g. pychecker) can still run in the sandbox.
+
+0.5a2
+ * Fix stupid stupid refactoring-at-the-last-minute typos.  :(
+
+0.5a1
+ * Added support for converting ``.win32.exe`` installers to eggs on the fly.
+   EasyInstall will now recognize such files by name and install them.
+
+ * Fixed a problem with picking the "best" version to install (versions were
+   being sorted as strings, rather than as parsed values)
+
+0.4a4
+ * Added support for the distutils "verbose/quiet" and "dry-run" options, as
+   well as the "optimize" flag.
+
+ * Support downloading packages that were uploaded to PyPI (by scanning all
+   links on package pages, not just the homepage/download links).
+
+0.4a3
+ * Add progress messages to the search/download process so that you can tell
+   what URLs it's reading to find download links.  (Hopefully, this will help
+   people report out-of-date and broken links to package authors, and to tell
+   when they've asked for a package that doesn't exist.)
+
+0.4a2
+ * Added support for installing scripts
+
+ * Added support for setting options via distutils configuration files, and
+   using distutils' default options as a basis for EasyInstall's defaults.
+
+ * Renamed ``--scan-url/-s`` to ``--find-links/-f`` to free up ``-s`` for the
+   script installation directory option.
+
+ * Use ``urllib2`` instead of ``urllib``, to allow use of ``https:`` URLs if
+   Python includes SSL support.
+
+0.4a1
+ * Added ``--scan-url`` and ``--index-url`` options, to scan download pages
+   and search PyPI for needed packages.
+
+0.3a4
+ * Restrict ``--build-directory=DIR/-b DIR`` option to only be used with single
+   URL installs, to avoid running the wrong setup.py.
+
+0.3a3
+ * Added ``--build-directory=DIR/-b DIR`` option.
+
+ * Added "installation report" that explains how to use 'require()' when doing
+   a multiversion install or alternate installation directory.
+
+ * Added SourceForge mirror auto-select (Contributed by Ian Bicking)
+
+ * Added "sandboxing" that stops a setup script from running if it attempts to
+   write to the filesystem outside of the build area
+
+ * Added more workarounds for packages with quirky ``install_data`` hacks
+
+0.3a2
+ * Added subversion download support for ``svn:`` and ``svn+`` URLs, as well as
+   automatic recognition of HTTP subversion URLs (Contributed by Ian Bicking)
+
+ * Misc. bug fixes
+
+0.3a1
+ * Initial release.
+
+
+Future Plans
+============
+
+* Additional utilities to list/remove/verify packages
+* Signature checking?  SSL?  Ability to suppress PyPI search?
+* Display byte progress meter when downloading distributions and long pages?
+* Redirect stdout/stderr to log during run_setup?
+
diff --git a/vendor/setuptools-39.0.1/docs/formats.txt b/vendor/setuptools-39.0.1/docs/formats.txt
new file mode 100644
index 00000000..a182eb99
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/formats.txt
@@ -0,0 +1,682 @@
+=====================================
+The Internal Structure of Python Eggs
+=====================================
+
+STOP! This is not the first document you should read!
+
+
+
+.. contents:: **Table of Contents**
+
+
+----------------------
+Eggs and their Formats
+----------------------
+
+A "Python egg" is a logical structure embodying the release of a
+specific version of a Python project, comprising its code, resources,
+and metadata. There are multiple formats that can be used to physically
+encode a Python egg, and others can be developed. However, a key
+principle of Python eggs is that they should be discoverable and
+importable. That is, it should be possible for a Python application to
+easily and efficiently find out what eggs are present on a system, and
+to ensure that the desired eggs' contents are importable.
+
+There are two basic formats currently implemented for Python eggs:
+
+1. ``.egg`` format: a directory or zipfile *containing* the project's
+   code and resources, along with an ``EGG-INFO`` subdirectory that
+   contains the project's metadata
+
+2. ``.egg-info`` format: a file or directory placed *adjacent* to the
+   project's code and resources, that directly contains the project's
+   metadata.
+
+Both formats can include arbitrary Python code and resources, including
+static data files, package and non-package directories, Python
+modules, C extension modules, and so on.  But each format is optimized
+for different purposes.
+
+The ``.egg`` format is well-suited to distribution and the easy
+uninstallation or upgrades of code, since the project is essentially
+self-contained within a single directory or file, unmingled with any
+other projects' code or resources.  It also makes it possible to have
+multiple versions of a project simultaneously installed, such that
+individual programs can select the versions they wish to use.
+
+The ``.egg-info`` format, on the other hand, was created to support
+backward-compatibility, performance, and ease of installation for system
+packaging tools that expect to install all projects' code and resources
+to a single directory (e.g. ``site-packages``).  Placing the metadata
+in that same directory simplifies the installation process, since it
+isn't necessary to create ``.pth`` files or otherwise modify
+``sys.path`` to include each installed egg.
+
+Its disadvantage, however, is that it provides no support for clean
+uninstallation or upgrades, and of course only a single version of a
+project can be installed to a given directory. Thus, support from a
+package management tool is required. (This is why setuptools' "install"
+command refers to this type of egg installation as "single-version,
+externally managed".)  Also, they lack sufficient data to allow them to
+be copied from their installation source.  easy_install can "ship" an
+application by copying ``.egg`` files or directories to a target
+location, but it cannot do this for ``.egg-info`` installs, because
+there is no way to tell what code and resources belong to a particular
+egg -- there may be several eggs "scrambled" together in a single
+installation location, and the ``.egg-info`` format does not currently
+include a way to list the files that were installed.  (This may change
+in a future version.)
+
+
+Code and Resources
+==================
+
+The layout of the code and resources is dictated by Python's normal
+import layout, relative to the egg's "base location".
+
+For the ``.egg`` format, the base location is the ``.egg`` itself. That
+is, adding the ``.egg`` filename or directory name to ``sys.path``
+makes its contents importable.
+
+For the ``.egg-info`` format, however, the base location is the
+directory that *contains* the ``.egg-info``, and thus it is the
+directory that must be added to ``sys.path`` to make the egg importable.
+(Note that this means that the "normal" installation of a package to a
+``sys.path`` directory is sufficient to make it an "egg" if it has an
+``.egg-info`` file or directory installed alongside of it.)
+
+
+Project Metadata
+=================
+
+If eggs contained only code and resources, there would of course be
+no difference between them and any other directory or zip file on
+``sys.path``.  Thus, metadata must also be included, using a metadata
+file or directory.
+
+For the ``.egg`` format, the metadata is placed in an ``EGG-INFO``
+subdirectory, directly within the ``.egg`` file or directory.  For the
+``.egg-info`` format, metadata is stored directly within the
+``.egg-info`` directory itself.
+
+The minimum project metadata that all eggs must have is a standard
+Python ``PKG-INFO`` file, named ``PKG-INFO`` and placed within the
+metadata directory appropriate to the format.  Because it's possible for
+this to be the only metadata file included, ``.egg-info`` format eggs
+are not required to be a directory; they can just be a ``.egg-info``
+file that directly contains the ``PKG-INFO`` metadata.  This eliminates
+the need to create a directory just to store one file.  This option is
+*not* available for ``.egg`` formats, since setuptools always includes
+other metadata.  (In fact, setuptools itself never generates
+``.egg-info`` files, either; the support for using files was added so
+that the requirement could easily be satisfied by other tools, such
+as distutils).
+
+In addition to the ``PKG-INFO`` file, an egg's metadata directory may
+also include files and directories representing various forms of
+optional standard metadata (see the section on `Standard Metadata`_,
+below) or user-defined metadata required by the project.  For example,
+some projects may define a metadata format to describe their application
+plugins, and metadata in this format would then be included by plugin
+creators in their projects' metadata directories.
+
+
+Filename-Embedded Metadata
+==========================
+
+To allow introspection of installed projects and runtime resolution of
+inter-project dependencies, a certain amount of information is embedded
+in egg filenames.  At a minimum, this includes the project name, and
+ideally will also include the project version number.  Optionally, it
+can also include the target Python version and required runtime
+platform if platform-specific C code is included.  The syntax of an
+egg filename is as follows::
+
+    name ["-" version ["-py" pyver ["-" required_platform]]] "." ext
+
+The "name" and "version" should be escaped using the ``to_filename()``
+function provided by ``pkg_resources``, after first processing them with
+``safe_name()`` and ``safe_version()`` respectively.  These latter two
+functions can also be used to later "unescape" these parts of the
+filename.  (For a detailed description of these transformations, please
+see the "Parsing Utilities" section of the ``pkg_resources`` manual.)
+
+The "pyver" string is the Python major version, as found in the first
+3 characters of ``sys.version``.  "required_platform" is essentially
+a distutils ``get_platform()`` string, but with enhancements to properly
+distinguish Mac OS versions.  (See the ``get_build_platform()``
+documentation in the "Platform Utilities" section of the
+``pkg_resources`` manual for more details.)
+
+Finally, the "ext" is either ``.egg`` or ``.egg-info``, as appropriate
+for the egg's format.
+
+Normally, an egg's filename should include at least the project name and
+version, as this allows the runtime system to find desired project
+versions without having to read the egg's PKG-INFO to determine its
+version number.
+
+Setuptools, however, only includes the version number in the filename
+when an ``.egg`` file is built using the ``bdist_egg`` command, or when
+an ``.egg-info`` directory is being installed by the
+``install_egg_info`` command. When generating metadata for use with the
+original source tree, it only includes the project name, so that the
+directory will not have to be renamed each time the project's version
+changes.
+
+This is especially important when version numbers change frequently, and
+the source metadata directory is kept under version control with the
+rest of the project.  (As would be the case when the project's source
+includes project-defined metadata that is not generated from by
+setuptools from data in the setup script.)
+
+
+Egg Links
+=========
+
+In addition to the ``.egg`` and ``.egg-info`` formats, there is a third
+egg-related extension that you may encounter on occasion: ``.egg-link``
+files.
+
+These files are not eggs, strictly speaking. They simply provide a way
+to reference an egg that is not physically installed in the desired
+location. They exist primarily as a cross-platform alternative to
+symbolic links, to support "installing" code that is being developed in
+a different location than the desired installation location. For
+example, if a user is developing an application plugin in their home
+directory, but the plugin needs to be "installed" in an application
+plugin directory, running "setup.py develop -md /path/to/app/plugins"
+will install an ``.egg-link`` file in ``/path/to/app/plugins``, that
+tells the egg runtime system where to find the actual egg (the user's
+project source directory and its ``.egg-info`` subdirectory).
+
+``.egg-link`` files are named following the format for ``.egg`` and
+``.egg-info`` names, but only the project name is included; no version,
+Python version, or platform information is included.  When the runtime
+searches for available eggs, ``.egg-link`` files are opened and the
+actual egg file/directory name is read from them.
+
+Each ``.egg-link`` file should contain a single file or directory name,
+with no newlines.  This filename should be the base location of one or
+more eggs.  That is, the name must either end in ``.egg``, or else it
+should be the parent directory of one or more ``.egg-info`` format eggs.
+
+As of setuptools 0.6c6, the path may be specified as a platform-independent
+(i.e. ``/``-separated) relative path from the directory containing the
+``.egg-link`` file, and a second line may appear in the file, specifying a
+platform-independent relative path from the egg's base directory to its
+setup script directory.  This allows installation tools such as EasyInstall
+to find the project's setup directory and build eggs or perform other setup
+commands on it.
+
+
+-----------------
+Standard Metadata
+-----------------
+
+In addition to the minimum required ``PKG-INFO`` metadata, projects can
+include a variety of standard metadata files or directories, as
+described below.  Except as otherwise noted, these files and directories
+are automatically generated by setuptools, based on information supplied
+in the setup script or through analysis of the project's code and
+resources.
+
+Most of these files and directories are generated via "egg-info
+writers" during execution of the setuptools ``egg_info`` command, and
+are listed in the ``egg_info.writers`` entry point group defined by
+setuptools' own ``setup.py`` file.
+
+Project authors can register their own metadata writers as entry points
+in this group (as described in the setuptools manual under "Adding new
+EGG-INFO Files") to cause setuptools to generate project-specific
+metadata files or directories during execution of the ``egg_info``
+command.  It is up to project authors to document these new metadata
+formats, if they create any.
+
+
+``.txt`` File Formats
+=====================
+
+Files described in this section that have ``.txt`` extensions have a
+simple lexical format consisting of a sequence of text lines, each line
+terminated by a linefeed character (regardless of platform).  Leading
+and trailing whitespace on each line is ignored, as are blank lines and
+lines whose first nonblank character is a ``#`` (comment symbol).  (This
+is the parsing format defined by the ``yield_lines()`` function of
+the ``pkg_resources`` module.)
+
+All ``.txt`` files defined by this section follow this format, but some
+are also "sectioned" files, meaning that their contents are divided into
+sections, using square-bracketed section headers akin to Windows
+``.ini`` format.  Note that this does *not* imply that the lines within
+the sections follow an ``.ini`` format, however.  Please see an
+individual metadata file's documentation for a description of what the
+lines and section names mean in that particular file.
+
+Sectioned files can be parsed using the ``split_sections()`` function;
+see the "Parsing Utilities" section of the ``pkg_resources`` manual for
+for details.
+
+
+Dependency Metadata
+===================
+
+
+``requires.txt``
+----------------
+
+This is a "sectioned" text file.  Each section is a sequence of
+"requirements", as parsed by the ``parse_requirements()`` function;
+please see the ``pkg_resources`` manual for the complete requirement
+parsing syntax.
+
+The first, unnamed section (i.e., before the first section header) in
+this file is the project's core requirements, which must be installed
+for the project to function.  (Specified using the ``install_requires``
+keyword to ``setup()``).
+
+The remaining (named) sections describe the project's "extra"
+requirements, as specified using the ``extras_require`` keyword to
+``setup()``.  The section name is the name of the optional feature, and
+the section body lists that feature's dependencies.
+
+Note that it is not normally necessary to inspect this file directly;
+``pkg_resources.Distribution`` objects have a ``requires()`` method
+that can be used to obtain ``Requirement`` objects describing the
+project's core and optional dependencies.
+
+
+``setup_requires.txt``
+----------------------
+
+Much like ``requires.txt`` except represents the requirements
+specified by the ``setup_requires`` parameter to the Distribution.
+
+
+``dependency_links.txt``
+------------------------
+
+A list of dependency URLs, one per line, as specified using the
+``dependency_links`` keyword to ``setup()``.  These may be direct
+download URLs, or the URLs of web pages containing direct download
+links, and will be used by EasyInstall to find dependencies, as though
+the user had manually provided them via the ``--find-links`` command
+line option.  Please see the setuptools manual and EasyInstall manual
+for more information on specifying this option, and for information on
+how EasyInstall processes ``--find-links`` URLs.
+
+
+``depends.txt`` -- Obsolete, do not create!
+-------------------------------------------
+
+This file follows an identical format to ``requires.txt``, but is
+obsolete and should not be used.  The earliest versions of setuptools
+required users to manually create and maintain this file, so the runtime
+still supports reading it, if it exists.  The new filename was created
+so that it could be automatically generated from ``setup()`` information
+without overwriting an existing hand-created ``depends.txt``, if one
+was already present in the project's source ``.egg-info`` directory.
+
+
+``namespace_packages.txt`` -- Namespace Package Metadata
+========================================================
+
+A list of namespace package names, one per line, as supplied to the
+``namespace_packages`` keyword to ``setup()``.  Please see the manuals
+for setuptools and ``pkg_resources`` for more information about
+namespace packages.
+
+
+``entry_points.txt`` -- "Entry Point"/Plugin Metadata
+=====================================================
+
+This is a "sectioned" text file, whose contents encode the
+``entry_points`` keyword supplied to ``setup()``.  All sections are
+named, as the section names specify the entry point groups in which the
+corresponding section's entry points are registered.
+
+Each section is a sequence of "entry point" lines, each parseable using
+the ``EntryPoint.parse`` classmethod; please see the ``pkg_resources``
+manual for the complete entry point parsing syntax.
+
+Note that it is not necessary to parse this file directly; the
+``pkg_resources`` module provides a variety of APIs to locate and load
+entry points automatically.  Please see the setuptools and
+``pkg_resources`` manuals for details on the nature and uses of entry
+points.
+
+
+The ``scripts`` Subdirectory
+============================
+
+This directory is currently only created for ``.egg`` files built by
+the setuptools ``bdist_egg`` command.  It will contain copies of all
+of the project's "traditional" scripts (i.e., those specified using the
+``scripts`` keyword to ``setup()``).  This is so that they can be
+reconstituted when an ``.egg`` file is installed.
+
+The scripts are placed here using the distutils' standard
+``install_scripts`` command, so any ``#!`` lines reflect the Python
+installation where the egg was built.  But instead of copying the
+scripts to the local script installation directory, EasyInstall writes
+short wrapper scripts that invoke the original scripts from inside the
+egg, after ensuring that sys.path includes the egg and any eggs it
+depends on.  For more about `script wrappers`_, see the section below on
+`Installation and Path Management Issues`_.
+
+
+Zip Support Metadata
+====================
+
+
+``native_libs.txt``
+-------------------
+
+A list of C extensions and other dynamic link libraries contained in
+the egg, one per line.  Paths are ``/``-separated and relative to the
+egg's base location.
+
+This file is generated as part of ``bdist_egg`` processing, and as such
+only appears in ``.egg`` files (and ``.egg`` directories created by
+unpacking them).  It is used to ensure that all libraries are extracted
+from a zipped egg at the same time, in case there is any direct linkage
+between them.  Please see the `Zip File Issues`_ section below for more
+information on library and resource extraction from ``.egg`` files.
+
+
+``eager_resources.txt``
+-----------------------
+
+A list of resource files and/or directories, one per line, as specified
+via the ``eager_resources`` keyword to ``setup()``.  Paths are
+``/``-separated and relative to the egg's base location.
+
+Resource files or directories listed here will be extracted
+simultaneously, if any of the named resources are extracted, or if any
+native libraries listed in ``native_libs.txt`` are extracted.  Please
+see the setuptools manual for details on what this feature is used for
+and how it works, as well as the `Zip File Issues`_ section below.
+
+
+``zip-safe`` and ``not-zip-safe``
+---------------------------------
+
+These are zero-length files, and either one or the other should exist.
+If ``zip-safe`` exists, it means that the project will work properly
+when installed as an ``.egg`` zipfile, and conversely the existence of
+``not-zip-safe`` means the project should not be installed as an
+``.egg`` file.  The ``zip_safe`` option to setuptools' ``setup()``
+determines which file will be written. If the option isn't provided,
+setuptools attempts to make its own assessment of whether the package
+can work, based on code and content analysis.
+
+If neither file is present at installation time, EasyInstall defaults
+to assuming that the project should be unzipped.  (Command-line options
+to EasyInstall, however, take precedence even over an existing
+``zip-safe`` or ``not-zip-safe`` file.)
+
+Note that these flag files appear only in ``.egg`` files generated by
+``bdist_egg``, and in ``.egg`` directories created by unpacking such an
+``.egg`` file.
+
+
+
+``top_level.txt`` -- Conflict Management Metadata
+=================================================
+
+This file is a list of the top-level module or package names provided
+by the project, one Python identifier per line.
+
+Subpackages are not included; a project containing both a ``foo.bar``
+and a ``foo.baz`` would include only one line, ``foo``, in its
+``top_level.txt``.
+
+This data is used by ``pkg_resources`` at runtime to issue a warning if
+an egg is added to ``sys.path`` when its contained packages may have
+already been imported.
+
+(It was also once used to detect conflicts with non-egg packages at
+installation time, but in more recent versions, setuptools installs eggs
+in such a way that they always override non-egg packages, thus
+preventing a problem from arising.)
+
+
+``SOURCES.txt`` -- Source Files Manifest
+========================================
+
+This file is roughly equivalent to the distutils' ``MANIFEST`` file.
+The differences are as follows:
+
+* The filenames always use ``/`` as a path separator, which must be
+  converted back to a platform-specific path whenever they are read.
+
+* The file is automatically generated by setuptools whenever the
+  ``egg_info`` or ``sdist`` commands are run, and it is *not*
+  user-editable.
+
+Although this metadata is included with distributed eggs, it is not
+actually used at runtime for any purpose.  Its function is to ensure
+that setuptools-built *source* distributions can correctly discover
+what files are part of the project's source, even if the list had been
+generated using revision control metadata on the original author's
+system.
+
+In other words, ``SOURCES.txt`` has little or no runtime value for being
+included in distributed eggs, and it is possible that future versions of
+the ``bdist_egg`` and ``install_egg_info`` commands will strip it before
+installation or distribution.  Therefore, do not rely on its being
+available outside of an original source directory or source
+distribution.
+
+
+------------------------------
+Other Technical Considerations
+------------------------------
+
+
+Zip File Issues
+===============
+
+Although zip files resemble directories, they are not fully
+substitutable for them.  Most platforms do not support loading dynamic
+link libraries contained in zipfiles, so it is not possible to directly
+import C extensions from ``.egg`` zipfiles.  Similarly, there are many
+existing libraries -- whether in Python or C -- that require actual
+operating system filenames, and do not work with arbitrary "file-like"
+objects or in-memory strings, and thus cannot operate directly on the
+contents of zip files.
+
+To address these issues, the ``pkg_resources`` module provides a
+"resource API" to support obtaining either the contents of a resource,
+or a true operating system filename for the resource.  If the egg
+containing the resource is a directory, the resource's real filename
+is simply returned.  However, if the egg is a zipfile, then the
+resource is first extracted to a cache directory, and the filename
+within the cache is returned.
+
+The cache directory is determined by the ``pkg_resources`` API; please
+see the ``set_cache_path()`` and ``get_default_cache()`` documentation
+for details.
+
+
+The Extraction Process
+----------------------
+
+Resources are extracted to a cache subdirectory whose name is based
+on the enclosing ``.egg`` filename and the path to the resource.  If
+there is already a file of the correct name, size, and timestamp, its
+filename is returned to the requester.  Otherwise, the desired file is
+extracted first to a temporary name generated using
+``mkstemp(".$extract",target_dir)``, and then its timestamp is set to
+match the one in the zip file, before renaming it to its final name.
+(Some collision detection and resolution code is used to handle the
+fact that Windows doesn't overwrite files when renaming.)
+
+If a resource directory is requested, all of its contents are
+recursively extracted in this fashion, to ensure that the directory
+name can be used as if it were valid all along.
+
+If the resource requested for extraction is listed in the
+``native_libs.txt`` or ``eager_resources.txt`` metadata files, then
+*all* resources listed in *either* file will be extracted before the
+requested resource's filename is returned, thus ensuring that all
+C extensions and data used by them will be simultaneously available.
+
+
+Extension Import Wrappers
+-------------------------
+
+Since Python's built-in zip import feature does not support loading
+C extension modules from zipfiles, the setuptools ``bdist_egg`` command
+generates special import wrappers to make it work.
+
+The wrappers are ``.py`` files (along with corresponding ``.pyc``
+and/or ``.pyo`` files) that have the same module name as the
+corresponding C extension.  These wrappers are located in the same
+package directory (or top-level directory) within the zipfile, so that
+say, ``foomodule.so`` will get a corresponding ``foo.py``, while
+``bar/baz.pyd`` will get a corresponding ``bar/baz.py``.
+
+These wrapper files contain a short stanza of Python code that asks
+``pkg_resources`` for the filename of the corresponding C extension,
+then reloads the module using the obtained filename.  This will cause
+``pkg_resources`` to first ensure that all of the egg's C extensions
+(and any accompanying "eager resources") are extracted to the cache
+before attempting to link to the C library.
+
+Note, by the way, that ``.egg`` directories will also contain these
+wrapper files.  However, Python's default import priority is such that
+C extensions take precedence over same-named Python modules, so the
+import wrappers are ignored unless the egg is a zipfile.
+
+
+Installation and Path Management Issues
+=======================================
+
+Python's initial setup of ``sys.path`` is very dependent on the Python
+version and installation platform, as well as how Python was started
+(i.e., script vs. ``-c`` vs. ``-m`` vs. interactive interpreter).
+In fact, Python also provides only two relatively robust ways to affect
+``sys.path`` outside of direct manipulation in code: the ``PYTHONPATH``
+environment variable, and ``.pth`` files.
+
+However, with no cross-platform way to safely and persistently change
+environment variables, this leaves ``.pth`` files as EasyInstall's only
+real option for persistent configuration of ``sys.path``.
+
+But ``.pth`` files are rather strictly limited in what they are allowed
+to do normally.  They add directories only to the *end* of ``sys.path``,
+after any locally-installed ``site-packages`` directory, and they are
+only processed *in* the ``site-packages`` directory to start with.
+
+This is a double whammy for users who lack write access to that
+directory, because they can't create a ``.pth`` file that Python will
+read, and even if a sympathetic system administrator adds one for them
+that calls ``site.addsitedir()`` to allow some other directory to
+contain ``.pth`` files, they won't be able to install newer versions of
+anything that's installed in the systemwide ``site-packages``, because
+their paths will still be added *after* ``site-packages``.
+
+So EasyInstall applies two workarounds to solve these problems.
+
+The first is that EasyInstall leverages ``.pth`` files' "import" feature
+to manipulate ``sys.path`` and ensure that anything EasyInstall adds
+to a ``.pth`` file will always appear before both the standard library
+and the local ``site-packages`` directories.  Thus, it is always
+possible for a user who can write a Python-read ``.pth`` file to ensure
+that their packages come first in their own environment.
+
+Second, when installing to a ``PYTHONPATH`` directory (as opposed to
+a "site" directory like ``site-packages``) EasyInstall will also install
+a special version of the ``site`` module.  Because it's in a
+``PYTHONPATH`` directory, this module will get control before the
+standard library version of ``site`` does.  It will record the state of
+``sys.path`` before invoking the "real" ``site`` module, and then
+afterwards it processes any ``.pth`` files found in ``PYTHONPATH``
+directories, including all the fixups needed to ensure that eggs always
+appear before the standard library in sys.path, but are in a relative
+order to one another that is defined by their ``PYTHONPATH`` and
+``.pth``-prescribed sequence.
+
+The net result of these changes is that ``sys.path`` order will be
+as follows at runtime:
+
+1. The ``sys.argv[0]`` directory, or an empty string if no script
+   is being executed.
+
+2. All eggs installed by EasyInstall in any ``.pth`` file in each
+   ``PYTHONPATH`` directory, in order first by ``PYTHONPATH`` order,
+   then normal ``.pth`` processing order (which is to say alphabetical
+   by ``.pth`` filename, then by the order of listing within each
+   ``.pth`` file).
+
+3. All eggs installed by EasyInstall in any ``.pth`` file in each "site"
+   directory (such as ``site-packages``), following the same ordering
+   rules as for the ones on ``PYTHONPATH``.
+
+4. The ``PYTHONPATH`` directories themselves, in their original order
+
+5. Any paths from ``.pth`` files found on ``PYTHONPATH`` that were *not*
+   eggs installed by EasyInstall, again following the same relative
+   ordering rules.
+
+6. The standard library and "site" directories, along with the contents
+   of any ``.pth`` files found in the "site" directories.
+
+Notice that sections 1, 4, and 6 comprise the "normal" Python setup for
+``sys.path``.  Sections 2 and 3 are inserted to support eggs, and
+section 5 emulates what the "normal" semantics of ``.pth`` files on
+``PYTHONPATH`` would be if Python natively supported them.
+
+For further discussion of the tradeoffs that went into this design, as
+well as notes on the actual magic inserted into ``.pth`` files to make
+them do these things, please see also the following messages to the
+distutils-SIG mailing list:
+
+* http://mail.python.org/pipermail/distutils-sig/2006-February/006026.html
+* http://mail.python.org/pipermail/distutils-sig/2006-March/006123.html
+
+
+Script Wrappers
+---------------
+
+EasyInstall never directly installs a project's original scripts to
+a script installation directory.  Instead, it writes short wrapper
+scripts that first ensure that the project's dependencies are active
+on sys.path, before invoking the original script.  These wrappers
+have a #! line that points to the version of Python that was used to
+install them, and their second line is always a comment that indicates
+the type of script wrapper, the project version required for the script
+to run, and information identifying the script to be invoked.
+
+The format of this marker line is::
+
+    "# EASY-INSTALL-" script_type ": " tuple_of_strings "\n"
+
+The ``script_type`` is one of ``SCRIPT``, ``DEV-SCRIPT``, or
+``ENTRY-SCRIPT``.  The ``tuple_of_strings`` is a comma-separated
+sequence of Python string constants.  For ``SCRIPT`` and ``DEV-SCRIPT``
+wrappers, there are two strings: the project version requirement, and
+the script name (as a filename within the ``scripts`` metadata
+directory).  For ``ENTRY-SCRIPT`` wrappers, there are three:
+the project version requirement, the entry point group name, and the
+entry point name.  (See the "Automatic Script Creation" section in the
+setuptools manual for more information about entry point scripts.)
+
+In each case, the project version requirement string will be a string
+parseable with the ``pkg_resources`` modules' ``Requirement.parse()``
+classmethod.  The only difference between a ``SCRIPT`` wrapper and a
+``DEV-SCRIPT`` is that a ``DEV-SCRIPT`` actually executes the original
+source script in the project's source tree, and is created when the
+"setup.py develop" command is run.  A ``SCRIPT`` wrapper, on the other
+hand, uses the "installed" script written to the ``EGG-INFO/scripts``
+subdirectory of the corresponding ``.egg`` zipfile or directory.
+(``.egg-info`` eggs do not have script wrappers associated with them,
+except in the "setup.py develop" case.)
+
+The purpose of including the marker line in generated script wrappers is
+to facilitate introspection of installed scripts, and their relationship
+to installed eggs.  For example, an uninstallation tool could use this
+data to identify what scripts can safely be removed, and/or identify
+what scripts would stop working if a particular egg is uninstalled.
+
diff --git a/vendor/setuptools-39.0.1/docs/history.txt b/vendor/setuptools-39.0.1/docs/history.txt
new file mode 100644
index 00000000..8fd1dc65
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/history.txt
@@ -0,0 +1,46 @@
+:tocdepth: 2
+
+.. _changes:
+
+History
+*******
+
+.. include:: ../CHANGES (links).rst
+
+Credits
+*******
+
+* The original design for the ``.egg`` format and the ``pkg_resources`` API was
+  co-created by Phillip Eby and Bob Ippolito. Bob also implemented the first
+  version of ``pkg_resources``, and supplied the OS X operating system version
+  compatibility algorithm.
+
+* Ian Bicking implemented many early "creature comfort" features of
+  easy_install, including support for downloading via Sourceforge and
+  Subversion repositories. Ian's comments on the Web-SIG about WSGI
+  application deployment also inspired the concept of "entry points" in eggs,
+  and he has given talks at PyCon and elsewhere to inform and educate the
+  community about eggs and setuptools.
+
+* Jim Fulton contributed time and effort to build automated tests of various
+  aspects of ``easy_install``, and supplied the doctests for the command-line
+  ``.exe`` wrappers on Windows.
+
+* Phillip J. Eby is the seminal author of setuptools, and
+  first proposed the idea of an importable binary distribution format for
+  Python application plug-ins.
+
+* Significant parts of the implementation of setuptools were funded by the Open
+  Source Applications Foundation, to provide a plug-in infrastructure for the
+  Chandler PIM application. In addition, many OSAF staffers (such as Mike
+  "Code Bear" Taylor) contributed their time and stress as guinea pigs for the
+  use of eggs and setuptools, even before eggs were "cool".  (Thanks, guys!)
+
+* Tarek Ziadé is the principal author of the Distribute fork, which
+  re-invigorated the community on the project, encouraged renewed innovation,
+  and addressed many defects.
+
+* Since the merge with Distribute, Jason R. Coombs is the
+  maintainer of setuptools. The project is maintained in coordination with
+  the Python Packaging Authority (PyPA) and the larger Python community.
+
diff --git a/vendor/setuptools-39.0.1/docs/index.txt b/vendor/setuptools-39.0.1/docs/index.txt
new file mode 100644
index 00000000..74aabb5e
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/index.txt
@@ -0,0 +1,25 @@
+Welcome to Setuptools' documentation!
+=====================================
+
+Setuptools is a fully-featured, actively-maintained, and stable library
+designed to facilitate packaging Python projects, where packaging includes:
+
+ - Python package and module definitions
+ - Distribution package metadata
+ - Test hooks
+ - Project installation
+ - Platform-specific details
+ - Python 3 support
+
+Documentation content:
+
+.. toctree::
+   :maxdepth: 2
+
+   setuptools
+   easy_install
+   pkg_resources
+   python3
+   development
+   roadmap
+   history
diff --git a/vendor/setuptools-39.0.1/docs/pkg_resources.txt b/vendor/setuptools-39.0.1/docs/pkg_resources.txt
new file mode 100644
index 00000000..b40a209f
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/pkg_resources.txt
@@ -0,0 +1,1941 @@
+=============================================================
+Package Discovery and Resource Access using ``pkg_resources``
+=============================================================
+
+The ``pkg_resources`` module distributed with ``setuptools`` provides an API
+for Python libraries to access their resource files, and for extensible
+applications and frameworks to automatically discover plugins.  It also
+provides runtime support for using C extensions that are inside zipfile-format
+eggs, support for merging packages that have separately-distributed modules or
+subpackages, and APIs for managing Python's current "working set" of active
+packages.
+
+
+.. contents:: **Table of Contents**
+
+
+--------
+Overview
+--------
+
+The ``pkg_resources`` module provides runtime facilities for finding,
+introspecting, activating and using installed Python distributions. Some
+of the more advanced features (notably the support for parallel installation
+of multiple versions) rely specifically on the "egg" format (either as a
+zip archive or subdirectory), while others (such as plugin discovery) will
+work correctly so long as "egg-info" metadata directories are available for
+relevant distributions.
+
+Eggs are a distribution format for Python modules, similar in concept to
+Java's "jars" or Ruby's "gems", or the "wheel" format defined in PEP 427.
+However, unlike a pure distribution format, eggs can also be installed and
+added directly to ``sys.path`` as an import location. When installed in
+this way, eggs are *discoverable*, meaning that they carry metadata that
+unambiguously identifies their contents and dependencies. This means that
+an installed egg can be *automatically* found and added to ``sys.path`` in
+response to simple requests of the form, "get me everything I need to use
+docutils' PDF support". This feature allows mutually conflicting versions of
+a distribution to co-exist in the same Python installation, with individual
+applications activating the desired version at runtime by manipulating the
+contents of ``sys.path`` (this differs from the virtual environment
+approach, which involves creating isolated environments for each
+application).
+
+The following terms are needed in order to explain the capabilities offered
+by this module:
+
+project
+    A library, framework, script, plugin, application, or collection of data
+    or other resources, or some combination thereof.  Projects are assumed to
+    have "relatively unique" names, e.g. names registered with PyPI.
+
+release
+    A snapshot of a project at a particular point in time, denoted by a version
+    identifier.
+
+distribution
+    A file or files that represent a particular release.
+
+importable distribution
+    A file or directory that, if placed on ``sys.path``, allows Python to
+    import any modules contained within it.
+
+pluggable distribution
+    An importable distribution whose filename unambiguously identifies its
+    release (i.e. project and version), and whose contents unambiguously
+    specify what releases of other projects will satisfy its runtime
+    requirements.
+
+extra
+    An "extra" is an optional feature of a release, that may impose additional
+    runtime requirements.  For example, if docutils PDF support required a
+    PDF support library to be present, docutils could define its PDF support as
+    an "extra", and list what other project releases need to be available in
+    order to provide it.
+
+environment
+    A collection of distributions potentially available for importing, but not
+    necessarily active.  More than one distribution (i.e. release version) for
+    a given project may be present in an environment.
+
+working set
+    A collection of distributions actually available for importing, as on
+    ``sys.path``.  At most one distribution (release version) of a given
+    project may be present in a working set, as otherwise there would be
+    ambiguity as to what to import.
+
+eggs
+    Eggs are pluggable distributions in one of the three formats currently
+    supported by ``pkg_resources``.  There are built eggs, development eggs,
+    and egg links.  Built eggs are directories or zipfiles whose name ends
+    with ``.egg`` and follows the egg naming conventions, and contain an
+    ``EGG-INFO`` subdirectory (zipped or otherwise).  Development eggs are
+    normal directories of Python code with one or more ``ProjectName.egg-info``
+    subdirectories. The development egg format is also used to provide a
+    default version of a distribution that is available to software that
+    doesn't use ``pkg_resources`` to request specific versions. Egg links
+    are ``*.egg-link`` files that contain the name of a built or
+    development egg, to support symbolic linking on platforms that do not
+    have native symbolic links (or where the symbolic link support is
+    limited).
+
+(For more information about these terms and concepts, see also this
+`architectural overview`_ of ``pkg_resources`` and Python Eggs in general.)
+
+.. _architectural overview: http://mail.python.org/pipermail/distutils-sig/2005-June/004652.html
+
+
+.. -----------------
+.. Developer's Guide
+.. -----------------
+
+.. This section isn't written yet.  Currently planned topics include
+    Accessing Resources
+    Finding and Activating Package Distributions
+        get_provider()
+        require()
+        WorkingSet
+        iter_distributions
+    Running Scripts
+    Configuration
+    Namespace Packages
+    Extensible Applications and Frameworks
+        Locating entry points
+        Activation listeners
+        Metadata access
+        Extended Discovery and Installation
+    Supporting Custom PEP 302 Implementations
+.. For now, please check out the extensive `API Reference`_ below.
+
+
+-------------
+API Reference
+-------------
+
+Namespace Package Support
+=========================
+
+A namespace package is a package that only contains other packages and modules,
+with no direct contents of its own.  Such packages can be split across
+multiple, separately-packaged distributions.  They are normally used to split
+up large packages produced by a single organization, such as in the ``zope``
+namespace package for Zope Corporation packages, and the ``peak`` namespace
+package for the Python Enterprise Application Kit.
+
+To create a namespace package, you list it in the ``namespace_packages``
+argument to ``setup()``, in your project's ``setup.py``.  (See the
+:ref:`setuptools documentation on namespace packages <Namespace Packages>` for
+more information on this.)  Also, you must add a ``declare_namespace()`` call
+in the package's ``__init__.py`` file(s):
+
+``declare_namespace(name)``
+    Declare that the dotted package name `name` is a "namespace package" whose
+    contained packages and modules may be spread across multiple distributions.
+    The named package's ``__path__`` will be extended to include the
+    corresponding package in all distributions on ``sys.path`` that contain a
+    package of that name.  (More precisely, if an importer's
+    ``find_module(name)`` returns a loader, then it will also be searched for
+    the package's contents.)  Whenever a Distribution's ``activate()`` method
+    is invoked, it checks for the presence of namespace packages and updates
+    their ``__path__`` contents accordingly.
+
+Applications that manipulate namespace packages or directly alter ``sys.path``
+at runtime may also need to use this API function:
+
+``fixup_namespace_packages(path_item)``
+    Declare that `path_item` is a newly added item on ``sys.path`` that may
+    need to be used to update existing namespace packages.  Ordinarily, this is
+    called for you when an egg is automatically added to ``sys.path``, but if
+    your application modifies ``sys.path`` to include locations that may
+    contain portions of a namespace package, you will need to call this
+    function to ensure they are added to the existing namespace packages.
+
+Although by default ``pkg_resources`` only supports namespace packages for
+filesystem and zip importers, you can extend its support to other "importers"
+compatible with PEP 302 using the ``register_namespace_handler()`` function.
+See the section below on `Supporting Custom Importers`_ for details.
+
+
+``WorkingSet`` Objects
+======================
+
+The ``WorkingSet`` class provides access to a collection of "active"
+distributions.  In general, there is only one meaningful ``WorkingSet``
+instance: the one that represents the distributions that are currently active
+on ``sys.path``.  This global instance is available under the name
+``working_set`` in the ``pkg_resources`` module.  However, specialized
+tools may wish to manipulate working sets that don't correspond to
+``sys.path``, and therefore may wish to create other ``WorkingSet`` instances.
+
+It's important to note that the global ``working_set`` object is initialized
+from ``sys.path`` when ``pkg_resources`` is first imported, but is only updated
+if you do all future ``sys.path`` manipulation via ``pkg_resources`` APIs.  If
+you manually modify ``sys.path``, you must invoke the appropriate methods on
+the ``working_set`` instance to keep it in sync.  Unfortunately, Python does
+not provide any way to detect arbitrary changes to a list object like
+``sys.path``, so ``pkg_resources`` cannot automatically update the
+``working_set`` based on changes to ``sys.path``.
+
+``WorkingSet(entries=None)``
+    Create a ``WorkingSet`` from an iterable of path entries.  If `entries`
+    is not supplied, it defaults to the value of ``sys.path`` at the time
+    the constructor is called.
+
+    Note that you will not normally construct ``WorkingSet`` instances
+    yourself, but instead you will implicitly or explicitly use the global
+    ``working_set`` instance.  For the most part, the ``pkg_resources`` API
+    is designed so that the ``working_set`` is used by default, such that you
+    don't have to explicitly refer to it most of the time.
+
+All distributions available directly on ``sys.path`` will be activated
+automatically when ``pkg_resources`` is imported. This behaviour can cause
+version conflicts for applications which require non-default versions of
+those distributions. To handle this situation, ``pkg_resources`` checks for a
+``__requires__`` attribute in the ``__main__`` module when initializing the
+default working set, and uses this to ensure a suitable version of each
+affected distribution is activated. For example::
+
+    __requires__ = ["CherryPy < 3"] # Must be set before pkg_resources import
+    import pkg_resources
+
+
+Basic ``WorkingSet`` Methods
+----------------------------
+
+The following methods of ``WorkingSet`` objects are also available as module-
+level functions in ``pkg_resources`` that apply to the default ``working_set``
+instance.  Thus, you can use e.g. ``pkg_resources.require()`` as an
+abbreviation for ``pkg_resources.working_set.require()``:
+
+
+``require(*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.
+
+    For the syntax of requirement specifiers, see the section below on
+    `Requirements Parsing`_.
+
+    In general, it should not be necessary for you to call this method
+    directly.  It's intended more for use in quick-and-dirty scripting and
+    interactive interpreter hacking than for production use. If you're creating
+    an actual library or application, it's strongly recommended that you create
+    a "setup.py" script using ``setuptools``, and declare all your requirements
+    there.  That way, tools like EasyInstall can automatically detect what
+    requirements your package has, and deal with them accordingly.
+
+    Note that calling ``require('SomePackage')`` will not install
+    ``SomePackage`` if it isn't already present.  If you need to do this, you
+    should use the ``resolve()`` method instead, which allows you to pass an
+    ``installer`` callback that will be invoked when a needed distribution
+    can't be found on the local machine.  You can then have this callback
+    display a dialog, automatically download the needed distribution, or
+    whatever else is appropriate for your application. See the documentation
+    below on the ``resolve()`` method for more information, and also on the
+    ``obtain()`` method of ``Environment`` objects.
+
+``run_script(requires, script_name)``
+    Locate distribution specified by `requires` and run its `script_name`
+    script.  `requires` must be a string containing a requirement specifier.
+    (See `Requirements Parsing`_ below for the syntax.)
+
+    The script, if found, will be executed in *the caller's globals*.  That's
+    because this method is intended to be called from wrapper scripts that
+    act as a proxy for the "real" scripts in a distribution.  A wrapper script
+    usually doesn't need to do anything but invoke this function with the
+    correct arguments.
+
+    If you need more control over the script execution environment, you
+    probably want to use the ``run_script()`` method of a ``Distribution``
+    object's `Metadata API`_ instead.
+
+``iter_entry_points(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.  Entry points are yielded from the active
+    distributions in the order that the distributions appear in the working
+    set.  (For the global ``working_set``, this should be the same as the order
+    that they are listed in ``sys.path``.)  Note that within the entry points
+    advertised by an individual distribution, there is no particular ordering.
+
+    Please see the section below on `Entry Points`_ for more information.
+
+
+``WorkingSet`` Methods and Attributes
+-------------------------------------
+
+These methods are used to query or manipulate the contents of a specific
+working set, so they must be explicitly invoked on a particular ``WorkingSet``
+instance:
+
+``add_entry(entry)``
+    Add a path item to the ``entries``, finding any distributions on it.  You
+    should use this when you add additional items to ``sys.path`` and you want
+    the global ``working_set`` to reflect the change.  This method is also
+    called by the ``WorkingSet()`` constructor during initialization.
+
+    This method uses ``find_distributions(entry,True)`` to find distributions
+    corresponding to the path entry, and then ``add()`` them.  `entry` is
+    always appended to the ``entries`` attribute, even if it is already
+    present, however. (This is because ``sys.path`` can contain the same value
+    more than once, and the ``entries`` attribute should be able to reflect
+    this.)
+
+``__contains__(dist)``
+    True if `dist` is active in this ``WorkingSet``.  Note that only one
+    distribution for a given project can be active in a given ``WorkingSet``.
+
+``__iter__()``
+    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.
+
+``find(req)``
+    Find a distribution matching `req` (a ``Requirement`` instance).
+    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.
+
+``resolve(requirements, env=None, installer=None)``
+    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, an ``Environment`` is created from the working set's
+    ``entries``.  `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``.  (See the ``obtain()`` method
+    of `Environment Objects`_, below, for more information on the `installer`
+    argument.)
+
+``add(dist, entry=None)``
+    Add `dist` to working set, associated with `entry`
+
+    If `entry` is unspecified, it defaults to ``dist.location``.  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 active in the set.  If it's
+    successfully added, any  callbacks registered with the ``subscribe()``
+    method will be called.  (See `Receiving Change Notifications`_, below.)
+
+    Note: ``add()`` is automatically called for you by the ``require()``
+    method, so you don't normally need to use this method directly.
+
+``entries``
+    This attribute represents a "shadow" ``sys.path``, primarily useful for
+    debugging.  If you are experiencing import problems, you should check
+    the global ``working_set`` object's ``entries`` against ``sys.path``, to
+    ensure that they match.  If they do not, then some part of your program
+    is manipulating ``sys.path`` without updating the ``working_set``
+    accordingly.  IMPORTANT NOTE: do not directly manipulate this attribute!
+    Setting it equal to ``sys.path`` will not fix your problem, any more than
+    putting black tape over an "engine warning" light will fix your car!  If
+    this attribute is out of sync with ``sys.path``, it's merely an *indicator*
+    of the problem, not the cause of it.
+
+
+Receiving Change Notifications
+------------------------------
+
+Extensible applications and frameworks may need to receive notification when
+a new distribution (such as a plug-in component) has been added to a working
+set.  This is what the ``subscribe()`` method and ``add_activation_listener()``
+function are for.
+
+``subscribe(callback)``
+    Invoke ``callback(distribution)`` once for each active distribution that is
+    in the set now, or gets added later.  Because the callback is invoked for
+    already-active distributions, you do not need to loop over the working set
+    yourself to deal with the existing items; just register the callback and
+    be prepared for the fact that it will be called immediately by this method.
+
+    Note that callbacks *must not* allow exceptions to propagate, or they will
+    interfere with the operation of other callbacks and possibly result in an
+    inconsistent working set state.  Callbacks should use a try/except block
+    to ignore, log, or otherwise process any errors, especially since the code
+    that caused the callback to be invoked is unlikely to be able to handle
+    the errors any better than the callback itself.
+
+``pkg_resources.add_activation_listener()`` is an alternate spelling of
+``pkg_resources.working_set.subscribe()``.
+
+
+Locating Plugins
+----------------
+
+Extensible applications will sometimes have a "plugin directory" or a set of
+plugin directories, from which they want to load entry points or other
+metadata.  The ``find_plugins()`` method allows you to do this, by scanning an
+environment for the newest version of each project that can be safely loaded
+without conflicts or missing requirements.
+
+``find_plugins(plugin_env, full_env=None, fallback=True)``
+   Scan `plugin_env` and identify which distributions could be added to this
+   working set without version conflicts or missing requirements.
+
+   Example usage::
+
+       distributions, errors = working_set.find_plugins(
+           Environment(plugin_dirlist)
+       )
+       map(working_set.add, distributions)  # add plugins+libs to sys.path
+       print "Couldn't 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`` instance that
+   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.
+
+   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.
+
+   Most applications will use this method mainly on the master ``working_set``
+   instance in ``pkg_resources``, and then immediately add the returned
+   distributions to the working set so that they are available on sys.path.
+   This will make it possible to find any entry points, and allow any other
+   metadata tracking and hooks to be activated.
+
+   The resolution algorithm used by ``find_plugins()`` is as follows.  First,
+   the project names of the distributions present in `plugin_env` are sorted.
+   Then, each project's eggs are tried in descending version order (i.e.,
+   newest version first).
+
+   An attempt is made to resolve each egg's dependencies. If the attempt is
+   successful, the egg and its dependencies are added to the output list and to
+   a temporary copy of the working set.  The resolution process continues with
+   the next project name, and no older eggs for that project are tried.
+
+   If the resolution attempt fails, however, the error is added to the error
+   dictionary.  If the `fallback` flag is true, the next older version of the
+   plugin is tried, until a working version is found.  If false, the resolution
+   process continues with the next plugin project name.
+
+   Some applications may have stricter fallback requirements than others. For
+   example, an application that has a database schema or persistent objects
+   may not be able to safely downgrade a version of a package. Others may want
+   to ensure that a new plugin configuration is either 100% good or else
+   revert to a known-good configuration.  (That is, they may wish to revert to
+   a known configuration if the `error_info` return value is non-empty.)
+
+   Note that this algorithm gives precedence to satisfying the dependencies of
+   alphabetically prior project names in case of version conflicts. If two
+   projects named "AaronsPlugin" and "ZekesPlugin" both need different versions
+   of "TomsLibrary", then "AaronsPlugin" will win and "ZekesPlugin" will be
+   disabled due to version conflict.
+
+
+``Environment`` Objects
+=======================
+
+An "environment" is a collection of ``Distribution`` objects, usually ones
+that are present and potentially importable on the current platform.
+``Environment`` objects are used by ``pkg_resources`` to index available
+distributions during dependency resolution.
+
+``Environment(search_path=None, platform=get_supported_platform(), python=PY_MAJOR)``
+    Create an environment snapshot by scanning `search_path` for distributions
+    compatible with `platform` and `python`.  `search_path` should be a
+    sequence of strings such as might be used on ``sys.path``.  If a
+    `search_path` isn't 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 currently-running version.
+
+    You may explicitly set `platform` (and/or `python`) to ``None`` if you
+    wish to include *all* distributions, not just those compatible with the
+    running platform or Python version.
+
+    Note that `search_path` is scanned immediately for distributions, and the
+    resulting ``Environment`` is a snapshot of the found distributions.  It
+    is not automatically updated if the system's state changes due to e.g.
+    installation or removal of distributions.
+
+``__getitem__(project_name)``
+    Returns a list of distributions for the given project name, ordered
+    from newest to oldest version.  (And highest to lowest format precedence
+    for distributions that contain the same version of the project.)  If there
+    are no distributions for the project, returns an empty list.
+
+``__iter__()``
+    Yield the unique project names of the distributions in this environment.
+    The yielded names are always in lower case.
+
+``add(dist)``
+    Add `dist` to the environment if it matches the platform and python version
+    specified at creation time, and only if the distribution hasn't already
+    been added. (i.e., adding the same distribution more than once is a no-op.)
+
+``remove(dist)``
+    Remove `dist` from the environment.
+
+``can_add(dist)``
+    Is distribution `dist` acceptable for this environment?  If it's not
+    compatible with the ``platform`` and ``python`` version values specified
+    when the environment was created, a false value is returned.
+
+``__add__(dist_or_env)``  (``+`` operator)
+    Add a distribution or environment to an ``Environment`` instance, returning
+    a *new* environment object that contains all the distributions previously
+    contained by both.  The new environment will have a ``platform`` and
+    ``python`` of ``None``, meaning that it will not reject any distributions
+    from being added to it; it will simply accept whatever is added.  If you
+    want the added items to be filtered for platform and Python version, or
+    you want to add them to the *same* environment instance, you should use
+    in-place addition (``+=``) instead.
+
+``__iadd__(dist_or_env)``  (``+=`` operator)
+    Add a distribution or environment to an ``Environment`` instance
+    *in-place*, updating the existing instance and returning it.  The
+    ``platform`` and ``python`` filter attributes take effect, so distributions
+    in the source that do not have a suitable platform string or Python version
+    are silently ignored.
+
+``best_match(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.
+
+``obtain(requirement, installer=None)``
+    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.
+
+``scan(search_path=None)``
+    Scan `search_path` for distributions usable on `platform`
+
+    Any distributions found are added to the environment.  `search_path` should
+    be a sequence of strings such as might be used on ``sys.path``.  If not
+    supplied, ``sys.path`` is used.  Only distributions conforming to
+    the platform/python version defined at initialization are added.  This
+    method is a shortcut for using the ``find_distributions()`` function to
+    find the distributions from each item in `search_path`, and then calling
+    ``add()`` to add each one to the environment.
+
+
+``Requirement`` Objects
+=======================
+
+``Requirement`` objects express what versions of a project are suitable for
+some purpose.  These objects (or their string form) are used by various
+``pkg_resources`` APIs in order to find distributions that a script or
+distribution needs.
+
+
+Requirements Parsing
+--------------------
+
+``parse_requirements(s)``
+    Yield ``Requirement`` objects for a string or iterable of lines.  Each
+    requirement must start on a new line.  See below for syntax.
+
+``Requirement.parse(s)``
+    Create a ``Requirement`` object from a string or iterable of lines.  A
+    ``ValueError`` is raised if the string or lines do not contain a valid
+    requirement specifier, or if they contain more than one specifier.  (To
+    parse multiple specifiers from a string or iterable of strings, use
+    ``parse_requirements()`` instead.)
+
+    The syntax of a requirement specifier is defined in full in PEP 508.
+
+    Some examples of valid requirement specifiers::
+
+        FooProject >= 1.2
+        Fizzy [foo, bar]
+        PickyThing<1.6,>1.9,!=1.9.6,<2.0a0,==2.4c1
+        SomethingWhoseVersionIDontCareAbout
+        SomethingWithMarker[foo]>1.0;python_version<"2.7"
+
+    The project name is the only required portion of a requirement string, and
+    if it's the only thing supplied, the requirement will accept any version
+    of that project.
+
+    The "extras" in a requirement are used to request optional features of a
+    project, that may require additional project distributions in order to
+    function.  For example, if the hypothetical "Report-O-Rama" project offered
+    optional PDF support, it might require an additional library in order to
+    provide that support.  Thus, a project needing Report-O-Rama's PDF features
+    could use a requirement of ``Report-O-Rama[PDF]`` to request installation
+    or activation of both Report-O-Rama and any libraries it needs in order to
+    provide PDF support.  For example, you could use::
+
+        easy_install.py Report-O-Rama[PDF]
+
+    To install the necessary packages using the EasyInstall program, or call
+    ``pkg_resources.require('Report-O-Rama[PDF]')`` to add the necessary
+    distributions to sys.path at runtime.
+
+    The "markers" in a requirement are used to specify when a requirement
+    should be installed -- the requirement will be installed if the marker
+    evaluates as true in the current environment. For example, specifying
+    ``argparse;python_version<"3.0"`` will not install in an Python 3
+    environment, but will in a Python 2 environment.
+
+``Requirement`` Methods and Attributes
+--------------------------------------
+
+``__contains__(dist_or_version)``
+    Return true if `dist_or_version` fits the criteria for this requirement.
+    If `dist_or_version` is a ``Distribution`` object, its project name must
+    match the requirement's project name, and its version must meet the
+    requirement's version criteria.  If `dist_or_version` is a string, it is
+    parsed using the ``parse_version()`` utility function.  Otherwise, it is
+    assumed to be an already-parsed version.
+
+    The ``Requirement`` object's version specifiers (``.specs``) are internally
+    sorted into ascending version order, and used to establish what ranges of
+    versions are acceptable.  Adjacent redundant conditions are effectively
+    consolidated (e.g. ``">1, >2"`` produces the same results as ``">2"``, and
+    ``"<2,<3"`` produces the same results as ``"<2"``). ``"!="`` versions are
+    excised from the ranges they fall within.  The version being tested for
+    acceptability is then checked for membership in the resulting ranges.
+
+``__eq__(other_requirement)``
+    A requirement compares equal to another requirement if they have
+    case-insensitively equal project names, version specifiers, and "extras".
+    (The order that extras and version specifiers are in is also ignored.)
+    Equal requirements also have equal hashes, so that requirements can be
+    used in sets or as dictionary keys.
+
+``__str__()``
+    The string form of a ``Requirement`` is a string that, if passed to
+    ``Requirement.parse()``, would return an equal ``Requirement`` object.
+
+``project_name``
+    The name of the required project
+
+``key``
+    An all-lowercase version of the ``project_name``, useful for comparison
+    or indexing.
+
+``extras``
+    A tuple of names of "extras" that this requirement calls for.  (These will
+    be all-lowercase and normalized using the ``safe_extra()`` parsing utility
+    function, so they may not exactly equal the extras the requirement was
+    created with.)
+
+``specs``
+    A list of ``(op,version)`` tuples, sorted in ascending parsed-version
+    order.  The `op` in each tuple is a comparison operator, represented as
+    a string.  The `version` is the (unparsed) version number.
+
+``marker``
+    An instance of ``packaging.markers.Marker`` that allows evaluation
+    against the current environment. May be None if no marker specified.
+
+``url``
+    The location to download the requirement from if specified.
+
+Entry Points
+============
+
+Entry points are a simple way for distributions to "advertise" Python objects
+(such as functions or classes) for use by other distributions.  Extensible
+applications and frameworks can search for entry points with a particular name
+or group, either from a specific distribution or from all active distributions
+on sys.path, and then inspect or load the advertised objects at will.
+
+Entry points belong to "groups" which are named with a dotted name similar to
+a Python package or module name.  For example, the ``setuptools`` package uses
+an entry point named ``distutils.commands`` in order to find commands defined
+by distutils extensions.  ``setuptools`` treats the names of entry points
+defined in that group as the acceptable commands for a setup script.
+
+In a similar way, other packages can define their own entry point groups,
+either using dynamic names within the group (like ``distutils.commands``), or
+possibly using predefined names within the group.  For example, a blogging
+framework that offers various pre- or post-publishing hooks might define an
+entry point group and look for entry points named "pre_process" and
+"post_process" within that group.
+
+To advertise an entry point, a project needs to use ``setuptools`` and provide
+an ``entry_points`` argument to ``setup()`` in its setup script, so that the
+entry points will be included in the distribution's metadata.  For more
+details, see the ``setuptools`` documentation.  (XXX link here to setuptools)
+
+Each project distribution can advertise at most one entry point of a given
+name within the same entry point group.  For example, a distutils extension
+could advertise two different ``distutils.commands`` entry points, as long as
+they had different names.  However, there is nothing that prevents *different*
+projects from advertising entry points of the same name in the same group.  In
+some cases, this is a desirable thing, since the application or framework that
+uses the entry points may be calling them as hooks, or in some other way
+combining them.  It is up to the application or framework to decide what to do
+if multiple distributions advertise an entry point; some possibilities include
+using both entry points, displaying an error message, using the first one found
+in sys.path order, etc.
+
+
+Convenience API
+---------------
+
+In the following functions, the `dist` argument can be a ``Distribution``
+instance, a ``Requirement`` instance, or a string specifying a requirement
+(i.e. project name, version, etc.).  If the argument is a string or
+``Requirement``, the specified distribution is located (and added to sys.path
+if not already present).  An error will be raised if a matching distribution is
+not available.
+
+The `group` argument should be a string containing a dotted identifier,
+identifying an entry point group.  If you are defining an entry point group,
+you should include some portion of your package's name in the group name so as
+to avoid collision with other packages' entry point groups.
+
+``load_entry_point(dist, group, name)``
+    Load the named entry point from the specified distribution, or raise
+    ``ImportError``.
+
+``get_entry_info(dist, group, name)``
+    Return an ``EntryPoint`` object for the given `group` and `name` from
+    the specified distribution.  Returns ``None`` if the distribution has not
+    advertised a matching entry point.
+
+``get_entry_map(dist, group=None)``
+    Return the distribution's entry point map for `group`, or the full entry
+    map for the distribution.  This function always returns a dictionary,
+    even if the distribution advertises no entry points.  If `group` is given,
+    the dictionary maps entry point names to the corresponding ``EntryPoint``
+    object.  If `group` is None, the dictionary maps group names to
+    dictionaries that then map entry point names to the corresponding
+    ``EntryPoint`` instance in that group.
+
+``iter_entry_points(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 on sys.path, otherwise only ones matching
+    both `group` and `name` are yielded.  Entry points are yielded from
+    the active distributions in the order that the distributions appear on
+    sys.path.  (Within entry points for a particular distribution, however,
+    there is no particular ordering.)
+
+    (This API is actually a method of the global ``working_set`` object; see
+    the section above on `Basic WorkingSet Methods`_ for more information.)
+
+
+Creating and Parsing
+--------------------
+
+``EntryPoint(name, module_name, attrs=(), extras=(), dist=None)``
+    Create an ``EntryPoint`` instance.  `name` is the entry point name.  The
+    `module_name` is the (dotted) name of the module containing the advertised
+    object.  `attrs` is an optional tuple of names to look up from the
+    module to obtain the advertised object.  For example, an `attrs` of
+    ``("foo","bar")`` and a `module_name` of ``"baz"`` would mean that the
+    advertised object could be obtained by the following code::
+
+        import baz
+        advertised_object = baz.foo.bar
+
+    The `extras` are an optional tuple of "extra feature" names that the
+    distribution needs in order to provide this entry point.  When the
+    entry point is loaded, these extra features are looked up in the `dist`
+    argument to find out what other distributions may need to be activated
+    on sys.path; see the ``load()`` method for more details.  The `extras`
+    argument is only meaningful if `dist` is specified.  `dist` must be
+    a ``Distribution`` instance.
+
+``EntryPoint.parse(src, dist=None)`` (classmethod)
+    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, as is the whitespace shown between
+    some of the items.  The `dist` argument is passed through to the
+    ``EntryPoint()`` constructor, along with the other values parsed from
+    `src`.
+
+``EntryPoint.parse_group(group, lines, dist=None)`` (classmethod)
+    Parse `lines` (a string or sequence of lines) to create a dictionary
+    mapping entry point names to ``EntryPoint`` objects.  ``ValueError`` is
+    raised if entry point names are duplicated, if `group` is not a valid
+    entry point group name, or if there are any syntax errors.  (Note: the
+    `group` parameter is used only for validation and to create more
+    informative error messages.)  If `dist` is provided, it will be used to
+    set the ``dist`` attribute of the created ``EntryPoint`` objects.
+
+``EntryPoint.parse_map(data, dist=None)`` (classmethod)
+    Parse `data` into a dictionary mapping group names to dictionaries mapping
+    entry point names to ``EntryPoint`` objects.  If `data` is a dictionary,
+    then the keys are used as group names and the values are passed to
+    ``parse_group()`` as the `lines` argument.  If `data` is a string or
+    sequence of lines, it is first split into .ini-style sections (using
+    the ``split_sections()`` utility function) and the section names are used
+    as group names.  In either case, the `dist` argument is passed through to
+    ``parse_group()`` so that the entry points will be linked to the specified
+    distribution.
+
+
+``EntryPoint`` Objects
+----------------------
+
+For simple introspection, ``EntryPoint`` objects have attributes that
+correspond exactly to the constructor argument names: ``name``,
+``module_name``, ``attrs``, ``extras``, and ``dist`` are all available.  In
+addition, the following methods are provided:
+
+``load()``
+    Load the entry point, returning the advertised Python object.  Effectively
+    calls ``self.require()`` then returns ``self.resolve()``.
+
+``require(env=None, installer=None)``
+    Ensure that any "extras" needed by the entry point are available on
+    sys.path.  ``UnknownExtra`` is raised if the ``EntryPoint`` has ``extras``,
+    but no ``dist``, or if the named extras are not defined by the
+    distribution.  If `env` is supplied, it must be an ``Environment``, and it
+    will be used to search for needed distributions if they are not already
+    present on sys.path.  If `installer` is supplied, it must be a callable
+    taking a ``Requirement`` instance and returning a matching importable
+    ``Distribution`` instance or None.
+
+``resolve()``
+    Resolve the entry point from its module and attrs, returning the advertised
+    Python object. Raises ``ImportError`` if it cannot be obtained.
+
+``__str__()``
+    The string form of an ``EntryPoint`` is a string that could be passed to
+    ``EntryPoint.parse()`` to produce an equivalent ``EntryPoint``.
+
+
+``Distribution`` Objects
+========================
+
+``Distribution`` objects represent collections of Python code that may or may
+not be importable, and may or may not have metadata and resources associated
+with them.  Their metadata may include information such as what other projects
+the distribution depends on, what entry points the distribution advertises, and
+so on.
+
+
+Getting or Creating Distributions
+---------------------------------
+
+Most commonly, you'll obtain ``Distribution`` objects from a ``WorkingSet`` or
+an ``Environment``.  (See the sections above on `WorkingSet Objects`_ and
+`Environment Objects`_, which are containers for active distributions and
+available distributions, respectively.)  You can also obtain ``Distribution``
+objects from one of these high-level APIs:
+
+``find_distributions(path_item, only=False)``
+    Yield distributions accessible via `path_item`.  If `only` is true, yield
+    only distributions whose ``location`` is equal to `path_item`.  In other
+    words, if `only` is true, this yields any distributions that would be
+    importable if `path_item` were on ``sys.path``.  If `only` is false, this
+    also yields distributions that are "in" or "under" `path_item`, but would
+    not be importable unless their locations were also added to ``sys.path``.
+
+``get_distribution(dist_spec)``
+    Return a ``Distribution`` object for a given ``Requirement`` or string.
+    If `dist_spec` is already a ``Distribution`` instance, it is returned.
+    If it is a ``Requirement`` object or a string that can be parsed into one,
+    it is used to locate and activate a matching distribution, which is then
+    returned.
+
+However, if you're creating specialized tools for working with distributions,
+or creating a new distribution format, you may also need to create
+``Distribution`` objects directly, using one of the three constructors below.
+
+These constructors all take an optional `metadata` argument, which is used to
+access any resources or metadata associated with the distribution.  `metadata`
+must be an object that implements the ``IResourceProvider`` interface, or None.
+If it is None, an ``EmptyProvider`` is used instead.  ``Distribution`` objects
+implement both the `IResourceProvider`_ and `IMetadataProvider Methods`_ by
+delegating them to the `metadata` object.
+
+``Distribution.from_location(location, basename, metadata=None, **kw)`` (classmethod)
+    Create a distribution for `location`, which must be a string such as a
+    URL, filename, or other string that might be used on ``sys.path``.
+    `basename` is a string naming the distribution, like ``Foo-1.2-py2.4.egg``.
+    If `basename` ends with ``.egg``, then the project's name, version, python
+    version and platform are extracted from the filename and used to set those
+    properties of the created distribution.  Any additional keyword arguments
+    are forwarded to the ``Distribution()`` constructor.
+
+``Distribution.from_filename(filename, metadata=None**kw)`` (classmethod)
+    Create a distribution by parsing a local filename.  This is a shorter way
+    of saying  ``Distribution.from_location(normalize_path(filename),
+    os.path.basename(filename), metadata)``.  In other words, it creates a
+    distribution whose location is the normalize form of the filename, parsing
+    name and version information from the base portion of the filename.  Any
+    additional keyword arguments are forwarded to the ``Distribution()``
+    constructor.
+
+``Distribution(location,metadata,project_name,version,py_version,platform,precedence)``
+    Create a distribution by setting its properties.  All arguments are
+    optional and default to None, except for `py_version` (which defaults to
+    the current Python version) and `precedence` (which defaults to
+    ``EGG_DIST``; for more details see ``precedence`` under `Distribution
+    Attributes`_ below).  Note that it's usually easier to use the
+    ``from_filename()`` or ``from_location()`` constructors than to specify
+    all these arguments individually.
+
+
+``Distribution`` Attributes
+---------------------------
+
+location
+    A string indicating the distribution's location.  For an importable
+    distribution, this is the string that would be added to ``sys.path`` to
+    make it actively importable.  For non-importable distributions, this is
+    simply a filename, URL, or other way of locating the distribution.
+
+project_name
+    A string, naming the project that this distribution is for.  Project names
+    are defined by a project's setup script, and they are used to identify
+    projects on PyPI.  When a ``Distribution`` is constructed, the
+    `project_name` argument is passed through the ``safe_name()`` utility
+    function to filter out any unacceptable characters.
+
+key
+    ``dist.key`` is short for ``dist.project_name.lower()``.  It's used for
+    case-insensitive comparison and indexing of distributions by project name.
+
+extras
+    A list of strings, giving the names of extra features defined by the
+    project's dependency list (the ``extras_require`` argument specified in
+    the project's setup script).
+
+version
+    A string denoting what release of the project this distribution contains.
+    When a ``Distribution`` is constructed, the `version` argument is passed
+    through the ``safe_version()`` utility function to filter out any
+    unacceptable characters.  If no `version` is specified at construction
+    time, then attempting to access this attribute later will cause the
+    ``Distribution`` to try to discover its version by reading its ``PKG-INFO``
+    metadata file.  If ``PKG-INFO`` is unavailable or can't be parsed,
+    ``ValueError`` is raised.
+
+parsed_version
+    The ``parsed_version`` is an object representing a "parsed" form of the
+    distribution's ``version``.  ``dist.parsed_version`` is a shortcut for
+    calling ``parse_version(dist.version)``.  It is used to compare or sort
+    distributions by version.  (See the `Parsing Utilities`_ section below for
+    more information on the ``parse_version()`` function.)  Note that accessing
+    ``parsed_version`` may result in a ``ValueError`` if the ``Distribution``
+    was constructed without a `version` and without `metadata` capable of
+    supplying the missing version info.
+
+py_version
+    The major/minor Python version the distribution supports, as a string.
+    For example, "2.7" or "3.4".  The default is the current version of Python.
+
+platform
+    A string representing the platform the distribution is intended for, or
+    ``None`` if the distribution is "pure Python" and therefore cross-platform.
+    See `Platform Utilities`_ below for more information on platform strings.
+
+precedence
+    A distribution's ``precedence`` is used to determine the relative order of
+    two distributions that have the same ``project_name`` and
+    ``parsed_version``.  The default precedence is ``pkg_resources.EGG_DIST``,
+    which is the highest (i.e. most preferred) precedence.  The full list
+    of predefined precedences, from most preferred to least preferred, is:
+    ``EGG_DIST``, ``BINARY_DIST``, ``SOURCE_DIST``, ``CHECKOUT_DIST``, and
+    ``DEVELOP_DIST``.  Normally, precedences other than ``EGG_DIST`` are used
+    only by the ``setuptools.package_index`` module, when sorting distributions
+    found in a package index to determine their suitability for installation.
+    "System" and "Development" eggs (i.e., ones that use the ``.egg-info``
+    format), however, are automatically given a precedence of ``DEVELOP_DIST``.
+
+
+
+``Distribution`` Methods
+------------------------
+
+``activate(path=None)``
+    Ensure distribution is importable on `path`.  If `path` is None,
+    ``sys.path`` is used instead.  This ensures that the distribution's
+    ``location`` is in the `path` list, and it also performs any necessary
+    namespace package fixups or declarations.  (That is, if the distribution
+    contains namespace packages, this method ensures that they are declared,
+    and that the distribution's contents for those namespace packages are
+    merged with the contents provided by any other active distributions.  See
+    the section above on `Namespace Package Support`_ for more information.)
+
+    ``pkg_resources`` adds a notification callback to the global ``working_set``
+    that ensures this method is called whenever a distribution is added to it.
+    Therefore, you should not normally need to explicitly call this method.
+    (Note that this means that namespace packages on ``sys.path`` are always
+    imported as soon as ``pkg_resources`` is, which is another reason why
+    namespace packages should not contain any code or import statements.)
+
+``as_requirement()``
+    Return a ``Requirement`` instance that matches this distribution's project
+    name and version.
+
+``requires(extras=())``
+    List the ``Requirement`` objects that specify this distribution's
+    dependencies.  If `extras` is specified, it should be a sequence of names
+    of "extras" defined by the distribution, and the list returned will then
+    include any dependencies needed to support the named "extras".
+
+``clone(**kw)``
+    Create a copy of the distribution.  Any supplied keyword arguments override
+    the corresponding argument to the ``Distribution()`` constructor, allowing
+    you to change some of the copied distribution's attributes.
+
+``egg_name()``
+    Return what this distribution's standard filename should be, not including
+    the ".egg" extension.  For example, a distribution for project "Foo"
+    version 1.2 that runs on Python 2.3 for Windows would have an ``egg_name()``
+    of ``Foo-1.2-py2.3-win32``.  Any dashes in the name or version are
+    converted to underscores.  (``Distribution.from_location()`` will convert
+    them back when parsing a ".egg" file name.)
+
+``__cmp__(other)``, ``__hash__()``
+    Distribution objects are hashed and compared on the basis of their parsed
+    version and precedence, followed by their key (lowercase project name),
+    location, Python version, and platform.
+
+The following methods are used to access ``EntryPoint`` objects advertised
+by the distribution.  See the section above on `Entry Points`_ for more
+detailed information about these operations:
+
+``get_entry_info(group, name)``
+    Return the ``EntryPoint`` object for `group` and `name`, or None if no
+    such point is advertised by this distribution.
+
+``get_entry_map(group=None)``
+    Return the entry point map for `group`.  If `group` is None, return
+    a dictionary mapping group names to entry point maps for all groups.
+    (An entry point map is a dictionary of entry point names to ``EntryPoint``
+    objects.)
+
+``load_entry_point(group, name)``
+    Short for ``get_entry_info(group, name).load()``.  Returns the object
+    advertised by the named entry point, or raises ``ImportError`` if
+    the entry point isn't advertised by this distribution, or there is some
+    other import problem.
+
+In addition to the above methods, ``Distribution`` objects also implement all
+of the `IResourceProvider`_ and `IMetadataProvider Methods`_ (which are
+documented in later sections):
+
+* ``has_metadata(name)``
+* ``metadata_isdir(name)``
+* ``metadata_listdir(name)``
+* ``get_metadata(name)``
+* ``get_metadata_lines(name)``
+* ``run_script(script_name, namespace)``
+* ``get_resource_filename(manager, resource_name)``
+* ``get_resource_stream(manager, resource_name)``
+* ``get_resource_string(manager, resource_name)``
+* ``has_resource(resource_name)``
+* ``resource_isdir(resource_name)``
+* ``resource_listdir(resource_name)``
+
+If the distribution was created with a `metadata` argument, these resource and
+metadata access methods are all delegated to that `metadata` provider.
+Otherwise, they are delegated to an ``EmptyProvider``, so that the distribution
+will appear to have no resources or metadata.  This delegation approach is used
+so that supporting custom importers or new distribution formats can be done
+simply by creating an appropriate `IResourceProvider`_ implementation; see the
+section below on `Supporting Custom Importers`_ for more details.
+
+
+``ResourceManager`` API
+=======================
+
+The ``ResourceManager`` class provides uniform access to package resources,
+whether those resources exist as files and directories or are compressed in
+an archive of some kind.
+
+Normally, you do not need to create or explicitly manage ``ResourceManager``
+instances, as the ``pkg_resources`` module creates a global instance for you,
+and makes most of its methods available as top-level names in the
+``pkg_resources`` module namespace.  So, for example, this code actually
+calls the ``resource_string()`` method of the global ``ResourceManager``::
+
+    import pkg_resources
+    my_data = pkg_resources.resource_string(__name__, "foo.dat")
+
+Thus, you can use the APIs below without needing an explicit
+``ResourceManager`` instance; just import and use them as needed.
+
+
+Basic Resource Access
+---------------------
+
+In the following methods, the `package_or_requirement` argument may be either
+a Python package/module name (e.g. ``foo.bar``) or a ``Requirement`` instance.
+If it is a package or module name, the named module or package must be
+importable (i.e., be in a distribution or directory on ``sys.path``), and the
+`resource_name` argument is interpreted relative to the named package.  (Note
+that if a module name is used, then the resource name is relative to the
+package immediately containing the named module.  Also, you should not use use
+a namespace package name, because a namespace package can be spread across
+multiple distributions, and is therefore ambiguous as to which distribution
+should be searched for the resource.)
+
+If it is a ``Requirement``, then the requirement is automatically resolved
+(searching the current ``Environment`` if necessary) and a matching
+distribution is added to the ``WorkingSet`` and ``sys.path`` if one was not
+already present.  (Unless the ``Requirement`` can't be satisfied, in which
+case an exception is raised.)  The `resource_name` argument is then interpreted
+relative to the root of the identified distribution; i.e. its first path
+segment will be treated as a peer of the top-level modules or packages in the
+distribution.
+
+Note that resource names must be ``/``-separated paths and cannot be absolute
+(i.e. no leading ``/``) or contain relative names like ``".."``.  Do *not* use
+``os.path`` routines to manipulate resource paths, as they are *not* filesystem
+paths.
+
+``resource_exists(package_or_requirement, resource_name)``
+    Does the named resource exist?  Return ``True`` or ``False`` accordingly.
+
+``resource_stream(package_or_requirement, resource_name)``
+    Return a readable file-like object for the specified resource; it may be
+    an actual file, a ``StringIO``, or some similar object.  The stream is
+    in "binary mode", in the sense that whatever bytes are in the resource
+    will be read as-is.
+
+``resource_string(package_or_requirement, resource_name)``
+    Return the specified resource as a string.  The resource is read in
+    binary fashion, such that the returned string contains exactly the bytes
+    that are stored in the resource.
+
+``resource_isdir(package_or_requirement, resource_name)``
+    Is the named resource a directory?  Return ``True`` or ``False``
+    accordingly.
+
+``resource_listdir(package_or_requirement, resource_name)``
+    List the contents of the named resource directory, just like ``os.listdir``
+    except that it works even if the resource is in a zipfile.
+
+Note that only ``resource_exists()`` and ``resource_isdir()`` are insensitive
+as to the resource type.  You cannot use ``resource_listdir()`` on a file
+resource, and you can't use ``resource_string()`` or ``resource_stream()`` on
+directory resources.  Using an inappropriate method for the resource type may
+result in an exception or undefined behavior, depending on the platform and
+distribution format involved.
+
+
+Resource Extraction
+-------------------
+
+``resource_filename(package_or_requirement, resource_name)``
+    Sometimes, it is not sufficient to access a resource in string or stream
+    form, and a true filesystem filename is needed.  In such cases, you can
+    use this method (or module-level function) to obtain a filename for a
+    resource.  If the resource is in an archive distribution (such as a zipped
+    egg), it will be extracted to a cache directory, and the filename within
+    the cache will be returned.  If the named resource is a directory, then
+    all resources within that directory (including subdirectories) are also
+    extracted.  If the named resource is a C extension or "eager resource"
+    (see the ``setuptools`` documentation for details), then all C extensions
+    and eager resources are extracted at the same time.
+
+    Archived resources are extracted to a cache location that can be managed by
+    the following two methods:
+
+``set_extraction_path(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 resource provider.  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.  (On
+    Windows, for example, you can't unlink .pyd or .dll files that are still
+    in use.)
+
+    Note that you may not change the extraction path for a given resource
+    manager once resources have been extracted, unless you first call
+    ``cleanup_resources()``.
+
+``cleanup_resources(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.
+
+
+"Provider" Interface
+--------------------
+
+If you are implementing an ``IResourceProvider`` and/or ``IMetadataProvider``
+for a new distribution archive format, you may need to use the following
+``IResourceManager`` methods to co-ordinate extraction of resources to the
+filesystem.  If you're not implementing an archive format, however, you have
+no need to use these methods.  Unlike the other methods listed above, they are
+*not* available as top-level functions tied to the global ``ResourceManager``;
+you must therefore have an explicit ``ResourceManager`` instance to use them.
+
+``get_cache_path(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.
+
+``extraction_error()``
+    Raise an ``ExtractionError`` describing the active exception as interfering
+    with the extraction process.  You should call this if you encounter any
+    OS errors extracting the file to the cache path; it will format the
+    operating system exception for you, and add other information to the
+    ``ExtractionError`` instance that may be needed by programs that want to
+    wrap or handle extraction errors themselves.
+
+``postprocess(tempname, filename)``
+    Perform any platform-specific postprocessing of `tempname`.
+    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.
+
+
+Metadata API
+============
+
+The metadata API is used to access metadata resources bundled in a pluggable
+distribution.  Metadata resources are virtual files or directories containing
+information about the distribution, such as might be used by an extensible
+application or framework to connect "plugins".  Like other kinds of resources,
+metadata resource names are ``/``-separated and should not contain ``..`` or
+begin with a ``/``.  You should not use ``os.path`` routines to manipulate
+resource paths.
+
+The metadata API is provided by objects implementing the ``IMetadataProvider``
+or ``IResourceProvider`` interfaces.  ``Distribution`` objects implement this
+interface, as do objects returned by the ``get_provider()`` function:
+
+``get_provider(package_or_requirement)``
+    If a package name is supplied, return an ``IResourceProvider`` for the
+    package.  If a ``Requirement`` is supplied, resolve it by returning a
+    ``Distribution`` from the current working set (searching the current
+    ``Environment`` if necessary and adding the newly found ``Distribution``
+    to the working set).  If the named package can't be imported, or the
+    ``Requirement`` can't be satisfied, an exception is raised.
+
+    NOTE: if you use a package name rather than a ``Requirement``, the object
+    you get back may not be a pluggable distribution, depending on the method
+    by which the package was installed.  In particular, "development" packages
+    and "single-version externally-managed" packages do not have any way to
+    map from a package name to the corresponding project's metadata.  Do not
+    write code that passes a package name to ``get_provider()`` and then tries
+    to retrieve project metadata from the returned object.  It may appear to
+    work when the named package is in an ``.egg`` file or directory, but
+    it will fail in other installation scenarios.  If you want project
+    metadata, you need to ask for a *project*, not a package.
+
+
+``IMetadataProvider`` Methods
+-----------------------------
+
+The methods provided by objects (such as ``Distribution`` instances) that
+implement the ``IMetadataProvider`` or ``IResourceProvider`` interfaces are:
+
+``has_metadata(name)``
+    Does the named metadata resource exist?
+
+``metadata_isdir(name)``
+    Is the named metadata resource a directory?
+
+``metadata_listdir(name)``
+    List of metadata names in the directory (like ``os.listdir()``)
+
+``get_metadata(name)``
+    Return the named metadata resource as a string.  The data is read in binary
+    mode; i.e., the exact bytes of the resource file are returned.
+
+``get_metadata_lines(name)``
+    Yield named metadata resource as list of non-blank non-comment lines.  This
+    is short for calling ``yield_lines(provider.get_metadata(name))``.  See the
+    section on `yield_lines()`_ below for more information on the syntax it
+    recognizes.
+
+``run_script(script_name, namespace)``
+    Execute the named script in the supplied namespace dictionary.  Raises
+    ``ResolutionError`` if there is no script by that name in the ``scripts``
+    metadata directory.  `namespace` should be a Python dictionary, usually
+    a module dictionary if the script is being run as a module.
+
+
+Exceptions
+==========
+
+``pkg_resources`` provides a simple exception hierarchy for problems that may
+occur when processing requests to locate and activate packages::
+
+    ResolutionError
+        DistributionNotFound
+        VersionConflict
+        UnknownExtra
+
+    ExtractionError
+
+``ResolutionError``
+    This class is used as a base class for the other three exceptions, so that
+    you can catch all of them with a single "except" clause.  It is also raised
+    directly for miscellaneous requirement-resolution problems like trying to
+    run a script that doesn't exist in the distribution it was requested from.
+
+``DistributionNotFound``
+    A distribution needed to fulfill a requirement could not be found.
+
+``VersionConflict``
+    The requested version of a project conflicts with an already-activated
+    version of the same project.
+
+``UnknownExtra``
+    One of the "extras" requested was not recognized by the distribution it
+    was requested from.
+
+``ExtractionError``
+    A problem occurred extracting a resource to the Python Egg cache.  The
+    following attributes are available on 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
+
+
+Supporting Custom Importers
+===========================
+
+By default, ``pkg_resources`` supports normal filesystem imports, and
+``zipimport`` importers.  If you wish to use the ``pkg_resources`` features
+with other (PEP 302-compatible) importers or module loaders, you may need to
+register various handlers and support functions using these APIs:
+
+``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, when passed a
+    path item, the importer instance, and an `only` flag, yields
+    ``Distribution`` instances found under that path item.  (The `only` flag,
+    if true, means the finder should yield only ``Distribution`` objects whose
+    ``location`` is equal to the path item provided.)
+
+    See the source of the ``pkg_resources.find_on_path`` function for an
+    example finder function.
+
+``register_loader_type(loader_type, provider_factory)``
+    Register `provider_factory` to make ``IResourceProvider`` objects for
+    `loader_type`.  `loader_type` is the type or class of a PEP 302
+    ``module.__loader__``, and `provider_factory` is a function that, when
+    passed a module object, returns an `IResourceProvider`_ for that module,
+    allowing it to be used with the `ResourceManager API`_.
+
+``register_namespace_handler(importer_type, namespace_handler)``
+    Register `namespace_handler` to declare namespace packages for the given
+    `importer_type`.  `importer_type` is the type or class of a PEP 302
+    "importer" (sys.path item handler), and `namespace_handler` is a callable
+    with a signature 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 relevant importer object has
+    already agreed that it can handle the relevant path item.  The handler
+    should only return a subpath if the module ``__path__`` does not already
+    contain an equivalent subpath.  Otherwise, it should return None.
+
+    For an example namespace handler, see the source of the
+    ``pkg_resources.file_ns_handler`` function, which is used for both zipfile
+    importing and regular importing.
+
+
+IResourceProvider
+-----------------
+
+``IResourceProvider`` is an abstract class that documents what methods are
+required of objects returned by a `provider_factory` registered with
+``register_loader_type()``.  ``IResourceProvider`` is a subclass of
+``IMetadataProvider``, so objects that implement this interface must also
+implement all of the `IMetadataProvider Methods`_ as well as the methods
+shown here.  The `manager` argument to the methods below must be an object
+that supports the full `ResourceManager API`_ documented above.
+
+``get_resource_filename(manager, resource_name)``
+    Return a true filesystem path for `resource_name`, coordinating the
+    extraction with `manager`, if the resource must be unpacked to the
+    filesystem.
+
+``get_resource_stream(manager, resource_name)``
+    Return a readable file-like object for `resource_name`.
+
+``get_resource_string(manager, resource_name)``
+    Return a string containing the contents of `resource_name`.
+
+``has_resource(resource_name)``
+    Does the package contain the named resource?
+
+``resource_isdir(resource_name)``
+    Is the named resource a directory?  Return a false value if the resource
+    does not exist or is not a directory.
+
+``resource_listdir(resource_name)``
+    Return a list of the contents of the resource directory, ala
+    ``os.listdir()``.  Requesting the contents of a non-existent directory may
+    raise an exception.
+
+Note, by the way, that your provider classes need not (and should not) subclass
+``IResourceProvider`` or ``IMetadataProvider``!  These classes exist solely
+for documentation purposes and do not provide any useful implementation code.
+You may instead wish to subclass one of the `built-in resource providers`_.
+
+
+Built-in Resource Providers
+---------------------------
+
+``pkg_resources`` includes several provider classes that are automatically used
+where appropriate.  Their inheritance tree looks like this::
+
+    NullProvider
+        EggProvider
+            DefaultProvider
+                PathMetadata
+            ZipProvider
+                EggMetadata
+        EmptyProvider
+            FileMetadata
+
+
+``NullProvider``
+    This provider class is just an abstract base that provides for common
+    provider behaviors (such as running scripts), given a definition for just
+    a few abstract methods.
+
+``EggProvider``
+    This provider class adds in some egg-specific features that are common
+    to zipped and unzipped eggs.
+
+``DefaultProvider``
+    This provider class is used for unpacked eggs and "plain old Python"
+    filesystem modules.
+
+``ZipProvider``
+    This provider class is used for all zipped modules, whether they are eggs
+    or not.
+
+``EmptyProvider``
+    This provider class always returns answers consistent with a provider that
+    has no metadata or resources.  ``Distribution`` objects created without
+    a ``metadata`` argument use an instance of this provider class instead.
+    Since all ``EmptyProvider`` instances are equivalent, there is no need
+    to have more than one instance.  ``pkg_resources`` therefore creates a
+    global instance of this class under the name ``empty_provider``, and you
+    may use it if you have need of an ``EmptyProvider`` instance.
+
+``PathMetadata(path, egg_info)``
+    Create an ``IResourceProvider`` for a filesystem-based distribution, where
+    `path` is the filesystem location of the importable modules, and `egg_info`
+    is the filesystem location of the distribution's metadata directory.
+    `egg_info` should usually be the ``EGG-INFO`` subdirectory of `path` for an
+    "unpacked egg", and a ``ProjectName.egg-info`` subdirectory of `path` for
+    a "development egg".  However, other uses are possible for custom purposes.
+
+``EggMetadata(zipimporter)``
+    Create an ``IResourceProvider`` for a zipfile-based distribution.  The
+    `zipimporter` should be a ``zipimport.zipimporter`` instance, and may
+    represent a "basket" (a zipfile containing multiple ".egg" subdirectories)
+    a specific egg *within* a basket, or a zipfile egg (where the zipfile
+    itself is a ".egg").  It can also be a combination, such as a zipfile egg
+    that also contains other eggs.
+
+``FileMetadata(path_to_pkg_info)``
+    Create an ``IResourceProvider`` that provides exactly one metadata
+    resource: ``PKG-INFO``.  The supplied path should be a distutils PKG-INFO
+    file.  This is basically the same as an ``EmptyProvider``, except that
+    requests for ``PKG-INFO`` will be answered using the contents of the
+    designated file.  (This provider is used to wrap ``.egg-info`` files
+    installed by vendor-supplied system packages.)
+
+
+Utility Functions
+=================
+
+In addition to its high-level APIs, ``pkg_resources`` also includes several
+generally-useful utility routines.  These routines are used to implement the
+high-level APIs, but can also be quite useful by themselves.
+
+
+Parsing Utilities
+-----------------
+
+``parse_version(version)``
+    Parsed a project's version string as defined by PEP 440. The returned
+    value will be an object that represents the version. These objects may
+    be compared to each other and sorted. The sorting algorithm is as defined
+    by PEP 440 with the addition that any version which is not a valid PEP 440
+    version will be considered less than any valid PEP 440 version and the
+    invalid versions will continue sorting using the original algorithm.
+
+.. _yield_lines():
+
+``yield_lines(strs)``
+    Yield non-empty/non-comment lines from a string/unicode or a possibly-
+    nested sequence thereof.  If `strs` is an instance of ``basestring``, it
+    is split into lines, and each non-blank, non-comment line is yielded after
+    stripping leading and trailing whitespace.  (Lines whose first non-blank
+    character is ``#`` are considered comment lines.)
+
+    If `strs` is not an instance of ``basestring``, it is iterated over, and
+    each item is passed recursively to ``yield_lines()``, so that an arbitrarily
+    nested sequence of strings, or sequences of sequences of strings can be
+    flattened out to the lines contained therein.  So for example, passing
+    a file object or a list of strings to ``yield_lines`` will both work.
+    (Note that between each string in a sequence of strings there is assumed to
+    be an implicit line break, so lines cannot bridge two strings in a
+    sequence.)
+
+    This routine is used extensively by ``pkg_resources`` to parse metadata
+    and file formats of various kinds, and most other ``pkg_resources``
+    parsing functions that yield multiple values will use it to break up their
+    input.  However, this routine is idempotent, so calling ``yield_lines()``
+    on the output of another call to ``yield_lines()`` is completely harmless.
+
+``split_sections(strs)``
+    Split a string (or possibly-nested iterable thereof), yielding ``(section,
+    content)`` pairs found using an ``.ini``-like syntax.  Each ``section`` is
+    a whitespace-stripped version of the section name ("``[section]``")
+    and each ``content`` is a list of stripped lines excluding blank lines and
+    comment-only lines.  If there are any non-blank, non-comment lines before
+    the first section header, they're yielded in a first ``section`` of
+    ``None``.
+
+    This routine uses ``yield_lines()`` as its front end, so you can pass in
+    anything that ``yield_lines()`` accepts, such as an open text file, string,
+    or sequence of strings.  ``ValueError`` is raised if a malformed section
+    header is found (i.e. a line starting with ``[`` but not ending with
+    ``]``).
+
+    Note that this simplistic parser assumes that any line whose first nonblank
+    character is ``[`` is a section heading, so it can't support .ini format
+    variations that allow ``[`` as the first nonblank character on other lines.
+
+``safe_name(name)``
+    Return a "safe" form of a project's name, suitable for use in a
+    ``Requirement`` string, as a distribution name, or a PyPI project name.
+    All non-alphanumeric runs are condensed to single "-" characters, such that
+    a name like "The $$$ Tree" becomes "The-Tree".  Note that if you are
+    generating a filename from this value you should combine it with a call to
+    ``to_filename()`` so all dashes ("-") are replaced by underscores ("_").
+    See ``to_filename()``.
+
+``safe_version(version)``
+    This will return the normalized form of any PEP 440 version, if the version
+    string is not PEP 440 compatible than it is similar to ``safe_name()``
+    except that spaces in the input become dots, and dots are allowed to exist
+    in the output.  As with ``safe_name()``, if you are generating a filename
+    from this you should replace any "-" characters in the output with
+    underscores.
+
+``safe_extra(extra)``
+    Return a "safe" form of an extra's name, suitable for use in a requirement
+    string or a setup script's ``extras_require`` keyword.  This routine is
+    similar to ``safe_name()`` except that non-alphanumeric runs are replaced
+    by a single underbar (``_``), and the result is lowercased.
+
+``to_filename(name_or_version)``
+    Escape a name or version string so it can be used in a dash-separated
+    filename (or ``#egg=name-version`` tag) without ambiguity.  You
+    should only pass in values that were returned by ``safe_name()`` or
+    ``safe_version()``.
+
+
+Platform Utilities
+------------------
+
+``get_build_platform()``
+    Return this platform's identifier string.  For Windows, the return value
+    is ``"win32"``, and for Mac OS X it is a string of the form
+    ``"macosx-10.4-ppc"``.  All other platforms return the same uname-based
+    string that the ``distutils.util.get_platform()`` function returns.
+    This string is the minimum platform version required by distributions built
+    on the local machine.  (Backward compatibility note: setuptools versions
+    prior to 0.6b1 called this function ``get_platform()``, and the function is
+    still available under that name for backward compatibility reasons.)
+
+``get_supported_platform()`` (New in 0.6b1)
+    This is the similar to ``get_build_platform()``, but is the maximum
+    platform version that the local machine supports.  You will usually want
+    to use this value as the ``provided`` argument to the
+    ``compatible_platforms()`` function.
+
+``compatible_platforms(provided, required)``
+    Return true if a distribution built on the `provided` platform may be used
+    on the `required` platform.  If either platform value is ``None``, it is
+    considered a wildcard, and the platforms are therefore compatible.
+    Likewise, if the platform strings are equal, they're also considered
+    compatible, and ``True`` is returned.  Currently, the only non-equal
+    platform strings that are considered compatible are Mac OS X platform
+    strings with the same hardware type (e.g. ``ppc``) and major version
+    (e.g. ``10``) with the `provided` platform's minor version being less than
+    or equal to the `required` platform's minor version.
+
+``get_default_cache()``
+    Determine the default cache location for extracting resources from zipped
+    eggs.  This routine returns the ``PYTHON_EGG_CACHE`` environment variable,
+    if set.  Otherwise, on Windows, it returns a "Python-Eggs" subdirectory of
+    the user's "Application Data" directory.  On all other systems, it returns
+    ``os.path.expanduser("~/.python-eggs")`` if ``PYTHON_EGG_CACHE`` is not
+    set.
+
+
+PEP 302 Utilities
+-----------------
+
+``get_importer(path_item)``
+    A deprecated alias for ``pkgutil.get_importer()``
+
+
+File/Path Utilities
+-------------------
+
+``ensure_directory(path)``
+    Ensure that the parent directory (``os.path.dirname``) of `path` actually
+    exists, using ``os.makedirs()`` if necessary.
+
+``normalize_path(path)``
+    Return a "normalized" version of `path`, such that two paths represent
+    the same filesystem location if they have equal ``normalized_path()``
+    values.  Specifically, this is a shortcut for calling ``os.path.realpath``
+    and ``os.path.normcase`` on `path`.  Unfortunately, on certain platforms
+    (notably Cygwin and Mac OS X) the ``normcase`` function does not accurately
+    reflect the platform's case-sensitivity, so there is always the possibility
+    of two apparently-different paths being equal on such platforms.
+
+History
+-------
+
+0.6c9
+ * Fix ``resource_listdir('')`` always returning an empty list for zipped eggs.
+
+0.6c7
+ * Fix package precedence problem where single-version eggs installed in
+   ``site-packages`` would take precedence over ``.egg`` files (or directories)
+   installed in ``site-packages``.
+
+0.6c6
+ * Fix extracted C extensions not having executable permissions under Cygwin.
+
+ * Allow ``.egg-link`` files to contain relative paths.
+
+ * Fix cache dir defaults on Windows when multiple environment vars are needed
+   to construct a path.
+
+0.6c4
+ * Fix "dev" versions being considered newer than release candidates.
+
+0.6c3
+ * Python 2.5 compatibility fixes.
+
+0.6c2
+ * Fix a problem with eggs specified directly on ``PYTHONPATH`` on
+   case-insensitive filesystems possibly not showing up in the default
+   working set, due to differing normalizations of ``sys.path`` entries.
+
+0.6b3
+ * Fixed a duplicate path insertion problem on case-insensitive filesystems.
+
+0.6b1
+ * Split ``get_platform()`` into ``get_supported_platform()`` and
+   ``get_build_platform()`` to work around a Mac versioning problem that caused
+   the behavior of ``compatible_platforms()`` to be platform specific.
+
+ * Fix entry point parsing when a standalone module name has whitespace
+   between it and the extras.
+
+0.6a11
+ * Added ``ExtractionError`` and ``ResourceManager.extraction_error()`` so that
+   cache permission problems get a more user-friendly explanation of the
+   problem, and so that programs can catch and handle extraction errors if they
+   need to.
+
+0.6a10
+ * Added the ``extras`` attribute to ``Distribution``, the ``find_plugins()``
+   method to ``WorkingSet``, and the ``__add__()`` and ``__iadd__()`` methods
+   to ``Environment``.
+
+ * ``safe_name()`` now allows dots in project names.
+
+ * There is a new ``to_filename()`` function that escapes project names and
+   versions for safe use in constructing egg filenames from a Distribution
+   object's metadata.
+
+ * Added ``Distribution.clone()`` method, and keyword argument support to other
+   ``Distribution`` constructors.
+
+ * Added the ``DEVELOP_DIST`` precedence, and automatically assign it to
+   eggs using ``.egg-info`` format.
+
+0.6a9
+ * Don't raise an error when an invalid (unfinished) distribution is found
+   unless absolutely necessary.  Warn about skipping invalid/unfinished eggs
+   when building an Environment.
+
+ * Added support for ``.egg-info`` files or directories with version/platform
+   information embedded in the filename, so that system packagers have the
+   option of including ``PKG-INFO`` files to indicate the presence of a
+   system-installed egg, without needing to use ``.egg`` directories, zipfiles,
+   or ``.pth`` manipulation.
+
+ * Changed ``parse_version()`` to remove dashes before pre-release tags, so
+   that ``0.2-rc1`` is considered an *older* version than ``0.2``, and is equal
+   to ``0.2rc1``.  The idea that a dash *always* meant a post-release version
+   was highly non-intuitive to setuptools users and Python developers, who
+   seem to want to use ``-rc`` version numbers a lot.
+
+0.6a8
+ * Fixed a problem with ``WorkingSet.resolve()`` that prevented version
+   conflicts from being detected at runtime.
+
+ * Improved runtime conflict warning message to identify a line in the user's
+   program, rather than flagging the ``warn()`` call in ``pkg_resources``.
+
+ * Avoid giving runtime conflict warnings for namespace packages, even if they
+   were declared by a different package than the one currently being activated.
+
+ * Fix path insertion algorithm for case-insensitive filesystems.
+
+ * Fixed a problem with nested namespace packages (e.g. ``peak.util``) not
+   being set as an attribute of their parent package.
+
+0.6a6
+ * Activated distributions are now inserted in ``sys.path`` (and the working
+   set) just before the directory that contains them, instead of at the end.
+   This allows e.g. eggs in ``site-packages`` to override unmanaged modules in
+   the same location, and allows eggs found earlier on ``sys.path`` to override
+   ones found later.
+
+ * When a distribution is activated, it now checks whether any contained
+   non-namespace modules have already been imported and issues a warning if
+   a conflicting module has already been imported.
+
+ * Changed dependency processing so that it's breadth-first, allowing a
+   depender's preferences to override those of a dependee, to prevent conflicts
+   when a lower version is acceptable to the dependee, but not the depender.
+
+ * Fixed a problem extracting zipped files on Windows, when the egg in question
+   has had changed contents but still has the same version number.
+
+0.6a4
+ * Fix a bug in ``WorkingSet.resolve()`` that was introduced in 0.6a3.
+
+0.6a3
+ * Added ``safe_extra()`` parsing utility routine, and use it for Requirement,
+   EntryPoint, and Distribution objects' extras handling.
+
+0.6a1
+ * Enhanced performance of ``require()`` and related operations when all
+   requirements are already in the working set, and enhanced performance of
+   directory scanning for distributions.
+
+ * Fixed some problems using ``pkg_resources`` w/PEP 302 loaders other than
+   ``zipimport``, and the previously-broken "eager resource" support.
+
+ * Fixed ``pkg_resources.resource_exists()`` not working correctly, along with
+   some other resource API bugs.
+
+ * Many API changes and enhancements:
+
+   * Added ``EntryPoint``, ``get_entry_map``, ``load_entry_point``, and
+     ``get_entry_info`` APIs for dynamic plugin discovery.
+
+   * ``list_resources`` is now ``resource_listdir`` (and it actually works)
+
+   * Resource API functions like ``resource_string()`` that accepted a package
+     name and resource name, will now also accept a ``Requirement`` object in
+     place of the package name (to allow access to non-package data files in
+     an egg).
+
+   * ``get_provider()`` will now accept a ``Requirement`` instance or a module
+     name.  If it is given a ``Requirement``, it will return a corresponding
+     ``Distribution`` (by calling ``require()`` if a suitable distribution
+     isn't already in the working set), rather than returning a metadata and
+     resource provider for a specific module.  (The difference is in how
+     resource paths are interpreted; supplying a module name means resources
+     path will be module-relative, rather than relative to the distribution's
+     root.)
+
+   * ``Distribution`` objects now implement the ``IResourceProvider`` and
+     ``IMetadataProvider`` interfaces, so you don't need to reference the (no
+     longer available) ``metadata`` attribute to get at these interfaces.
+
+   * ``Distribution`` and ``Requirement`` both have a ``project_name``
+     attribute for the project name they refer to.  (Previously these were
+     ``name`` and ``distname`` attributes.)
+
+   * The ``path`` attribute of ``Distribution`` objects is now ``location``,
+     because it isn't necessarily a filesystem path (and hasn't been for some
+     time now).  The ``location`` of ``Distribution`` objects in the filesystem
+     should always be normalized using ``pkg_resources.normalize_path()``; all
+     of the setuptools and EasyInstall code that generates distributions from
+     the filesystem (including ``Distribution.from_filename()``) ensure this
+     invariant, but if you use a more generic API like ``Distribution()`` or
+     ``Distribution.from_location()`` you should take care that you don't
+     create a distribution with an un-normalized filesystem path.
+
+   * ``Distribution`` objects now have an ``as_requirement()`` method that
+     returns a ``Requirement`` for the distribution's project name and version.
+
+   * Distribution objects no longer have an ``installed_on()`` method, and the
+     ``install_on()`` method is now ``activate()`` (but may go away altogether
+     soon).  The ``depends()`` method has also been renamed to ``requires()``,
+     and ``InvalidOption`` is now ``UnknownExtra``.
+
+   * ``find_distributions()`` now takes an additional argument called ``only``,
+     that tells it to only yield distributions whose location is the passed-in
+     path.  (It defaults to False, so that the default behavior is unchanged.)
+
+   * ``AvailableDistributions`` is now called ``Environment``, and the
+     ``get()``, ``__len__()``, and ``__contains__()`` methods were removed,
+     because they weren't particularly useful.  ``__getitem__()`` no longer
+     raises ``KeyError``; it just returns an empty list if there are no
+     distributions for the named project.
+
+   * The ``resolve()`` method of ``Environment`` is now a method of
+     ``WorkingSet`` instead, and the ``best_match()`` method now uses a working
+     set instead of a path list as its second argument.
+
+   * There is a new ``pkg_resources.add_activation_listener()`` API that lets
+     you register a callback for notifications about distributions added to
+     ``sys.path`` (including the distributions already on it).  This is
+     basically a hook for extensible applications and frameworks to be able to
+     search for plugin metadata in distributions added at runtime.
+
+0.5a13
+ * Fixed a bug in resource extraction from nested packages in a zipped egg.
+
+0.5a12
+ * Updated extraction/cache mechanism for zipped resources to avoid inter-
+   process and inter-thread races during extraction.  The default cache
+   location can now be set via the ``PYTHON_EGGS_CACHE`` environment variable,
+   and the default Windows cache is now a ``Python-Eggs`` subdirectory of the
+   current user's "Application Data" directory, if the ``PYTHON_EGGS_CACHE``
+   variable isn't set.
+
+0.5a10
+ * Fix a problem with ``pkg_resources`` being confused by non-existent eggs on
+   ``sys.path`` (e.g. if a user deletes an egg without removing it from the
+   ``easy-install.pth`` file).
+
+ * Fix a problem with "basket" support in ``pkg_resources``, where egg-finding
+   never actually went inside ``.egg`` files.
+
+ * Made ``pkg_resources`` import the module you request resources from, if it's
+   not already imported.
+
+0.5a4
+ * ``pkg_resources.AvailableDistributions.resolve()`` and related methods now
+   accept an ``installer`` argument: a callable taking one argument, a
+   ``Requirement`` instance.  The callable must return a ``Distribution``
+   object, or ``None`` if no distribution is found.  This feature is used by
+   EasyInstall to resolve dependencies by recursively invoking itself.
+
+0.4a4
+ * Fix problems with ``resource_listdir()``, ``resource_isdir()`` and resource
+   directory extraction for zipped eggs.
+
+0.4a3
+ * Fixed scripts not being able to see a ``__file__`` variable in ``__main__``
+
+ * Fixed a problem with ``resource_isdir()`` implementation that was introduced
+   in 0.4a2.
+
+0.4a1
+ * Fixed a bug in requirements processing for exact versions (i.e. ``==`` and
+   ``!=``) when only one condition was included.
+
+ * Added ``safe_name()`` and ``safe_version()`` APIs to clean up handling of
+   arbitrary distribution names and versions found on PyPI.
+
+0.3a4
+ * ``pkg_resources`` now supports resource directories, not just the resources
+   in them.  In particular, there are ``resource_listdir()`` and
+   ``resource_isdir()`` APIs.
+
+ * ``pkg_resources`` now supports "egg baskets" -- .egg zipfiles which contain
+   multiple distributions in subdirectories whose names end with ``.egg``.
+   Having such a "basket" in a directory on ``sys.path`` is equivalent to
+   having the individual eggs in that directory, but the contained eggs can
+   be individually added (or not) to ``sys.path``.  Currently, however, there
+   is no automated way to create baskets.
+
+ * Namespace package manipulation is now protected by the Python import lock.
+
+0.3a1
+ * Initial release.
+
diff --git a/vendor/setuptools-39.0.1/docs/python3.txt b/vendor/setuptools-39.0.1/docs/python3.txt
new file mode 100644
index 00000000..d550cb68
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/python3.txt
@@ -0,0 +1,94 @@
+=====================================================
+Supporting both Python 2 and Python 3 with Setuptools
+=====================================================
+
+Starting with Distribute version 0.6.2 and Setuptools 0.7, the Setuptools
+project supported Python 3. Installing and
+using setuptools for Python 3 code works exactly the same as for Python 2
+code.
+
+Setuptools provides a facility to invoke 2to3 on the code as a part of the
+build process, by setting the keyword parameter ``use_2to3`` to True, but
+the Setuptools strongly recommends instead developing a unified codebase
+using `six <https://pypi.python.org/pypi/six>`_,
+`future <https://pypi.python.org/pypi/future>`_, or another compatibility
+library.
+
+
+Using 2to3
+==========
+
+Setuptools attempts to make the porting process easier by automatically
+running
+2to3 as a part of running tests. To do so, you need to configure the
+setup.py so that you can run the unit tests with ``python setup.py test``.
+
+See :ref:`test` for more information on this.
+
+Once you have the tests running under Python 2, you can add the use_2to3
+keyword parameters to setup(), and start running the tests under Python 3.
+The test command will now first run the build command during which the code
+will be converted with 2to3, and the tests will then be run from the build
+directory, as opposed from the source directory as is normally done.
+
+Setuptools will convert all Python files, and also all doctests in Python
+files. However, if you have doctests located in separate text files, these
+will not automatically be converted. By adding them to the
+``convert_2to3_doctests`` keyword parameter Setuptools will convert them as
+well.
+
+By default, the conversion uses all fixers in the ``lib2to3.fixers`` package.
+To use additional fixers, the parameter ``use_2to3_fixers`` can be set
+to a list of names of packages containing fixers. To exclude fixers, the
+parameter ``use_2to3_exclude_fixers`` can be set to fixer names to be
+skipped.
+
+An example setup.py might look something like this::
+
+    from setuptools import setup
+
+    setup(
+        name='your.module',
+        version='1.0',
+        description='This is your awesome module',
+        author='You',
+        author_email='your@email',
+        package_dir={'': 'src'},
+        packages=['your', 'you.module'],
+        test_suite='your.module.tests',
+        use_2to3=True,
+        convert_2to3_doctests=['src/your/module/README.txt'],
+        use_2to3_fixers=['your.fixers'],
+        use_2to3_exclude_fixers=['lib2to3.fixes.fix_import'],
+    )
+
+Differential conversion
+-----------------------
+
+Note that a file will only be copied and converted during the build process
+if the source file has been changed. If you add a file to the doctests
+that should be converted, it will not be converted the next time you run
+the tests, since it hasn't been modified. You need to remove it from the
+build directory. Also if you run the build, install or test commands before
+adding the use_2to3 parameter, you will have to remove the build directory
+before you run the test command, as the files otherwise will seem updated,
+and no conversion will happen.
+
+In general, if code doesn't seem to be converted, deleting the build directory
+and trying again is a good safeguard against the build directory getting
+"out of sync" with the source directory.
+
+Distributing Python 3 modules
+=============================
+
+You can distribute your modules with Python 3 support in different ways. A
+normal source distribution will work, but can be slow in installing, as the
+2to3 process will be run during the install. But you can also distribute
+the module in binary format, such as a binary egg. That egg will contain the
+already converted code, and hence no 2to3 conversion is needed during install.
+
+Advanced features
+=================
+
+If you don't want to run the 2to3 conversion on the doctests in Python files,
+you can turn that off by setting ``setuptools.use_2to3_on_doctests = False``.
diff --git a/vendor/setuptools-39.0.1/docs/releases.txt b/vendor/setuptools-39.0.1/docs/releases.txt
new file mode 100644
index 00000000..30ea084f
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/releases.txt
@@ -0,0 +1,48 @@
+===============
+Release Process
+===============
+
+In order to allow for rapid, predictable releases, Setuptools uses a
+mechanical technique for releases, enacted by Travis following a
+successful build of a tagged release per
+`PyPI deployment <https://docs.travis-ci.com/user/deployment/pypi>`_.
+
+Prior to cutting a release, please check that the CHANGES.rst reflects
+the summary of changes since the last release.
+Ideally, these changelog entries would have been added
+along with the changes, but it's always good to check.
+Think about it from the
+perspective of a user not involved with the development--what would
+that person want to know about what has changed--or from the
+perspective of your future self wanting to know when a particular
+change landed.
+
+To cut a release, install and run ``bump2version {part}`` where ``part``
+is major, minor, or patch based on the scope of the changes in the
+release. Then, push the commits to the master branch. If tests pass,
+the release will be uploaded to PyPI (from the Python 3.6 tests).
+
+Release Frequency
+-----------------
+
+Some have asked why Setuptools is released so frequently. Because Setuptools
+uses a mechanical release process, it's very easy to make releases whenever the
+code is stable (tests are passing). As a result, the philosophy is to release
+early and often.
+
+While some find the frequent releases somewhat surprising, they only empower
+the user. Although releases are made frequently, users can choose the frequency
+at which they use those releases. If instead Setuptools contributions were only
+released in batches, the user would be constrained to only use Setuptools when
+those official releases were made. With frequent releases, the user can govern
+exactly how often he wishes to update.
+
+Frequent releases also then obviate the need for dev or beta releases in most
+cases. Because releases are made early and often, bugs are discovered and
+corrected quickly, in many cases before other users have yet to encounter them.
+
+Release Managers
+----------------
+
+Additionally, anyone with push access to the master branch has access to cut
+releases.
diff --git a/vendor/setuptools-39.0.1/docs/requirements.txt b/vendor/setuptools-39.0.1/docs/requirements.txt
new file mode 100644
index 00000000..2138c884
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/requirements.txt
@@ -0,0 +1,5 @@
+sphinx
+rst.linker>=1.9
+jaraco.packaging>=3.2
+
+setuptools>=34
diff --git a/vendor/setuptools-39.0.1/docs/roadmap.txt b/vendor/setuptools-39.0.1/docs/roadmap.txt
new file mode 100644
index 00000000..8f175b9f
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/roadmap.txt
@@ -0,0 +1,6 @@
+=======
+Roadmap
+=======
+
+Setuptools is primarily in maintenance mode. The project attempts to address
+user issues, concerns, and feature requests in a timely fashion.
diff --git a/vendor/setuptools-39.0.1/docs/setuptools.txt b/vendor/setuptools-39.0.1/docs/setuptools.txt
new file mode 100644
index 00000000..65080a0b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/docs/setuptools.txt
@@ -0,0 +1,2775 @@
+==================================================
+Building and Distributing Packages with Setuptools
+==================================================
+
+``Setuptools`` is a collection of enhancements to the Python ``distutils``
+that allow developers to more easily build and
+distribute Python packages, especially ones that have dependencies on other
+packages.
+
+Packages built and distributed using ``setuptools`` look to the user like
+ordinary Python packages based on the ``distutils``.  Your users don't need to
+install or even know about setuptools in order to use them, and you don't
+have to include the entire setuptools package in your distributions.  By
+including just a single `bootstrap module`_ (a 12K .py file), your package will
+automatically download and install ``setuptools`` if the user is building your
+package from source and doesn't have a suitable version already installed.
+
+.. _bootstrap module: https://bootstrap.pypa.io/ez_setup.py
+
+Feature Highlights:
+
+* Automatically find/download/install/upgrade dependencies at build time using
+  the `EasyInstall tool <easy_install.html>`_,
+  which supports downloading via HTTP, FTP, Subversion, and SourceForge, and
+  automatically scans web pages linked from PyPI to find download links.  (It's
+  the closest thing to CPAN currently available for Python.)
+
+* Create `Python Eggs <http://peak.telecommunity.com/DevCenter/PythonEggs>`_ -
+  a single-file importable distribution format
+
+* Enhanced support for accessing data files hosted in zipped packages.
+
+* Automatically include all packages in your source tree, without listing them
+  individually in setup.py
+
+* Automatically include all relevant files in your source distributions,
+  without needing to create a ``MANIFEST.in`` file, and without having to force
+  regeneration of the ``MANIFEST`` file when your source tree changes.
+
+* Automatically generate wrapper scripts or Windows (console and GUI) .exe
+  files for any number of "main" functions in your project.  (Note: this is not
+  a py2exe replacement; the .exe files rely on the local Python installation.)
+
+* Transparent Pyrex support, so that your setup.py can list ``.pyx`` files and
+  still work even when the end-user doesn't have Pyrex installed (as long as
+  you include the Pyrex-generated C in your source distribution)
+
+* Command aliases - create project-specific, per-user, or site-wide shortcut
+  names for commonly used commands and options
+
+* PyPI upload support - upload your source distributions and eggs to PyPI
+
+* Deploy your project in "development mode", such that it's available on
+  ``sys.path``, yet can still be edited directly from its source checkout.
+
+* Easily extend the distutils with new commands or ``setup()`` arguments, and
+  distribute/reuse your extensions for multiple projects, without copying code.
+
+* Create extensible applications and frameworks that automatically discover
+  extensions, using simple "entry points" declared in a project's setup script.
+
+.. contents:: **Table of Contents**
+
+.. _ez_setup.py: `bootstrap module`_
+
+
+-----------------
+Developer's Guide
+-----------------
+
+
+Installing ``setuptools``
+=========================
+
+Please follow the `EasyInstall Installation Instructions`_ to install the
+current stable version of setuptools.  In particular, be sure to read the
+section on `Custom Installation Locations`_ if you are installing anywhere
+other than Python's ``site-packages`` directory.
+
+.. _EasyInstall Installation Instructions: easy_install.html#installation-instructions
+
+.. _Custom Installation Locations: easy_install.html#custom-installation-locations
+
+If you want the current in-development version of setuptools, you should first
+install a stable version, and then run::
+
+    ez_setup.py setuptools==dev
+
+This will download and install the latest development (i.e. unstable) version
+of setuptools from the Python Subversion sandbox.
+
+
+Basic Use
+=========
+
+For basic use of setuptools, just import things from setuptools instead of
+the distutils.  Here's a minimal setup script using setuptools::
+
+    from setuptools import setup, find_packages
+    setup(
+        name="HelloWorld",
+        version="0.1",
+        packages=find_packages(),
+    )
+
+As you can see, it doesn't take much to use setuptools in a project.
+Run that script in your project folder, alongside the Python packages
+you have developed.
+
+Invoke that script to produce eggs, upload to
+PyPI, and automatically include all packages in the directory where the
+setup.py lives.  See the `Command Reference`_ section below to see what
+commands you can give to this setup script. For example,
+to produce a source distribution, simply invoke::
+
+    python setup.py sdist
+
+Of course, before you release your project to PyPI, you'll want to add a bit
+more information to your setup script to help people find or learn about your
+project.  And maybe your project will have grown by then to include a few
+dependencies, and perhaps some data files and scripts::
+
+    from setuptools import setup, find_packages
+    setup(
+        name="HelloWorld",
+        version="0.1",
+        packages=find_packages(),
+        scripts=['say_hello.py'],
+
+        # Project uses reStructuredText, so ensure that the docutils get
+        # installed or upgraded on the target machine
+        install_requires=['docutils>=0.3'],
+
+        package_data={
+            # If any package contains *.txt or *.rst files, include them:
+            '': ['*.txt', '*.rst'],
+            # And include any *.msg files found in the 'hello' package, too:
+            'hello': ['*.msg'],
+        },
+
+        # metadata for upload to PyPI
+        author="Me",
+        author_email="me@example.com",
+        description="This is an Example Package",
+        license="PSF",
+        keywords="hello world example examples",
+        url="http://example.com/HelloWorld/",   # project home page, if any
+        project_urls={
+            "Bug Tracker": "https://bugs.example.com/HelloWorld/",
+            "Documentation": "https://docs.example.com/HelloWorld/",
+            "Source Code": "https://code.example.com/HelloWorld/",
+        }
+
+        # could also include long_description, download_url, classifiers, etc.
+    )
+
+In the sections that follow, we'll explain what most of these ``setup()``
+arguments do (except for the metadata ones), and the various ways you might use
+them in your own project(s).
+
+
+Specifying Your Project's Version
+---------------------------------
+
+Setuptools can work well with most versioning schemes; there are, however, a
+few special things to watch out for, in order to ensure that setuptools and
+EasyInstall can always tell what version of your package is newer than another
+version.  Knowing these things will also help you correctly specify what
+versions of other projects your project depends on.
+
+A version consists of an alternating series of release numbers and pre-release
+or post-release tags.  A release number is a series of digits punctuated by
+dots, such as ``2.4`` or ``0.5``.  Each series of digits is treated
+numerically, so releases ``2.1`` and ``2.1.0`` are different ways to spell the
+same release number, denoting the first subrelease of release 2.  But  ``2.10``
+is the *tenth* subrelease of release 2, and so is a different and newer release
+from ``2.1`` or ``2.1.0``.  Leading zeros within a series of digits are also
+ignored, so ``2.01`` is the same as ``2.1``, and different from ``2.0.1``.
+
+Following a release number, you can have either a pre-release or post-release
+tag.  Pre-release tags make a version be considered *older* than the version
+they are appended to.  So, revision ``2.4`` is *newer* than revision ``2.4c1``,
+which in turn is newer than ``2.4b1`` or ``2.4a1``.  Postrelease tags make
+a version be considered *newer* than the version they are appended to.  So,
+revisions like ``2.4-1`` and ``2.4pl3`` are newer than ``2.4``, but are *older*
+than ``2.4.1`` (which has a higher release number).
+
+A pre-release tag is a series of letters that are alphabetically before
+"final".  Some examples of prerelease tags would include ``alpha``, ``beta``,
+``a``, ``c``, ``dev``, and so on.  You do not have to place a dot or dash
+before the prerelease tag if it's immediately after a number, but it's okay to
+do so if you prefer.  Thus, ``2.4c1`` and ``2.4.c1`` and ``2.4-c1`` all
+represent release candidate 1 of version ``2.4``, and are treated as identical
+by setuptools.
+
+In addition, there are three special prerelease tags that are treated as if
+they were the letter ``c``: ``pre``, ``preview``, and ``rc``.  So, version
+``2.4rc1``, ``2.4pre1`` and ``2.4preview1`` are all the exact same version as
+``2.4c1``, and are treated as identical by setuptools.
+
+A post-release tag is either a series of letters that are alphabetically
+greater than or equal to "final", or a dash (``-``).  Post-release tags are
+generally used to separate patch numbers, port numbers, build numbers, revision
+numbers, or date stamps from the release number.  For example, the version
+``2.4-r1263`` might denote Subversion revision 1263 of a post-release patch of
+version ``2.4``.  Or you might use ``2.4-20051127`` to denote a date-stamped
+post-release.
+
+Notice that after each pre or post-release tag, you are free to place another
+release number, followed again by more pre- or post-release tags.  For example,
+``0.6a9.dev-r41475`` could denote Subversion revision 41475 of the in-
+development version of the ninth alpha of release 0.6.  Notice that ``dev`` is
+a pre-release tag, so this version is a *lower* version number than ``0.6a9``,
+which would be the actual ninth alpha of release 0.6.  But the ``-r41475`` is
+a post-release tag, so this version is *newer* than ``0.6a9.dev``.
+
+For the most part, setuptools' interpretation of version numbers is intuitive,
+but here are a few tips that will keep you out of trouble in the corner cases:
+
+* Don't stick adjoining pre-release tags together without a dot or number
+  between them.  Version ``1.9adev`` is the ``adev`` prerelease of ``1.9``,
+  *not* a development pre-release of ``1.9a``.  Use ``.dev`` instead, as in
+  ``1.9a.dev``, or separate the prerelease tags with a number, as in
+  ``1.9a0dev``.  ``1.9a.dev``, ``1.9a0dev``, and even ``1.9.a.dev`` are
+  identical versions from setuptools' point of view, so you can use whatever
+  scheme you prefer.
+
+* If you want to be certain that your chosen numbering scheme works the way
+  you think it will, you can use the ``pkg_resources.parse_version()`` function
+  to compare different version numbers::
+
+    >>> from pkg_resources import parse_version
+    >>> parse_version('1.9.a.dev') == parse_version('1.9a0dev')
+    True
+    >>> parse_version('2.1-rc2') < parse_version('2.1')
+    True
+    >>> parse_version('0.6a9dev-r41475') < parse_version('0.6a9')
+    True
+
+Once you've decided on a version numbering scheme for your project, you can
+have setuptools automatically tag your in-development releases with various
+pre- or post-release tags.  See the following sections for more details:
+
+* `Tagging and "Daily Build" or "Snapshot" Releases`_
+* `Managing "Continuous Releases" Using Subversion`_
+* The `egg_info`_ command
+
+
+New and Changed ``setup()`` Keywords
+====================================
+
+The following keyword arguments to ``setup()`` are added or changed by
+``setuptools``.  All of them are optional; you do not have to supply them
+unless you need the associated ``setuptools`` feature.
+
+``include_package_data``
+    If set to ``True``, this tells ``setuptools`` to automatically include any
+    data files it finds inside your package directories that are specified by
+    your ``MANIFEST.in`` file.  For more information, see the section below on
+    `Including Data Files`_.
+
+``exclude_package_data``
+    A dictionary mapping package names to lists of glob patterns that should
+    be *excluded* from your package directories.  You can use this to trim back
+    any excess files included by ``include_package_data``.  For a complete
+    description and examples, see the section below on `Including Data Files`_.
+
+``package_data``
+    A dictionary mapping package names to lists of glob patterns.  For a
+    complete description and examples, see the section below on `Including
+    Data Files`_.  You do not need to use this option if you are using
+    ``include_package_data``, unless you need to add e.g. files that are
+    generated by your setup script and build process.  (And are therefore not
+    in source control or are files that you don't want to include in your
+    source distribution.)
+
+``zip_safe``
+    A boolean (True or False) flag specifying whether the project can be
+    safely installed and run from a zip file.  If this argument is not
+    supplied, the ``bdist_egg`` command will have to analyze all of your
+    project's contents for possible problems each time it builds an egg.
+
+``install_requires``
+    A string or list of strings specifying what other distributions need to
+    be installed when this one is.  See the section below on `Declaring
+    Dependencies`_ for details and examples of the format of this argument.
+
+``entry_points``
+    A dictionary mapping entry point group names to strings or lists of strings
+    defining the entry points.  Entry points are used to support dynamic
+    discovery of services or plugins provided by a project.  See `Dynamic
+    Discovery of Services and Plugins`_ for details and examples of the format
+    of this argument.  In addition, this keyword is used to support `Automatic
+    Script Creation`_.
+
+``extras_require``
+    A dictionary mapping names of "extras" (optional features of your project)
+    to strings or lists of strings specifying what other distributions must be
+    installed to support those features.  See the section below on `Declaring
+    Dependencies`_ for details and examples of the format of this argument.
+
+``python_requires``
+    A string corresponding to a version specifier (as defined in PEP 440) for
+    the Python version, used to specify the Requires-Python defined in PEP 345.
+
+``setup_requires``
+    A string or list of strings specifying what other distributions need to
+    be present in order for the *setup script* to run.  ``setuptools`` will
+    attempt to obtain these (even going so far as to download them using
+    ``EasyInstall``) before processing the rest of the setup script or commands.
+    This argument is needed if you are using distutils extensions as part of
+    your build process; for example, extensions that process setup() arguments
+    and turn them into EGG-INFO metadata files.
+
+    (Note: projects listed in ``setup_requires`` will NOT be automatically
+    installed on the system where the setup script is being run.  They are
+    simply downloaded to the ./.eggs directory if they're not locally available
+    already.  If you want them to be installed, as well as being available
+    when the setup script is run, you should add them to ``install_requires``
+    **and** ``setup_requires``.)
+
+``dependency_links``
+    A list of strings naming URLs to be searched when satisfying dependencies.
+    These links will be used if needed to install packages specified by
+    ``setup_requires`` or ``tests_require``.  They will also be written into
+    the egg's metadata for use by tools like EasyInstall to use when installing
+    an ``.egg`` file.
+
+``namespace_packages``
+    A list of strings naming the project's "namespace packages".  A namespace
+    package is a package that may be split across multiple project
+    distributions.  For example, Zope 3's ``zope`` package is a namespace
+    package, because subpackages like ``zope.interface`` and ``zope.publisher``
+    may be distributed separately.  The egg runtime system can automatically
+    merge such subpackages into a single parent package at runtime, as long
+    as you declare them in each project that contains any subpackages of the
+    namespace package, and as long as the namespace package's ``__init__.py``
+    does not contain any code other than a namespace declaration.  See the
+    section below on `Namespace Packages`_ for more information.
+
+``test_suite``
+    A string naming a ``unittest.TestCase`` subclass (or a package or module
+    containing one or more of them, or a method of such a subclass), or naming
+    a function that can be called with no arguments and returns a
+    ``unittest.TestSuite``.  If the named suite is a module, and the module
+    has an ``additional_tests()`` function, it is called and the results are
+    added to the tests to be run.  If the named suite is a package, any
+    submodules and subpackages are recursively added to the overall test suite.
+
+    Specifying this argument enables use of the `test`_ command to run the
+    specified test suite, e.g. via ``setup.py test``.  See the section on the
+    `test`_ command below for more details.
+
+``tests_require``
+    If your project's tests need one or more additional packages besides those
+    needed to install it, you can use this option to specify them.  It should
+    be a string or list of strings specifying what other distributions need to
+    be present for the package's tests to run.  When you run the ``test``
+    command, ``setuptools`` will  attempt to obtain these (even going
+    so far as to download them using ``EasyInstall``).  Note that these
+    required projects will *not* be installed on the system where the tests
+    are run, but only downloaded to the project's setup directory if they're
+    not already installed locally.
+
+.. _test_loader:
+
+``test_loader``
+    If you would like to use a different way of finding tests to run than what
+    setuptools normally uses, you can specify a module name and class name in
+    this argument.  The named class must be instantiable with no arguments, and
+    its instances must support the ``loadTestsFromNames()`` method as defined
+    in the Python ``unittest`` module's ``TestLoader`` class.  Setuptools will
+    pass only one test "name" in the `names` argument: the value supplied for
+    the ``test_suite`` argument.  The loader you specify may interpret this
+    string in any way it likes, as there are no restrictions on what may be
+    contained in a ``test_suite`` string.
+
+    The module name and class name must be separated by a ``:``.  The default
+    value of this argument is ``"setuptools.command.test:ScanningLoader"``.  If
+    you want to use the default ``unittest`` behavior, you can specify
+    ``"unittest:TestLoader"`` as your ``test_loader`` argument instead.  This
+    will prevent automatic scanning of submodules and subpackages.
+
+    The module and class you specify here may be contained in another package,
+    as long as you use the ``tests_require`` option to ensure that the package
+    containing the loader class is available when the ``test`` command is run.
+
+``eager_resources``
+    A list of strings naming resources that should be extracted together, if
+    any of them is needed, or if any C extensions included in the project are
+    imported.  This argument is only useful if the project will be installed as
+    a zipfile, and there is a need to have all of the listed resources be
+    extracted to the filesystem *as a unit*.  Resources listed here
+    should be '/'-separated paths, relative to the source root, so to list a
+    resource ``foo.png`` in package ``bar.baz``, you would include the string
+    ``bar/baz/foo.png`` in this argument.
+
+    If you only need to obtain resources one at a time, or you don't have any C
+    extensions that access other files in the project (such as data files or
+    shared libraries), you probably do NOT need this argument and shouldn't
+    mess with it.  For more details on how this argument works, see the section
+    below on `Automatic Resource Extraction`_.
+
+``use_2to3``
+    Convert the source code from Python 2 to Python 3 with 2to3 during the
+    build process. See :doc:`python3` for more details.
+
+``convert_2to3_doctests``
+    List of doctest source files that need to be converted with 2to3.
+    See :doc:`python3` for more details.
+
+``use_2to3_fixers``
+    A list of modules to search for additional fixers to be used during
+    the 2to3 conversion. See :doc:`python3` for more details.
+
+``project_urls``
+    An arbitrary map of URL names to hyperlinks, allowing more extensible
+    documentation of where various resources can be found than the simple
+    ``url`` and ``download_url`` options provide.
+
+
+Using ``find_packages()``
+-------------------------
+
+For simple projects, it's usually easy enough to manually add packages to
+the ``packages`` argument of ``setup()``.  However, for very large projects
+(Twisted, PEAK, Zope, Chandler, etc.), it can be a big burden to keep the
+package list updated.  That's what ``setuptools.find_packages()`` is for.
+
+``find_packages()`` takes a source directory and two lists of package name
+patterns to exclude and include.  If omitted, the source directory defaults to
+the same
+directory as the setup script.  Some projects use a ``src`` or ``lib``
+directory as the root of their source tree, and those projects would of course
+use ``"src"`` or ``"lib"`` as the first argument to ``find_packages()``.  (And
+such projects also need something like ``package_dir={'':'src'}`` in their
+``setup()`` arguments, but that's just a normal distutils thing.)
+
+Anyway, ``find_packages()`` walks the target directory, filtering by inclusion
+patterns, and finds Python packages (any directory). Packages are only
+recognized if they include an ``__init__.py`` file. Finally, exclusion 
+patterns are applied to remove matching packages.
+
+Inclusion and exclusion patterns are package names, optionally including
+wildcards.  For
+example, ``find_packages(exclude=["*.tests"])`` will exclude all packages whose
+last name part is ``tests``.   Or, ``find_packages(exclude=["*.tests",
+"*.tests.*"])`` will also exclude any subpackages of packages named ``tests``,
+but it still won't exclude a top-level ``tests`` package or the children
+thereof.  In fact, if you really want no ``tests`` packages at all, you'll need
+something like this::
+
+    find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"])
+
+in order to cover all the bases.  Really, the exclusion patterns are intended
+to cover simpler use cases than this, like excluding a single, specified
+package and its subpackages.
+
+Regardless of the parameters, the ``find_packages()``
+function returns a list of package names suitable for use as the ``packages``
+argument to ``setup()``, and so is usually the easiest way to set that
+argument in your setup script.  Especially since it frees you from having to
+remember to modify your setup script whenever your project grows additional
+top-level packages or subpackages.
+
+
+Automatic Script Creation
+=========================
+
+Packaging and installing scripts can be a bit awkward with the distutils.  For
+one thing, there's no easy way to have a script's filename match local
+conventions on both Windows and POSIX platforms.  For another, you often have
+to create a separate file just for the "main" script, when your actual "main"
+is a function in a module somewhere.  And even in Python 2.4, using the ``-m``
+option only works for actual ``.py`` files that aren't installed in a package.
+
+``setuptools`` fixes all of these problems by automatically generating scripts
+for you with the correct extension, and on Windows it will even create an
+``.exe`` file so that users don't have to change their ``PATHEXT`` settings.
+The way to use this feature is to define "entry points" in your setup script
+that indicate what function the generated script should import and run.  For
+example, to create two console scripts called ``foo`` and ``bar``, and a GUI
+script called ``baz``, you might do something like this::
+
+    setup(
+        # other arguments here...
+        entry_points={
+            'console_scripts': [
+                'foo = my_package.some_module:main_func',
+                'bar = other_module:some_func',
+            ],
+            'gui_scripts': [
+                'baz = my_package_gui:start_func',
+            ]
+        }
+    )
+
+When this project is installed on non-Windows platforms (using "setup.py
+install", "setup.py develop", or by using EasyInstall), a set of ``foo``,
+``bar``, and ``baz`` scripts will be installed that import ``main_func`` and
+``some_func`` from the specified modules.  The functions you specify are called
+with no arguments, and their return value is passed to ``sys.exit()``, so you
+can return an errorlevel or message to print to stderr.
+
+On Windows, a set of ``foo.exe``, ``bar.exe``, and ``baz.exe`` launchers are
+created, alongside a set of ``foo.py``, ``bar.py``, and ``baz.pyw`` files.  The
+``.exe`` wrappers find and execute the right version of Python to run the
+``.py`` or ``.pyw`` file.
+
+You may define as many "console script" and "gui script" entry points as you
+like, and each one can optionally specify "extras" that it depends on, that
+will be added to ``sys.path`` when the script is run.  For more information on
+"extras", see the section below on `Declaring Extras`_.  For more information
+on "entry points" in general, see the section below on `Dynamic Discovery of
+Services and Plugins`_.
+
+
+"Eggsecutable" Scripts
+----------------------
+
+Occasionally, there are situations where it's desirable to make an ``.egg``
+file directly executable.  You can do this by including an entry point such
+as the following::
+
+    setup(
+        # other arguments here...
+        entry_points={
+            'setuptools.installation': [
+                'eggsecutable = my_package.some_module:main_func',
+            ]
+        }
+    )
+
+Any eggs built from the above setup script will include a short executable
+prelude that imports and calls ``main_func()`` from ``my_package.some_module``.
+The prelude can be run on Unix-like platforms (including Mac and Linux) by
+invoking the egg with ``/bin/sh``, or by enabling execute permissions on the
+``.egg`` file.  For the executable prelude to run, the appropriate version of
+Python must be available via the ``PATH`` environment variable, under its
+"long" name.  That is, if the egg is built for Python 2.3, there must be a
+``python2.3`` executable present in a directory on ``PATH``.
+
+This feature is primarily intended to support ez_setup the installation of
+setuptools itself on non-Windows platforms, but may also be useful for other
+projects as well.
+
+IMPORTANT NOTE: Eggs with an "eggsecutable" header cannot be renamed, or
+invoked via symlinks.  They *must* be invoked using their original filename, in
+order to ensure that, once running, ``pkg_resources`` will know what project
+and version is in use.  The header script will check this and exit with an
+error if the ``.egg`` file has been renamed or is invoked via a symlink that
+changes its base name.
+
+
+Declaring Dependencies
+======================
+
+``setuptools`` supports automatically installing dependencies when a package is
+installed, and including information about dependencies in Python Eggs (so that
+package management tools like EasyInstall can use the information).
+
+``setuptools`` and ``pkg_resources`` use a common syntax for specifying a
+project's required dependencies.  This syntax consists of a project's PyPI
+name, optionally followed by a comma-separated list of "extras" in square
+brackets, optionally followed by a comma-separated list of version
+specifiers.  A version specifier is one of the operators ``<``, ``>``, ``<=``,
+``>=``, ``==`` or ``!=``, followed by a version identifier.  Tokens may be
+separated by whitespace, but any whitespace or nonstandard characters within a
+project name or version identifier must be replaced with ``-``.
+
+Version specifiers for a given project are internally sorted into ascending
+version order, and used to establish what ranges of versions are acceptable.
+Adjacent redundant conditions are also consolidated (e.g. ``">1, >2"`` becomes
+``">2"``, and ``"<2,<3"`` becomes ``"<2"``). ``"!="`` versions are excised from
+the ranges they fall within.  A project's version is then checked for
+membership in the resulting ranges. (Note that providing conflicting conditions
+for the same version (e.g. "<2,>=2" or "==2,!=2") is meaningless and may
+therefore produce bizarre results.)
+
+Here are some example requirement specifiers::
+
+    docutils >= 0.3
+
+    # comment lines and \ continuations are allowed in requirement strings
+    BazSpam ==1.1, ==1.2, ==1.3, ==1.4, ==1.5, \
+        ==1.6, ==1.7  # and so are line-end comments
+
+    PEAK[FastCGI, reST]>=0.5a4
+
+    setuptools==0.5a7
+
+The simplest way to include requirement specifiers is to use the
+``install_requires`` argument to ``setup()``.  It takes a string or list of
+strings containing requirement specifiers.  If you include more than one
+requirement in a string, each requirement must begin on a new line.
+
+This has three effects:
+
+1. When your project is installed, either by using EasyInstall, ``setup.py
+   install``, or ``setup.py develop``, all of the dependencies not already
+   installed will be located (via PyPI), downloaded, built (if necessary),
+   and installed.
+
+2. Any scripts in your project will be installed with wrappers that verify
+   the availability of the specified dependencies at runtime, and ensure that
+   the correct versions are added to ``sys.path`` (e.g. if multiple versions
+   have been installed).
+
+3. Python Egg distributions will include a metadata file listing the
+   dependencies.
+
+Note, by the way, that if you declare your dependencies in ``setup.py``, you do
+*not* need to use the ``require()`` function in your scripts or modules, as
+long as you either install the project or use ``setup.py develop`` to do
+development work on it.  (See `"Development Mode"`_ below for more details on
+using ``setup.py develop``.)
+
+
+Dependencies that aren't in PyPI
+--------------------------------
+
+If your project depends on packages that aren't registered in PyPI, you may
+still be able to depend on them, as long as they are available for download
+as:
+
+- an egg, in the standard distutils ``sdist`` format,
+- a single ``.py`` file, or
+- a VCS repository (Subversion, Mercurial, or Git).
+
+You just need to add some URLs to the ``dependency_links`` argument to
+``setup()``.
+
+The URLs must be either:
+
+1. direct download URLs,
+2. the URLs of web pages that contain direct download links, or
+3. the repository's URL
+
+In general, it's better to link to web pages, because it is usually less
+complex to update a web page than to release a new version of your project.
+You can also use a SourceForge ``showfiles.php`` link in the case where a
+package you depend on is distributed via SourceForge.
+
+If you depend on a package that's distributed as a single ``.py`` file, you
+must include an ``"#egg=project-version"`` suffix to the URL, to give a project
+name and version number.  (Be sure to escape any dashes in the name or version
+by replacing them with underscores.)  EasyInstall will recognize this suffix
+and automatically create a trivial ``setup.py`` to wrap the single ``.py`` file
+as an egg.
+
+In the case of a VCS checkout, you should also append ``#egg=project-version``
+in order to identify for what package that checkout should be used. You can
+append ``@REV`` to the URL's path (before the fragment) to specify a revision.
+Additionally, you can also force the VCS being used by prepending the URL with
+a certain prefix. Currently available are:
+
+-  ``svn+URL`` for Subversion,
+-  ``git+URL`` for Git, and
+-  ``hg+URL`` for Mercurial
+
+A more complete example would be:
+
+    ``vcs+proto://host/path@revision#egg=project-version``
+
+Be careful with the version. It should match the one inside the project files.
+If you want to disregard the version, you have to omit it both in the
+``requires`` and in the URL's fragment.
+
+This will do a checkout (or a clone, in Git and Mercurial parlance) to a
+temporary folder and run ``setup.py bdist_egg``.
+
+The ``dependency_links`` option takes the form of a list of URL strings.  For
+example, the below will cause EasyInstall to search the specified page for
+eggs or source distributions, if the package's dependencies aren't already
+installed::
+
+    setup(
+        ...
+        dependency_links=[
+            "http://peak.telecommunity.com/snapshots/"
+        ],
+    )
+
+
+.. _Declaring Extras:
+
+
+Declaring "Extras" (optional features with their own dependencies)
+------------------------------------------------------------------
+
+Sometimes a project has "recommended" dependencies, that are not required for
+all uses of the project.  For example, a project might offer optional PDF
+output if ReportLab is installed, and reStructuredText support if docutils is
+installed.  These optional features are called "extras", and setuptools allows
+you to define their requirements as well.  In this way, other projects that
+require these optional features can force the additional requirements to be
+installed, by naming the desired extras in their ``install_requires``.
+
+For example, let's say that Project A offers optional PDF and reST support::
+
+    setup(
+        name="Project-A",
+        ...
+        extras_require={
+            'PDF':  ["ReportLab>=1.2", "RXP"],
+            'reST': ["docutils>=0.3"],
+        }
+    )
+
+As you can see, the ``extras_require`` argument takes a dictionary mapping
+names of "extra" features, to strings or lists of strings describing those
+features' requirements.  These requirements will *not* be automatically
+installed unless another package depends on them (directly or indirectly) by
+including the desired "extras" in square brackets after the associated project
+name.  (Or if the extras were listed in a requirement spec on the EasyInstall
+command line.)
+
+Extras can be used by a project's `entry points`_ to specify dynamic
+dependencies.  For example, if Project A includes a "rst2pdf" script, it might
+declare it like this, so that the "PDF" requirements are only resolved if the
+"rst2pdf" script is run::
+
+    setup(
+        name="Project-A",
+        ...
+        entry_points={
+            'console_scripts': [
+                'rst2pdf = project_a.tools.pdfgen [PDF]',
+                'rst2html = project_a.tools.htmlgen',
+                # more script entry points ...
+            ],
+        }
+    )
+
+Projects can also use another project's extras when specifying dependencies.
+For example, if project B needs "project A" with PDF support installed, it
+might declare the dependency like this::
+
+    setup(
+        name="Project-B",
+        install_requires=["Project-A[PDF]"],
+        ...
+    )
+
+This will cause ReportLab to be installed along with project A, if project B is
+installed -- even if project A was already installed.  In this way, a project
+can encapsulate groups of optional "downstream dependencies" under a feature
+name, so that packages that depend on it don't have to know what the downstream
+dependencies are.  If a later version of Project A builds in PDF support and
+no longer needs ReportLab, or if it ends up needing other dependencies besides
+ReportLab in order to provide PDF support, Project B's setup information does
+not need to change, but the right packages will still be installed if needed.
+
+Note, by the way, that if a project ends up not needing any other packages to
+support a feature, it should keep an empty requirements list for that feature
+in its ``extras_require`` argument, so that packages depending on that feature
+don't break (due to an invalid feature name).  For example, if Project A above
+builds in PDF support and no longer needs ReportLab, it could change its
+setup to this::
+
+    setup(
+        name="Project-A",
+        ...
+        extras_require={
+            'PDF':  [],
+            'reST': ["docutils>=0.3"],
+        }
+    )
+
+so that Package B doesn't have to remove the ``[PDF]`` from its requirement
+specifier.
+
+
+.. _Platform Specific Dependencies:
+
+
+Declaring platform specific dependencies
+----------------------------------------
+
+Sometimes a project might require a dependency to run on a specific platform.
+This could to a package that back ports a module so that it can be used in
+older python versions.  Or it could be a package that is required to run on a
+specific operating system.  This will allow a project to work on multiple
+different platforms without installing dependencies that are not required for
+a platform that is installing the project.
+
+For example, here is a project that uses the ``enum`` module and ``pywin32``::
+
+    setup(
+        name="Project",
+        ...
+        install_requires=[
+            'enum34;python_version<"3.4"',
+            'pywin32 >= 1.0;platform_system=="Windows"'
+        ]
+    )
+
+Since the ``enum`` module was added in Python 3.4, it should only be installed
+if the python version is earlier.  Since ``pywin32`` will only be used on
+windows, it should only be installed when the operating system is Windows.
+Specifying version requirements for the dependencies is supported as normal.
+
+The environmental markers that may be used for testing platform types are
+detailed in `PEP 508`_.
+
+.. _PEP 508: https://www.python.org/dev/peps/pep-0508/
+
+Including Data Files
+====================
+
+The distutils have traditionally allowed installation of "data files", which
+are placed in a platform-specific location.  However, the most common use case
+for data files distributed with a package is for use *by* the package, usually
+by including the data files in the package directory.
+
+Setuptools offers three ways to specify data files to be included in your
+packages.  First, you can simply use the ``include_package_data`` keyword,
+e.g.::
+
+    from setuptools import setup, find_packages
+    setup(
+        ...
+        include_package_data=True
+    )
+
+This tells setuptools to install any data files it finds in your packages.
+The data files must be specified via the distutils' ``MANIFEST.in`` file.
+(They can also be tracked by a revision control system, using an appropriate
+plugin.  See the section below on `Adding Support for Revision Control
+Systems`_ for information on how to write such plugins.)
+
+If you want finer-grained control over what files are included (for example,
+if you have documentation files in your package directories and want to exclude
+them from installation), then you can also use the ``package_data`` keyword,
+e.g.::
+
+    from setuptools import setup, find_packages
+    setup(
+        ...
+        package_data={
+            # If any package contains *.txt or *.rst files, include them:
+            '': ['*.txt', '*.rst'],
+            # And include any *.msg files found in the 'hello' package, too:
+            'hello': ['*.msg'],
+        }
+    )
+
+The ``package_data`` argument is a dictionary that maps from package names to
+lists of glob patterns.  The globs may include subdirectory names, if the data
+files are contained in a subdirectory of the package.  For example, if the
+package tree looks like this::
+
+    setup.py
+    src/
+        mypkg/
+            __init__.py
+            mypkg.txt
+            data/
+                somefile.dat
+                otherdata.dat
+
+The setuptools setup file might look like this::
+
+    from setuptools import setup, find_packages
+    setup(
+        ...
+        packages=find_packages('src'),  # include all packages under src
+        package_dir={'':'src'},   # tell distutils packages are under src
+
+        package_data={
+            # If any package contains *.txt files, include them:
+            '': ['*.txt'],
+            # And include any *.dat files found in the 'data' subdirectory
+            # of the 'mypkg' package, also:
+            'mypkg': ['data/*.dat'],
+        }
+    )
+
+Notice that if you list patterns in ``package_data`` under the empty string,
+these patterns are used to find files in every package, even ones that also
+have their own patterns listed.  Thus, in the above example, the ``mypkg.txt``
+file gets included even though it's not listed in the patterns for ``mypkg``.
+
+Also notice that if you use paths, you *must* use a forward slash (``/``) as
+the path separator, even if you are on Windows.  Setuptools automatically
+converts slashes to appropriate platform-specific separators at build time.
+
+If datafiles are contained in a subdirectory of a package that isn't a package
+itself (no ``__init__.py``), then the subdirectory names (or ``*``) are required
+in the ``package_data`` argument (as shown above with ``'data/*.dat'``).
+
+When building an ``sdist``, the datafiles are also drawn from the
+``package_name.egg-info/SOURCES.txt`` file, so make sure that this is removed if
+the ``setup.py`` ``package_data`` list is updated before calling ``setup.py``.
+
+(Note: although the ``package_data`` argument was previously only available in
+``setuptools``, it was also added to the Python ``distutils`` package as of
+Python 2.4; there is `some documentation for the feature`__ available on the
+python.org website.  If using the setuptools-specific ``include_package_data``
+argument, files specified by ``package_data`` will *not* be automatically
+added to the manifest unless they are listed in the MANIFEST.in file.)
+
+__ http://docs.python.org/dist/node11.html
+
+Sometimes, the ``include_package_data`` or ``package_data`` options alone
+aren't sufficient to precisely define what files you want included.  For
+example, you may want to include package README files in your revision control
+system and source distributions, but exclude them from being installed.  So,
+setuptools offers an ``exclude_package_data`` option as well, that allows you
+to do things like this::
+
+    from setuptools import setup, find_packages
+    setup(
+        ...
+        packages=find_packages('src'),  # include all packages under src
+        package_dir={'':'src'},   # tell distutils packages are under src
+
+        include_package_data=True,    # include everything in source control
+
+        # ...but exclude README.txt from all packages
+        exclude_package_data={'': ['README.txt']},
+    )
+
+The ``exclude_package_data`` option is a dictionary mapping package names to
+lists of wildcard patterns, just like the ``package_data`` option.  And, just
+as with that option, a key of ``''`` will apply the given pattern(s) to all
+packages.  However, any files that match these patterns will be *excluded*
+from installation, even if they were listed in ``package_data`` or were
+included as a result of using ``include_package_data``.
+
+In summary, the three options allow you to:
+
+``include_package_data``
+    Accept all data files and directories matched by ``MANIFEST.in``.
+
+``package_data``
+    Specify additional patterns to match files that may or may
+    not be matched by ``MANIFEST.in`` or found in source control.
+
+``exclude_package_data``
+    Specify patterns for data files and directories that should *not* be
+    included when a package is installed, even if they would otherwise have
+    been included due to the use of the preceding options.
+
+NOTE: Due to the way the distutils build process works, a data file that you
+include in your project and then stop including may be "orphaned" in your
+project's build directories, requiring you to run ``setup.py clean --all`` to
+fully remove them.  This may also be important for your users and contributors
+if they track intermediate revisions of your project using Subversion; be sure
+to let them know when you make changes that remove files from inclusion so they
+can run ``setup.py clean --all``.
+
+
+Accessing Data Files at Runtime
+-------------------------------
+
+Typically, existing programs manipulate a package's ``__file__`` attribute in
+order to find the location of data files.  However, this manipulation isn't
+compatible with PEP 302-based import hooks, including importing from zip files
+and Python Eggs.  It is strongly recommended that, if you are using data files,
+you should use the :ref:`ResourceManager API` of ``pkg_resources`` to access
+them.  The ``pkg_resources`` module is distributed as part of setuptools, so if
+you're using setuptools to distribute your package, there is no reason not to
+use its resource management API.  See also `Accessing Package Resources`_ for
+a quick example of converting code that uses ``__file__`` to use
+``pkg_resources`` instead.
+
+.. _Accessing Package Resources: http://peak.telecommunity.com/DevCenter/PythonEggs#accessing-package-resources
+
+
+Non-Package Data Files
+----------------------
+
+The ``distutils`` normally install general "data files" to a platform-specific
+location (e.g. ``/usr/share``).  This feature intended to be used for things
+like documentation, example configuration files, and the like.  ``setuptools``
+does not install these data files in a separate location, however.  They are
+bundled inside the egg file or directory, alongside the Python modules and
+packages.  The data files can also be accessed using the :ref:`ResourceManager
+API`, by specifying a ``Requirement`` instead of a package name::
+
+    from pkg_resources import Requirement, resource_filename
+    filename = resource_filename(Requirement.parse("MyProject"),"sample.conf")
+
+The above code will obtain the filename of the "sample.conf" file in the data
+root of the "MyProject" distribution.
+
+Note, by the way, that this encapsulation of data files means that you can't
+actually install data files to some arbitrary location on a user's machine;
+this is a feature, not a bug.  You can always include a script in your
+distribution that extracts and copies your the documentation or data files to
+a user-specified location, at their discretion.  If you put related data files
+in a single directory, you can use ``resource_filename()`` with the directory
+name to get a filesystem directory that then can be copied with the ``shutil``
+module.  (Even if your package is installed as a zipfile, calling
+``resource_filename()`` on a directory will return an actual filesystem
+directory, whose contents will be that entire subtree of your distribution.)
+
+(Of course, if you're writing a new package, you can just as easily place your
+data files or directories inside one of your packages, rather than using the
+distutils' approach.  However, if you're updating an existing application, it
+may be simpler not to change the way it currently specifies these data files.)
+
+
+Automatic Resource Extraction
+-----------------------------
+
+If you are using tools that expect your resources to be "real" files, or your
+project includes non-extension native libraries or other files that your C
+extensions expect to be able to access, you may need to list those files in
+the ``eager_resources`` argument to ``setup()``, so that the files will be
+extracted together, whenever a C extension in the project is imported.
+
+This is especially important if your project includes shared libraries *other*
+than distutils-built C extensions, and those shared libraries use file
+extensions other than ``.dll``, ``.so``, or ``.dylib``, which are the
+extensions that setuptools 0.6a8 and higher automatically detects as shared
+libraries and adds to the ``native_libs.txt`` file for you.  Any shared
+libraries whose names do not end with one of those extensions should be listed
+as ``eager_resources``, because they need to be present in the filesystem when
+he C extensions that link to them are used.
+
+The ``pkg_resources`` runtime for compressed packages will automatically
+extract *all* C extensions and ``eager_resources`` at the same time, whenever
+*any* C extension or eager resource is requested via the ``resource_filename()``
+API.  (C extensions are imported using ``resource_filename()`` internally.)
+This ensures that C extensions will see all of the "real" files that they
+expect to see.
+
+Note also that you can list directory resource names in ``eager_resources`` as
+well, in which case the directory's contents (including subdirectories) will be
+extracted whenever any C extension or eager resource is requested.
+
+Please note that if you're not sure whether you need to use this argument, you
+don't!  It's really intended to support projects with lots of non-Python
+dependencies and as a last resort for crufty projects that can't otherwise
+handle being compressed.  If your package is pure Python, Python plus data
+files, or Python plus C, you really don't need this.  You've got to be using
+either C or an external program that needs "real" files in your project before
+there's any possibility of ``eager_resources`` being relevant to your project.
+
+
+Extensible Applications and Frameworks
+======================================
+
+
+.. _Entry Points:
+
+Dynamic Discovery of Services and Plugins
+-----------------------------------------
+
+``setuptools`` supports creating libraries that "plug in" to extensible
+applications and frameworks, by letting you register "entry points" in your
+project that can be imported by the application or framework.
+
+For example, suppose that a blogging tool wants to support plugins
+that provide translation for various file types to the blog's output format.
+The framework might define an "entry point group" called ``blogtool.parsers``,
+and then allow plugins to register entry points for the file extensions they
+support.
+
+This would allow people to create distributions that contain one or more
+parsers for different file types, and then the blogging tool would be able to
+find the parsers at runtime by looking up an entry point for the file
+extension (or mime type, or however it wants to).
+
+Note that if the blogging tool includes parsers for certain file formats, it
+can register these as entry points in its own setup script, which means it
+doesn't have to special-case its built-in formats.  They can just be treated
+the same as any other plugin's entry points would be.
+
+If you're creating a project that plugs in to an existing application or
+framework, you'll need to know what entry points or entry point groups are
+defined by that application or framework.  Then, you can register entry points
+in your setup script.  Here are a few examples of ways you might register an
+``.rst`` file parser entry point in the ``blogtool.parsers`` entry point group,
+for our hypothetical blogging tool::
+
+    setup(
+        # ...
+        entry_points={'blogtool.parsers': '.rst = some_module:SomeClass'}
+    )
+
+    setup(
+        # ...
+        entry_points={'blogtool.parsers': ['.rst = some_module:a_func']}
+    )
+
+    setup(
+        # ...
+        entry_points="""
+            [blogtool.parsers]
+            .rst = some.nested.module:SomeClass.some_classmethod [reST]
+        """,
+        extras_require=dict(reST="Docutils>=0.3.5")
+    )
+
+The ``entry_points`` argument to ``setup()`` accepts either a string with
+``.ini``-style sections, or a dictionary mapping entry point group names to
+either strings or lists of strings containing entry point specifiers.  An
+entry point specifier consists of a name and value, separated by an ``=``
+sign.  The value consists of a dotted module name, optionally followed by a
+``:`` and a dotted identifier naming an object within the module.  It can
+also include a bracketed list of "extras" that are required for the entry
+point to be used.  When the invoking application or framework requests loading
+of an entry point, any requirements implied by the associated extras will be
+passed to ``pkg_resources.require()``, so that an appropriate error message
+can be displayed if the needed package(s) are missing.  (Of course, the
+invoking app or framework can ignore such errors if it wants to make an entry
+point optional if a requirement isn't installed.)
+
+
+Defining Additional Metadata
+----------------------------
+
+Some extensible applications and frameworks may need to define their own kinds
+of metadata to include in eggs, which they can then access using the
+``pkg_resources`` metadata APIs.  Ordinarily, this is done by having plugin
+developers include additional files in their ``ProjectName.egg-info``
+directory.  However, since it can be tedious to create such files by hand, you
+may want to create a distutils extension that will create the necessary files
+from arguments to ``setup()``, in much the same way that ``setuptools`` does
+for many of the ``setup()`` arguments it adds.  See the section below on
+`Creating distutils Extensions`_ for more details, especially the subsection on
+`Adding new EGG-INFO Files`_.
+
+
+"Development Mode"
+==================
+
+Under normal circumstances, the ``distutils`` assume that you are going to
+build a distribution of your project, not use it in its "raw" or "unbuilt"
+form.  If you were to use the ``distutils`` that way, you would have to rebuild
+and reinstall your project every time you made a change to it during
+development.
+
+Another problem that sometimes comes up with the ``distutils`` is that you may
+need to do development on two related projects at the same time.  You may need
+to put both projects' packages in the same directory to run them, but need to
+keep them separate for revision control purposes.  How can you do this?
+
+Setuptools allows you to deploy your projects for use in a common directory or
+staging area, but without copying any files.  Thus, you can edit each project's
+code in its checkout directory, and only need to run build commands when you
+change a project's C extensions or similarly compiled files.  You can even
+deploy a project into another project's checkout directory, if that's your
+preferred way of working (as opposed to using a common independent staging area
+or the site-packages directory).
+
+To do this, use the ``setup.py develop`` command.  It works very similarly to
+``setup.py install`` or the EasyInstall tool, except that it doesn't actually
+install anything.  Instead, it creates a special ``.egg-link`` file in the
+deployment directory, that links to your project's source code.  And, if your
+deployment directory is Python's ``site-packages`` directory, it will also
+update the ``easy-install.pth`` file to include your project's source code,
+thereby making it available on ``sys.path`` for all programs using that Python
+installation.
+
+If you have enabled the ``use_2to3`` flag, then of course the ``.egg-link``
+will not link directly to your source code when run under Python 3, since
+that source code would be made for Python 2 and not work under Python 3.
+Instead the ``setup.py develop`` will build Python 3 code under the ``build``
+directory, and link there. This means that after doing code changes you will
+have to run ``setup.py build`` before these changes are picked up by your
+Python 3 installation.
+
+In addition, the ``develop`` command creates wrapper scripts in the target
+script directory that will run your in-development scripts after ensuring that
+all your ``install_requires`` packages are available on ``sys.path``.
+
+You can deploy the same project to multiple staging areas, e.g. if you have
+multiple projects on the same machine that are sharing the same project you're
+doing development work.
+
+When you're done with a given development task, you can remove the project
+source from a staging area using ``setup.py develop --uninstall``, specifying
+the desired staging area if it's not the default.
+
+There are several options to control the precise behavior of the ``develop``
+command; see the section on the `develop`_ command below for more details.
+
+Note that you can also apply setuptools commands to non-setuptools projects,
+using commands like this::
+
+   python -c "import setuptools; execfile('setup.py')" develop
+
+That is, you can simply list the normal setup commands and options following
+the quoted part.
+
+
+Distributing a ``setuptools``-based project
+===========================================
+
+Using ``setuptools``...  Without bundling it!
+---------------------------------------------
+
+.. warning:: **ez_setup** is deprecated in favor of PIP with **PEP-518** support.
+
+Your users might not have ``setuptools`` installed on their machines, or even
+if they do, it might not be the right version.  Fixing this is easy; just
+download `ez_setup.py`_, and put it in the same directory as your ``setup.py``
+script.  (Be sure to add it to your revision control system, too.)  Then add
+these two lines to the very top of your setup script, before the script imports
+anything from setuptools:
+
+.. code-block:: python
+
+    import ez_setup
+    ez_setup.use_setuptools()
+
+That's it.  The ``ez_setup`` module will automatically download a matching
+version of ``setuptools`` from PyPI, if it isn't present on the target system.
+Whenever you install an updated version of setuptools, you should also update
+your projects' ``ez_setup.py`` files, so that a matching version gets installed
+on the target machine(s).
+
+By the way, setuptools supports the new PyPI "upload" command, so you can use
+``setup.py sdist upload`` or ``setup.py bdist_egg upload`` to upload your
+source or egg distributions respectively.  Your project's current version must
+be registered with PyPI first, of course; you can use ``setup.py register`` to
+do that.  Or you can do it all in one step, e.g. ``setup.py register sdist
+bdist_egg upload`` will register the package, build source and egg
+distributions, and then upload them both to PyPI, where they'll be easily
+found by other projects that depend on them.
+
+(By the way, if you need to distribute a specific version of ``setuptools``,
+you can specify the exact version and base download URL as parameters to the
+``use_setuptools()`` function.  See the function's docstring for details.)
+
+
+What Your Users Should Know
+---------------------------
+
+In general, a setuptools-based project looks just like any distutils-based
+project -- as long as your users have an internet connection and are installing
+to ``site-packages``, that is.  But for some users, these conditions don't
+apply, and they may become frustrated if this is their first encounter with
+a setuptools-based project.  To keep these users happy, you should review the
+following topics in your project's installation instructions, if they are
+relevant to your project and your target audience isn't already familiar with
+setuptools and ``easy_install``.
+
+Network Access
+    If your project is using ``ez_setup``, you should inform users of the
+    need to either have network access, or to preinstall the correct version of
+    setuptools using the `EasyInstall installation instructions`_.  Those
+    instructions also have tips for dealing with firewalls as well as how to
+    manually download and install setuptools.
+
+Custom Installation Locations
+    You should inform your users that if they are installing your project to
+    somewhere other than the main ``site-packages`` directory, they should
+    first install setuptools using the instructions for `Custom Installation
+    Locations`_, before installing your project.
+
+Your Project's Dependencies
+    If your project depends on other projects that may need to be downloaded
+    from PyPI or elsewhere, you should list them in your installation
+    instructions, or tell users how to find out what they are.  While most
+    users will not need this information, any users who don't have unrestricted
+    internet access may have to find, download, and install the other projects
+    manually.  (Note, however, that they must still install those projects
+    using ``easy_install``, or your project will not know they are installed,
+    and your setup script will try to download them again.)
+
+    If you want to be especially friendly to users with limited network access,
+    you may wish to build eggs for your project and its dependencies, making
+    them all available for download from your site, or at least create a page
+    with links to all of the needed eggs.  In this way, users with limited
+    network access can manually download all the eggs to a single directory,
+    then use the ``-f`` option of ``easy_install`` to specify the directory
+    to find eggs in.  Users who have full network access can just use ``-f``
+    with the URL of your download page, and ``easy_install`` will find all the
+    needed eggs using your links directly.  This is also useful when your
+    target audience isn't able to compile packages (e.g. most Windows users)
+    and your package or some of its dependencies include C code.
+
+Revision Control System Users and Co-Developers
+    Users and co-developers who are tracking your in-development code using
+    a revision control system should probably read this manual's sections
+    regarding such development.  Alternately, you may wish to create a
+    quick-reference guide containing the tips from this manual that apply to
+    your particular situation.  For example, if you recommend that people use
+    ``setup.py develop`` when tracking your in-development code, you should let
+    them know that this needs to be run after every update or commit.
+
+    Similarly, if you remove modules or data files from your project, you
+    should remind them to run ``setup.py clean --all`` and delete any obsolete
+    ``.pyc`` or ``.pyo``.  (This tip applies to the distutils in general, not
+    just setuptools, but not everybody knows about them; be kind to your users
+    by spelling out your project's best practices rather than leaving them
+    guessing.)
+
+Creating System Packages
+    Some users want to manage all Python packages using a single package
+    manager, and sometimes that package manager isn't ``easy_install``!
+    Setuptools currently supports ``bdist_rpm``, ``bdist_wininst``, and
+    ``bdist_dumb`` formats for system packaging.  If a user has a locally-
+    installed "bdist" packaging tool that internally uses the distutils
+    ``install`` command, it should be able to work with ``setuptools``.  Some
+    examples of "bdist" formats that this should work with include the
+    ``bdist_nsi`` and ``bdist_msi`` formats for Windows.
+
+    However, packaging tools that build binary distributions by running
+    ``setup.py install`` on the command line or as a subprocess will require
+    modification to work with setuptools.  They should use the
+    ``--single-version-externally-managed`` option to the ``install`` command,
+    combined with the standard ``--root`` or ``--record`` options.
+    See the `install command`_ documentation below for more details.  The
+    ``bdist_deb`` command is an example of a command that currently requires
+    this kind of patching to work with setuptools.
+
+    If you or your users have a problem building a usable system package for
+    your project, please report the problem via the mailing list so that
+    either the "bdist" tool in question or setuptools can be modified to
+    resolve the issue.
+
+
+Setting the ``zip_safe`` flag
+-----------------------------
+
+For some use cases (such as bundling as part of a larger application), Python
+packages may be run directly from a zip file.
+Not all packages, however, are capable of running in compressed form, because
+they may expect to be able to access either source code or data files as
+normal operating system files.  So, ``setuptools`` can install your project
+as a zipfile or a directory, and its default choice is determined by the
+project's ``zip_safe`` flag.
+
+You can pass a True or False value for the ``zip_safe`` argument to the
+``setup()`` function, or you can omit it.  If you omit it, the ``bdist_egg``
+command will analyze your project's contents to see if it can detect any
+conditions that would prevent it from working in a zipfile.  It will output
+notices to the console about any such conditions that it finds.
+
+Currently, this analysis is extremely conservative: it will consider the
+project unsafe if it contains any C extensions or datafiles whatsoever.  This
+does *not* mean that the project can't or won't work as a zipfile!  It just
+means that the ``bdist_egg`` authors aren't yet comfortable asserting that
+the project *will* work.  If the project contains no C or data files, and does
+no ``__file__`` or ``__path__`` introspection or source code manipulation, then
+there is an extremely solid chance the project will work when installed as a
+zipfile.  (And if the project uses ``pkg_resources`` for all its data file
+access, then C extensions and other data files shouldn't be a problem at all.
+See the `Accessing Data Files at Runtime`_ section above for more information.)
+
+However, if ``bdist_egg`` can't be *sure* that your package will work, but
+you've checked over all the warnings it issued, and you are either satisfied it
+*will* work (or if you want to try it for yourself), then you should set
+``zip_safe`` to ``True`` in your ``setup()`` call.  If it turns out that it
+doesn't work, you can always change it to ``False``, which will force
+``setuptools`` to install your project as a directory rather than as a zipfile.
+
+Of course, the end-user can still override either decision, if they are using
+EasyInstall to install your package.  And, if you want to override for testing
+purposes, you can just run ``setup.py easy_install --zip-ok .`` or ``setup.py
+easy_install --always-unzip .`` in your project directory. to install the
+package as a zipfile or directory, respectively.
+
+In the future, as we gain more experience with different packages and become
+more satisfied with the robustness of the ``pkg_resources`` runtime, the
+"zip safety" analysis may become less conservative.  However, we strongly
+recommend that you determine for yourself whether your project functions
+correctly when installed as a zipfile, correct any problems if you can, and
+then make an explicit declaration of ``True`` or ``False`` for the ``zip_safe``
+flag, so that it will not be necessary for ``bdist_egg`` or ``EasyInstall`` to
+try to guess whether your project can work as a zipfile.
+
+
+Namespace Packages
+------------------
+
+Sometimes, a large package is more useful if distributed as a collection of
+smaller eggs.  However, Python does not normally allow the contents of a
+package to be retrieved from more than one location.  "Namespace packages"
+are a solution for this problem.  When you declare a package to be a namespace
+package, it means that the package has no meaningful contents in its
+``__init__.py``, and that it is merely a container for modules and subpackages.
+
+The ``pkg_resources`` runtime will then automatically ensure that the contents
+of namespace packages that are spread over multiple eggs or directories are
+combined into a single "virtual" package.
+
+The ``namespace_packages`` argument to ``setup()`` lets you declare your
+project's namespace packages, so that they will be included in your project's
+metadata.  The argument should list the namespace packages that the egg
+participates in.  For example, the ZopeInterface project might do this::
+
+    setup(
+        # ...
+        namespace_packages=['zope']
+    )
+
+because it contains a ``zope.interface`` package that lives in the ``zope``
+namespace package.  Similarly, a project for a standalone ``zope.publisher``
+would also declare the ``zope`` namespace package.  When these projects are
+installed and used, Python will see them both as part of a "virtual" ``zope``
+package, even though they will be installed in different locations.
+
+Namespace packages don't have to be top-level packages.  For example, Zope 3's
+``zope.app`` package is a namespace package, and in the future PEAK's
+``peak.util`` package will be too.
+
+Note, by the way, that your project's source tree must include the namespace
+packages' ``__init__.py`` files (and the ``__init__.py`` of any parent
+packages), in a normal Python package layout.  These ``__init__.py`` files
+*must* contain the line::
+
+    __import__('pkg_resources').declare_namespace(__name__)
+
+This code ensures that the namespace package machinery is operating and that
+the current package is registered as a namespace package.
+
+You must NOT include any other code and data in a namespace package's
+``__init__.py``.  Even though it may appear to work during development, or when
+projects are installed as ``.egg`` files, it will not work when the projects
+are installed using "system" packaging tools -- in such cases the
+``__init__.py`` files will not be installed, let alone executed.
+
+You must include the ``declare_namespace()``  line in the ``__init__.py`` of
+*every* project that has contents for the namespace package in question, in
+order to ensure that the namespace will be declared regardless of which
+project's copy of ``__init__.py`` is loaded first.  If the first loaded
+``__init__.py`` doesn't declare it, it will never *be* declared, because no
+other copies will ever be loaded!
+
+
+TRANSITIONAL NOTE
+~~~~~~~~~~~~~~~~~
+
+Setuptools automatically calls ``declare_namespace()`` for you at runtime,
+but future versions may *not*.  This is because the automatic declaration
+feature has some negative side effects, such as needing to import all namespace
+packages during the initialization of the ``pkg_resources`` runtime, and also
+the need for ``pkg_resources`` to be explicitly imported before any namespace
+packages work at all.  In some future releases, you'll be responsible
+for including your own declaration lines, and the automatic declaration feature
+will be dropped to get rid of the negative side effects.
+
+During the remainder of the current development cycle, therefore, setuptools
+will warn you about missing ``declare_namespace()`` calls in your
+``__init__.py`` files, and you should correct these as soon as possible
+before the compatibility support is removed.
+Namespace packages without declaration lines will not work
+correctly once a user has upgraded to a later version, so it's important that
+you make this change now in order to avoid having your code break in the field.
+Our apologies for the inconvenience, and thank you for your patience.
+
+
+
+Tagging and "Daily Build" or "Snapshot" Releases
+------------------------------------------------
+
+When a set of related projects are under development, it may be important to
+track finer-grained version increments than you would normally use for e.g.
+"stable" releases.  While stable releases might be measured in dotted numbers
+with alpha/beta/etc. status codes, development versions of a project often
+need to be tracked by revision or build number or even build date.  This is
+especially true when projects in development need to refer to one another, and
+therefore may literally need an up-to-the-minute version of something!
+
+To support these scenarios, ``setuptools`` allows you to "tag" your source and
+egg distributions by adding one or more of the following to the project's
+"official" version identifier:
+
+* A manually-specified pre-release tag, such as "build" or "dev", or a
+  manually-specified post-release tag, such as a build or revision number
+  (``--tag-build=STRING, -bSTRING``)
+
+* An 8-character representation of the build date (``--tag-date, -d``), as
+  a postrelease tag
+
+You can add these tags by adding ``egg_info`` and the desired options to
+the command line ahead of the ``sdist`` or ``bdist`` commands that you want
+to generate a daily build or snapshot for.  See the section below on the
+`egg_info`_ command for more details.
+
+(Also, before you release your project, be sure to see the section above on
+`Specifying Your Project's Version`_ for more information about how pre- and
+post-release tags affect how setuptools and EasyInstall interpret version
+numbers.  This is important in order to make sure that dependency processing
+tools will know which versions of your project are newer than others.)
+
+Finally, if you are creating builds frequently, and either building them in a
+downloadable location or are copying them to a distribution server, you should
+probably also check out the `rotate`_ command, which lets you automatically
+delete all but the N most-recently-modified distributions matching a glob
+pattern.  So, you can use a command line like::
+
+    setup.py egg_info -rbDEV bdist_egg rotate -m.egg -k3
+
+to build an egg whose version info includes 'DEV-rNNNN' (where NNNN is the
+most recent Subversion revision that affected the source tree), and then
+delete any egg files from the distribution directory except for the three
+that were built most recently.
+
+If you have to manage automated builds for multiple packages, each with
+different tagging and rotation policies, you may also want to check out the
+`alias`_ command, which would let each package define an alias like ``daily``
+that would perform the necessary tag, build, and rotate commands.  Then, a
+simpler script or cron job could just run ``setup.py daily`` in each project
+directory.  (And, you could also define sitewide or per-user default versions
+of the ``daily`` alias, so that projects that didn't define their own would
+use the appropriate defaults.)
+
+
+Generating Source Distributions
+-------------------------------
+
+``setuptools`` enhances the distutils' default algorithm for source file
+selection with pluggable endpoints for looking up files to include. If you are
+using a revision control system, and your source distributions only need to
+include files that you're tracking in revision control, use a corresponding
+plugin instead of writing a ``MANIFEST.in`` file. See the section below on
+`Adding Support for Revision Control Systems`_ for information on plugins.
+
+If you need to include automatically generated files, or files that are kept in
+an unsupported revision control system, you'll need to create a ``MANIFEST.in``
+file to specify any files that the default file location algorithm doesn't
+catch.  See the distutils documentation for more information on the format of
+the ``MANIFEST.in`` file.
+
+But, be sure to ignore any part of the distutils documentation that deals with
+``MANIFEST`` or how it's generated from ``MANIFEST.in``; setuptools shields you
+from these issues and doesn't work the same way in any case.  Unlike the
+distutils, setuptools regenerates the source distribution manifest file
+every time you build a source distribution, and it builds it inside the
+project's ``.egg-info`` directory, out of the way of your main project
+directory.  You therefore need not worry about whether it is up-to-date or not.
+
+Indeed, because setuptools' approach to determining the contents of a source
+distribution is so much simpler, its ``sdist`` command omits nearly all of
+the options that the distutils' more complex ``sdist`` process requires.  For
+all practical purposes, you'll probably use only the ``--formats`` option, if
+you use any option at all.
+
+
+Making your package available for EasyInstall
+---------------------------------------------
+
+If you use the ``register`` command (``setup.py register``) to register your
+package with PyPI, that's most of the battle right there.  (See the
+`docs for the register command`_ for more details.)
+
+.. _docs for the register command: http://docs.python.org/dist/package-index.html
+
+If you also use the `upload`_ command to upload actual distributions of your
+package, that's even better, because EasyInstall will be able to find and
+download them directly from your project's PyPI page.
+
+However, there may be reasons why you don't want to upload distributions to
+PyPI, and just want your existing distributions (or perhaps a Subversion
+checkout) to be used instead.
+
+So here's what you need to do before running the ``register`` command.  There
+are three ``setup()`` arguments that affect EasyInstall:
+
+``url`` and ``download_url``
+   These become links on your project's PyPI page.  EasyInstall will examine
+   them to see if they link to a package ("primary links"), or whether they are
+   HTML pages.  If they're HTML pages, EasyInstall scans all HREF's on the
+   page for primary links
+
+``long_description``
+   EasyInstall will check any URLs contained in this argument to see if they
+   are primary links.
+
+A URL is considered a "primary link" if it is a link to a .tar.gz, .tgz, .zip,
+.egg, .egg.zip, .tar.bz2, or .exe file, or if it has an ``#egg=project`` or
+``#egg=project-version`` fragment identifier attached to it.  EasyInstall
+attempts to determine a project name and optional version number from the text
+of a primary link *without* downloading it.  When it has found all the primary
+links, EasyInstall will select the best match based on requested version,
+platform compatibility, and other criteria.
+
+So, if your ``url`` or ``download_url`` point either directly to a downloadable
+source distribution, or to HTML page(s) that have direct links to such, then
+EasyInstall will be able to locate downloads automatically.  If you want to
+make Subversion checkouts available, then you should create links with either
+``#egg=project`` or ``#egg=project-version`` added to the URL.  You should
+replace ``project`` and ``version`` with the values they would have in an egg
+filename.  (Be sure to actually generate an egg and then use the initial part
+of the filename, rather than trying to guess what the escaped form of the
+project name and version number will be.)
+
+Note that Subversion checkout links are of lower precedence than other kinds
+of distributions, so EasyInstall will not select a Subversion checkout for
+downloading unless it has a version included in the ``#egg=`` suffix, and
+it's a higher version than EasyInstall has seen in any other links for your
+project.
+
+As a result, it's a common practice to use mark checkout URLs with a version of
+"dev" (i.e., ``#egg=projectname-dev``), so that users can do something like
+this::
+
+    easy_install --editable projectname==dev
+
+in order to check out the in-development version of ``projectname``.
+
+
+Making "Official" (Non-Snapshot) Releases
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When you make an official release, creating source or binary distributions,
+you will need to override the tag settings from ``setup.cfg``, so that you
+don't end up registering versions like ``foobar-0.7a1.dev-r34832``.  This is
+easy to do if you are developing on the trunk and using tags or branches for
+your releases - just make the change to ``setup.cfg`` after branching or
+tagging the release, so the trunk will still produce development snapshots.
+
+Alternately, if you are not branching for releases, you can override the
+default version options on the command line, using something like::
+
+    python setup.py egg_info -Db "" sdist bdist_egg register upload
+
+The first part of this command (``egg_info -Db ""``) will override the
+configured tag information, before creating source and binary eggs, registering
+the project with PyPI, and uploading the files.  Thus, these commands will use
+the plain version from your ``setup.py``, without adding the build designation
+string.
+
+Of course, if you will be doing this a lot, you may wish to create a personal
+alias for this operation, e.g.::
+
+    python setup.py alias -u release egg_info -Db ""
+
+You can then use it like this::
+
+    python setup.py release sdist bdist_egg register upload
+
+Or of course you can create more elaborate aliases that do all of the above.
+See the sections below on the `egg_info`_ and `alias`_ commands for more ideas.
+
+
+
+Distributing Extensions compiled with Pyrex
+-------------------------------------------
+
+``setuptools`` includes transparent support for building Pyrex extensions, as
+long as you define your extensions using ``setuptools.Extension``, *not*
+``distutils.Extension``.  You must also not import anything from Pyrex in
+your setup script.
+
+If you follow these rules, you can safely list ``.pyx`` files as the source
+of your ``Extension`` objects in the setup script.  ``setuptools`` will detect
+at build time whether Pyrex is installed or not.  If it is, then ``setuptools``
+will use it.  If not, then ``setuptools`` will silently change the
+``Extension`` objects to refer to the ``.c`` counterparts of the ``.pyx``
+files, so that the normal distutils C compilation process will occur.
+
+Of course, for this to work, your source distributions must include the C
+code generated by Pyrex, as well as your original ``.pyx`` files.  This means
+that you will probably want to include current ``.c`` files in your revision
+control system, rebuilding them whenever you check changes in for the ``.pyx``
+source files.  This will ensure that people tracking your project in a revision
+control system will be able to build it even if they don't have Pyrex
+installed, and that your source releases will be similarly usable with or
+without Pyrex.
+
+
+-----------------
+Command Reference
+-----------------
+
+.. _alias:
+
+``alias`` - Define shortcuts for commonly used commands
+=======================================================
+
+Sometimes, you need to use the same commands over and over, but you can't
+necessarily set them as defaults.  For example, if you produce both development
+snapshot releases and "stable" releases of a project, you may want to put
+the distributions in different places, or use different ``egg_info`` tagging
+options, etc.  In these cases, it doesn't make sense to set the options in
+a distutils configuration file, because the values of the options changed based
+on what you're trying to do.
+
+Setuptools therefore allows you to define "aliases" - shortcut names for
+an arbitrary string of commands and options, using ``setup.py alias aliasname
+expansion``, where aliasname is the name of the new alias, and the remainder of
+the command line supplies its expansion.  For example, this command defines
+a sitewide alias called "daily", that sets various ``egg_info`` tagging
+options::
+
+    setup.py alias --global-config daily egg_info --tag-build=development
+
+Once the alias is defined, it can then be used with other setup commands,
+e.g.::
+
+    setup.py daily bdist_egg        # generate a daily-build .egg file
+    setup.py daily sdist            # generate a daily-build source distro
+    setup.py daily sdist bdist_egg  # generate both
+
+The above commands are interpreted as if the word ``daily`` were replaced with
+``egg_info --tag-build=development``.
+
+Note that setuptools will expand each alias *at most once* in a given command
+line.  This serves two purposes.  First, if you accidentally create an alias
+loop, it will have no effect; you'll instead get an error message about an
+unknown command.  Second, it allows you to define an alias for a command, that
+uses that command.  For example, this (project-local) alias::
+
+    setup.py alias bdist_egg bdist_egg rotate -k1 -m.egg
+
+redefines the ``bdist_egg`` command so that it always runs the ``rotate``
+command afterwards to delete all but the newest egg file.  It doesn't loop
+indefinitely on ``bdist_egg`` because the alias is only expanded once when
+used.
+
+You can remove a defined alias with the ``--remove`` (or ``-r``) option, e.g.::
+
+    setup.py alias --global-config --remove daily
+
+would delete the "daily" alias we defined above.
+
+Aliases can be defined on a project-specific, per-user, or sitewide basis.  The
+default is to define or remove a project-specific alias, but you can use any of
+the `configuration file options`_ (listed under the `saveopts`_ command, below)
+to determine which distutils configuration file an aliases will be added to
+(or removed from).
+
+Note that if you omit the "expansion" argument to the ``alias`` command,
+you'll get output showing that alias' current definition (and what
+configuration file it's defined in).  If you omit the alias name as well,
+you'll get a listing of all current aliases along with their configuration
+file locations.
+
+
+``bdist_egg`` - Create a Python Egg for the project
+===================================================
+
+This command generates a Python Egg (``.egg`` file) for the project.  Python
+Eggs are the preferred binary distribution format for EasyInstall, because they
+are cross-platform (for "pure" packages), directly importable, and contain
+project metadata including scripts and information about the project's
+dependencies.  They can be simply downloaded and added to ``sys.path``
+directly, or they can be placed in a directory on ``sys.path`` and then
+automatically discovered by the egg runtime system.
+
+This command runs the `egg_info`_ command (if it hasn't already run) to update
+the project's metadata (``.egg-info``) directory.  If you have added any extra
+metadata files to the ``.egg-info`` directory, those files will be included in
+the new egg file's metadata directory, for use by the egg runtime system or by
+any applications or frameworks that use that metadata.
+
+You won't usually need to specify any special options for this command; just
+use ``bdist_egg`` and you're done.  But there are a few options that may
+be occasionally useful:
+
+``--dist-dir=DIR, -d DIR``
+    Set the directory where the ``.egg`` file will be placed.  If you don't
+    supply this, then the ``--dist-dir`` setting of the ``bdist`` command
+    will be used, which is usually a directory named ``dist`` in the project
+    directory.
+
+``--plat-name=PLATFORM, -p PLATFORM``
+    Set the platform name string that will be embedded in the egg's filename
+    (assuming the egg contains C extensions).  This can be used to override
+    the distutils default platform name with something more meaningful.  Keep
+    in mind, however, that the egg runtime system expects to see eggs with
+    distutils platform names, so it may ignore or reject eggs with non-standard
+    platform names.  Similarly, the EasyInstall program may ignore them when
+    searching web pages for download links.  However, if you are
+    cross-compiling or doing some other unusual things, you might find a use
+    for this option.
+
+``--exclude-source-files``
+    Don't include any modules' ``.py`` files in the egg, just compiled Python,
+    C, and data files.  (Note that this doesn't affect any ``.py`` files in the
+    EGG-INFO directory or its subdirectories, since for example there may be
+    scripts with a ``.py`` extension which must still be retained.)  We don't
+    recommend that you use this option except for packages that are being
+    bundled for proprietary end-user applications, or for "embedded" scenarios
+    where space is at an absolute premium.  On the other hand, if your package
+    is going to be installed and used in compressed form, you might as well
+    exclude the source because Python's ``traceback`` module doesn't currently
+    understand how to display zipped source code anyway, or how to deal with
+    files that are in a different place from where their code was compiled.
+
+There are also some options you will probably never need, but which are there
+because they were copied from similar ``bdist`` commands used as an example for
+creating this one.  They may be useful for testing and debugging, however,
+which is why we kept them:
+
+``--keep-temp, -k``
+    Keep the contents of the ``--bdist-dir`` tree around after creating the
+    ``.egg`` file.
+
+``--bdist-dir=DIR, -b DIR``
+    Set the temporary directory for creating the distribution.  The entire
+    contents of this directory are zipped to create the ``.egg`` file, after
+    running various installation commands to copy the package's modules, data,
+    and extensions here.
+
+``--skip-build``
+    Skip doing any "build" commands; just go straight to the
+    install-and-compress phases.
+
+
+.. _develop:
+
+``develop`` - Deploy the project source in "Development Mode"
+=============================================================
+
+This command allows you to deploy your project's source for use in one or more
+"staging areas" where it will be available for importing.  This deployment is
+done in such a way that changes to the project source are immediately available
+in the staging area(s), without needing to run a build or install step after
+each change.
+
+The ``develop`` command works by creating an ``.egg-link`` file (named for the
+project) in the given staging area.  If the staging area is Python's
+``site-packages`` directory, it also updates an ``easy-install.pth`` file so
+that the project is on ``sys.path`` by default for all programs run using that
+Python installation.
+
+The ``develop`` command also installs wrapper scripts in the staging area (or
+a separate directory, as specified) that will ensure the project's dependencies
+are available on ``sys.path`` before running the project's source scripts.
+And, it ensures that any missing project dependencies are available in the
+staging area, by downloading and installing them if necessary.
+
+Last, but not least, the ``develop`` command invokes the ``build_ext -i``
+command to ensure any C extensions in the project have been built and are
+up-to-date, and the ``egg_info`` command to ensure the project's metadata is
+updated (so that the runtime and wrappers know what the project's dependencies
+are).  If you make any changes to the project's setup script or C extensions,
+you should rerun the ``develop`` command against all relevant staging areas to
+keep the project's scripts, metadata and extensions up-to-date.  Most other
+kinds of changes to your project should not require any build operations or
+rerunning ``develop``, but keep in mind that even minor changes to the setup
+script (e.g. changing an entry point definition) require you to re-run the
+``develop`` or ``test`` commands to keep the distribution updated.
+
+Here are some of the options that the ``develop`` command accepts.  Note that
+they affect the project's dependencies as well as the project itself, so if you
+have dependencies that need to be installed and you use ``--exclude-scripts``
+(for example), the dependencies' scripts will not be installed either!  For
+this reason, you may want to use EasyInstall to install the project's
+dependencies before using the ``develop`` command, if you need finer control
+over the installation options for dependencies.
+
+``--uninstall, -u``
+    Un-deploy the current project.  You may use the ``--install-dir`` or ``-d``
+    option to designate the staging area.  The created ``.egg-link`` file will
+    be removed, if present and it is still pointing to the project directory.
+    The project directory will be removed from ``easy-install.pth`` if the
+    staging area is Python's ``site-packages`` directory.
+
+    Note that this option currently does *not* uninstall script wrappers!  You
+    must uninstall them yourself, or overwrite them by using EasyInstall to
+    activate a different version of the package.  You can also avoid installing
+    script wrappers in the first place, if you use the ``--exclude-scripts``
+    (aka ``-x``) option when you run ``develop`` to deploy the project.
+
+``--multi-version, -m``
+    "Multi-version" mode. Specifying this option prevents ``develop`` from
+    adding an ``easy-install.pth`` entry for the project(s) being deployed, and
+    if an entry for any version of a project already exists, the entry will be
+    removed upon successful deployment.  In multi-version mode, no specific
+    version of the package is available for importing, unless you use
+    ``pkg_resources.require()`` to put it on ``sys.path``, or you are running
+    a wrapper script generated by ``setuptools`` or EasyInstall.  (In which
+    case the wrapper script calls ``require()`` for you.)
+
+    Note that if you install to a directory other than ``site-packages``,
+    this option is automatically in effect, because ``.pth`` files can only be
+    used in ``site-packages`` (at least in Python 2.3 and 2.4). So, if you use
+    the ``--install-dir`` or ``-d`` option (or they are set via configuration
+    file(s)) your project and its dependencies will be deployed in multi-
+    version mode.
+
+``--install-dir=DIR, -d DIR``
+    Set the installation directory (staging area).  If this option is not
+    directly specified on the command line or in a distutils configuration
+    file, the distutils default installation location is used.  Normally, this
+    will be the ``site-packages`` directory, but if you are using distutils
+    configuration files, setting things like ``prefix`` or ``install_lib``,
+    then those settings are taken into account when computing the default
+    staging area.
+
+``--script-dir=DIR, -s DIR``
+    Set the script installation directory.  If you don't supply this option
+    (via the command line or a configuration file), but you *have* supplied
+    an ``--install-dir`` (via command line or config file), then this option
+    defaults to the same directory, so that the scripts will be able to find
+    their associated package installation.  Otherwise, this setting defaults
+    to the location where the distutils would normally install scripts, taking
+    any distutils configuration file settings into account.
+
+``--exclude-scripts, -x``
+    Don't deploy script wrappers.  This is useful if you don't want to disturb
+    existing versions of the scripts in the staging area.
+
+``--always-copy, -a``
+    Copy all needed distributions to the staging area, even if they
+    are already present in another directory on ``sys.path``.  By default, if
+    a requirement can be met using a distribution that is already available in
+    a directory on ``sys.path``, it will not be copied to the staging area.
+
+``--egg-path=DIR``
+    Force the generated ``.egg-link`` file to use a specified relative path
+    to the source directory.  This can be useful in circumstances where your
+    installation directory is being shared by code running under multiple
+    platforms (e.g. Mac and Windows) which have different absolute locations
+    for the code under development, but the same *relative* locations with
+    respect to the installation directory.  If you use this option when
+    installing, you must supply the same relative path when uninstalling.
+
+In addition to the above options, the ``develop`` command also accepts all of
+the same options accepted by ``easy_install``.  If you've configured any
+``easy_install`` settings in your ``setup.cfg`` (or other distutils config
+files), the ``develop`` command will use them as defaults, unless you override
+them in a ``[develop]`` section or on the command line.
+
+
+``easy_install`` - Find and install packages
+============================================
+
+This command runs the `EasyInstall tool
+<easy_install.html>`_ for you.  It is exactly
+equivalent to running the ``easy_install`` command.  All command line arguments
+following this command are consumed and not processed further by the distutils,
+so this must be the last command listed on the command line.  Please see
+the EasyInstall documentation for the options reference and usage examples.
+Normally, there is no reason to use this command via the command line, as you
+can just use ``easy_install`` directly.  It's only listed here so that you know
+it's a distutils command, which means that you can:
+
+* create command aliases that use it,
+* create distutils extensions that invoke it as a subcommand, and
+* configure options for it in your ``setup.cfg`` or other distutils config
+  files.
+
+
+.. _egg_info:
+
+``egg_info`` - Create egg metadata and set build tags
+=====================================================
+
+This command performs two operations: it updates a project's ``.egg-info``
+metadata directory (used by the ``bdist_egg``, ``develop``, and ``test``
+commands), and it allows you to temporarily change a project's version string,
+to support "daily builds" or "snapshot" releases.  It is run automatically by
+the ``sdist``, ``bdist_egg``, ``develop``, ``register``, and ``test`` commands
+in order to update the project's metadata, but you can also specify it
+explicitly in order to temporarily change the project's version string while
+executing other commands.  (It also generates the``.egg-info/SOURCES.txt``
+manifest file, which is used when you are building source distributions.)
+
+In addition to writing the core egg metadata defined by ``setuptools`` and
+required by ``pkg_resources``, this command can be extended to write other
+metadata files as well, by defining entry points in the ``egg_info.writers``
+group.  See the section on `Adding new EGG-INFO Files`_ below for more details.
+Note that using additional metadata writers may require you to include a
+``setup_requires`` argument to ``setup()`` in order to ensure that the desired
+writers are available on ``sys.path``.
+
+
+Release Tagging Options
+-----------------------
+
+The following options can be used to modify the project's version string for
+all remaining commands on the setup command line.  The options are processed
+in the order shown, so if you use more than one, the requested tags will be
+added in the following order:
+
+``--tag-build=NAME, -b NAME``
+    Append NAME to the project's version string.  Due to the way setuptools
+    processes "pre-release" version suffixes beginning with the letters "a"
+    through "e" (like "alpha", "beta", and "candidate"), you will usually want
+    to use a tag like ".build" or ".dev", as this will cause the version number
+    to be considered *lower* than the project's default version.  (If you
+    want to make the version number *higher* than the default version, you can
+    always leave off --tag-build and then use one or both of the following
+    options.)
+
+    If you have a default build tag set in your ``setup.cfg``, you can suppress
+    it on the command line using ``-b ""`` or ``--tag-build=""`` as an argument
+    to the ``egg_info`` command.
+
+``--tag-date, -d``
+    Add a date stamp of the form "-YYYYMMDD" (e.g. "-20050528") to the
+    project's version number.
+
+``--no-date, -D``
+    Don't include a date stamp in the version number.  This option is included
+    so you can override a default setting in ``setup.cfg``.
+
+
+(Note: Because these options modify the version number used for source and
+binary distributions of your project, you should first make sure that you know
+how the resulting version numbers will be interpreted by automated tools
+like EasyInstall.  See the section above on `Specifying Your Project's
+Version`_ for an explanation of pre- and post-release tags, as well as tips on
+how to choose and verify a versioning scheme for your your project.)
+
+For advanced uses, there is one other option that can be set, to change the
+location of the project's ``.egg-info`` directory.  Commands that need to find
+the project's source directory or metadata should get it from this setting:
+
+
+Other ``egg_info`` Options
+--------------------------
+
+``--egg-base=SOURCEDIR, -e SOURCEDIR``
+    Specify the directory that should contain the .egg-info directory.  This
+    should normally be the root of your project's source tree (which is not
+    necessarily the same as your project directory; some projects use a ``src``
+    or ``lib`` subdirectory as the source root).  You should not normally need
+    to specify this directory, as it is normally determined from the
+    ``package_dir`` argument to the ``setup()`` function, if any.  If there is
+    no ``package_dir`` set, this option defaults to the current directory.
+
+
+``egg_info`` Examples
+---------------------
+
+Creating a dated "nightly build" snapshot egg::
+
+    python setup.py egg_info --tag-date --tag-build=DEV bdist_egg
+
+Creating and uploading a release with no version tags, even if some default
+tags are specified in ``setup.cfg``::
+
+    python setup.py egg_info -RDb "" sdist bdist_egg register upload
+
+(Notice that ``egg_info`` must always appear on the command line *before* any
+commands that you want the version changes to apply to.)
+
+
+.. _install command:
+
+``install`` - Run ``easy_install`` or old-style installation
+============================================================
+
+The setuptools ``install`` command is basically a shortcut to run the
+``easy_install`` command on the current project.  However, for convenience
+in creating "system packages" of setuptools-based projects, you can also
+use this option:
+
+``--single-version-externally-managed``
+    This boolean option tells the ``install`` command to perform an "old style"
+    installation, with the addition of an ``.egg-info`` directory so that the
+    installed project will still have its metadata available and operate
+    normally.  If you use this option, you *must* also specify the ``--root``
+    or ``--record`` options (or both), because otherwise you will have no way
+    to identify and remove the installed files.
+
+This option is automatically in effect when ``install`` is invoked by another
+distutils command, so that commands like ``bdist_wininst`` and ``bdist_rpm``
+will create system packages of eggs.  It is also automatically in effect if
+you specify the ``--root`` option.
+
+
+``install_egg_info`` - Install an ``.egg-info`` directory in ``site-packages``
+==============================================================================
+
+Setuptools runs this command as part of ``install`` operations that use the
+``--single-version-externally-managed`` options.  You should not invoke it
+directly; it is documented here for completeness and so that distutils
+extensions such as system package builders can make use of it.  This command
+has only one option:
+
+``--install-dir=DIR, -d DIR``
+    The parent directory where the ``.egg-info`` directory will be placed.
+    Defaults to the same as the ``--install-dir`` option specified for the
+    ``install_lib`` command, which is usually the system ``site-packages``
+    directory.
+
+This command assumes that the ``egg_info`` command has been given valid options
+via the command line or ``setup.cfg``, as it will invoke the ``egg_info``
+command and use its options to locate the project's source ``.egg-info``
+directory.
+
+
+.. _rotate:
+
+``rotate`` - Delete outdated distribution files
+===============================================
+
+As you develop new versions of your project, your distribution (``dist``)
+directory will gradually fill up with older source and/or binary distribution
+files.  The ``rotate`` command lets you automatically clean these up, keeping
+only the N most-recently modified files matching a given pattern.
+
+``--match=PATTERNLIST, -m PATTERNLIST``
+    Comma-separated list of glob patterns to match.  This option is *required*.
+    The project name and ``-*`` is prepended to the supplied patterns, in order
+    to match only distributions belonging to the current project (in case you
+    have a shared distribution directory for multiple projects).  Typically,
+    you will use a glob pattern like ``.zip`` or ``.egg`` to match files of
+    the specified type.  Note that each supplied pattern is treated as a
+    distinct group of files for purposes of selecting files to delete.
+
+``--keep=COUNT, -k COUNT``
+    Number of matching distributions to keep.  For each group of files
+    identified by a pattern specified with the ``--match`` option, delete all
+    but the COUNT most-recently-modified files in that group.  This option is
+    *required*.
+
+``--dist-dir=DIR, -d DIR``
+    Directory where the distributions are.  This defaults to the value of the
+    ``bdist`` command's ``--dist-dir`` option, which will usually be the
+    project's ``dist`` subdirectory.
+
+**Example 1**: Delete all .tar.gz files from the distribution directory, except
+for the 3 most recently modified ones::
+
+    setup.py rotate --match=.tar.gz --keep=3
+
+**Example 2**: Delete all Python 2.3 or Python 2.4 eggs from the distribution
+directory, except the most recently modified one for each Python version::
+
+    setup.py rotate --match=-py2.3*.egg,-py2.4*.egg --keep=1
+
+
+.. _saveopts:
+
+``saveopts`` - Save used options to a configuration file
+========================================================
+
+Finding and editing ``distutils`` configuration files can be a pain, especially
+since you also have to translate the configuration options from command-line
+form to the proper configuration file format.  You can avoid these hassles by
+using the ``saveopts`` command.  Just add it to the command line to save the
+options you used.  For example, this command builds the project using
+the ``mingw32`` C compiler, then saves the --compiler setting as the default
+for future builds (even those run implicitly by the ``install`` command)::
+
+    setup.py build --compiler=mingw32 saveopts
+
+The ``saveopts`` command saves all options for every command specified on the
+command line to the project's local ``setup.cfg`` file, unless you use one of
+the `configuration file options`_ to change where the options are saved.  For
+example, this command does the same as above, but saves the compiler setting
+to the site-wide (global) distutils configuration::
+
+    setup.py build --compiler=mingw32 saveopts -g
+
+Note that it doesn't matter where you place the ``saveopts`` command on the
+command line; it will still save all the options specified for all commands.
+For example, this is another valid way to spell the last example::
+
+    setup.py saveopts -g build --compiler=mingw32
+
+Note, however, that all of the commands specified are always run, regardless of
+where ``saveopts`` is placed on the command line.
+
+
+Configuration File Options
+--------------------------
+
+Normally, settings such as options and aliases are saved to the project's
+local ``setup.cfg`` file.  But you can override this and save them to the
+global or per-user configuration files, or to a manually-specified filename.
+
+``--global-config, -g``
+    Save settings to the global ``distutils.cfg`` file inside the ``distutils``
+    package directory.  You must have write access to that directory to use
+    this option.  You also can't combine this option with ``-u`` or ``-f``.
+
+``--user-config, -u``
+    Save settings to the current user's ``~/.pydistutils.cfg`` (POSIX) or
+    ``$HOME/pydistutils.cfg`` (Windows) file.  You can't combine this option
+    with ``-g`` or ``-f``.
+
+``--filename=FILENAME, -f FILENAME``
+    Save settings to the specified configuration file to use.  You can't
+    combine this option with ``-g`` or ``-u``.  Note that if you specify a
+    non-standard filename, the ``distutils`` and ``setuptools`` will not
+    use the file's contents.  This option is mainly included for use in
+    testing.
+
+These options are used by other ``setuptools`` commands that modify
+configuration files, such as the `alias`_ and `setopt`_ commands.
+
+
+.. _setopt:
+
+``setopt`` - Set a distutils or setuptools option in a config file
+==================================================================
+
+This command is mainly for use by scripts, but it can also be used as a quick
+and dirty way to change a distutils configuration option without having to
+remember what file the options are in and then open an editor.
+
+**Example 1**.  Set the default C compiler to ``mingw32`` (using long option
+names)::
+
+    setup.py setopt --command=build --option=compiler --set-value=mingw32
+
+**Example 2**.  Remove any setting for the distutils default package
+installation directory (short option names)::
+
+    setup.py setopt -c install -o install_lib -r
+
+
+Options for the ``setopt`` command:
+
+``--command=COMMAND, -c COMMAND``
+    Command to set the option for.  This option is required.
+
+``--option=OPTION, -o OPTION``
+    The name of the option to set.  This option is required.
+
+``--set-value=VALUE, -s VALUE``
+    The value to set the option to.  Not needed if ``-r`` or ``--remove`` is
+    set.
+
+``--remove, -r``
+    Remove (unset) the option, instead of setting it.
+
+In addition to the above options, you may use any of the `configuration file
+options`_ (listed under the `saveopts`_ command, above) to determine which
+distutils configuration file the option will be added to (or removed from).
+
+
+.. _test:
+
+``test`` - Build package and run a unittest suite
+=================================================
+
+When doing test-driven development, or running automated builds that need
+testing before they are deployed for downloading or use, it's often useful
+to be able to run a project's unit tests without actually deploying the project
+anywhere, even using the ``develop`` command.  The ``test`` command runs a
+project's unit tests without actually deploying it, by temporarily putting the
+project's source on ``sys.path``, after first running ``build_ext -i`` and
+``egg_info`` to ensure that any C extensions and project metadata are
+up-to-date.
+
+To use this command, your project's tests must be wrapped in a ``unittest``
+test suite by either a function, a ``TestCase`` class or method, or a module
+or package containing ``TestCase`` classes.  If the named suite is a module,
+and the module has an ``additional_tests()`` function, it is called and the
+result (which must be a ``unittest.TestSuite``) is added to the tests to be
+run.  If the named suite is a package, any submodules and subpackages are
+recursively added to the overall test suite.  (Note: if your project specifies
+a ``test_loader``, the rules for processing the chosen ``test_suite`` may
+differ; see the `test_loader`_ documentation for more details.)
+
+Note that many test systems including ``doctest`` support wrapping their
+non-``unittest`` tests in ``TestSuite`` objects.  So, if you are using a test
+package that does not support this, we suggest you encourage its developers to
+implement test suite support, as this is a convenient and standard way to
+aggregate a collection of tests to be run under a common test harness.
+
+By default, tests will be run in the "verbose" mode of the ``unittest``
+package's text test runner, but you can get the "quiet" mode (just dots) if
+you supply the ``-q`` or ``--quiet`` option, either as a global option to
+the setup script (e.g. ``setup.py -q test``) or as an option for the ``test``
+command itself (e.g. ``setup.py test -q``).  There is one other option
+available:
+
+``--test-suite=NAME, -s NAME``
+    Specify the test suite (or module, class, or method) to be run
+    (e.g. ``some_module.test_suite``).  The default for this option can be
+    set by giving a ``test_suite`` argument to the ``setup()`` function, e.g.::
+
+        setup(
+            # ...
+            test_suite="my_package.tests.test_all"
+        )
+
+    If you did not set a ``test_suite`` in your ``setup()`` call, and do not
+    provide a ``--test-suite`` option, an error will occur.
+
+
+.. _upload:
+
+``upload`` - Upload source and/or egg distributions to PyPI
+===========================================================
+
+The ``upload`` command is implemented and `documented
+<https://docs.python.org/3.1/distutils/uploading.html>`_
+in distutils.
+
+Setuptools augments the ``upload`` command with support
+for `keyring <https://pypi.python.org/pypi/keyring>`_,
+allowing the password to be stored in a secure
+location and not in plaintext in the .pypirc file. To use
+keyring, first install keyring and set the password for
+the relevant repository, e.g.::
+
+    python -m keyring set <repository> <username>
+    Password for '<username>' in '<repository>': ********
+
+Then, in .pypirc, set the repository configuration as normal,
+but omit the password. Thereafter, uploads will use the
+password from the keyring.
+
+New in 20.1: Added keyring support.
+
+
+-----------------------------------------
+Configuring setup() using setup.cfg files
+-----------------------------------------
+
+.. note:: New in 30.3.0 (8 Dec 2016).
+
+.. important::
+    A ``setup.py`` file containing a ``setup()`` function call is still
+    required even if your configuration resides in ``setup.cfg``.
+
+``Setuptools`` allows using configuration files (usually :file:`setup.cfg`)
+to define a package’s metadata and other options that are normally supplied
+to the ``setup()`` function.
+
+This approach not only allows automation scenarios but also reduces
+boilerplate code in some cases.
+
+.. note::
+
+    This implementation has limited compatibility with the distutils2-like
+    ``setup.cfg`` sections used by the ``pbr`` and ``d2to1`` packages.
+
+    Namely: only metadata-related keys from ``metadata`` section are supported
+    (except for ``description-file``); keys from ``files``, ``entry_points``
+    and ``backwards_compat`` are not supported.
+
+
+.. code-block:: ini
+
+    [metadata]
+    name = my_package
+    version = attr: src.VERSION
+    description = My package description
+    long_description = file: README.rst, CHANGELOG.rst, LICENSE.rst
+    keywords = one, two
+    license = BSD 3-Clause License
+    classifiers =
+        Framework :: Django
+        Programming Language :: Python :: 3
+        Programming Language :: Python :: 3.5
+
+    [options]
+    zip_safe = False
+    include_package_data = True
+    packages = find:
+    scripts =
+      bin/first.py
+      bin/second.py
+
+    [options.package_data]
+    * = *.txt, *.rst
+    hello = *.msg
+
+    [options.extras_require]
+    pdf = ReportLab>=1.2; RXP
+    rest = docutils>=0.3; pack ==1.1, ==1.3
+
+    [options.packages.find]
+    exclude =
+        src.subpackage1
+        src.subpackage2
+
+
+Metadata and options are set in the config sections of the same name.
+
+* Keys are the same as the keyword arguments one provides to the ``setup()``
+  function.
+
+* Complex values can be written comma-separated or placed one per line
+  in *dangling* config values. The following are equivalent:
+
+  .. code-block:: ini
+
+      [metadata]
+      keywords = one, two
+
+      [metadata]
+      keywords =
+        one
+        two
+
+* In some cases, complex values can be provided in dedicated subsections for
+  clarity.
+
+* Some keys allow ``file:``, ``attr:``, and ``find:`` directives in order to
+  cover common usecases.
+
+* Unknown keys are ignored.
+
+
+Specifying values
+=================
+
+Some values are treated as simple strings, some allow more logic.
+
+Type names used below:
+
+* ``str`` - simple string
+* ``list-comma`` - dangling list or string of comma-separated values
+* ``list-semi`` - dangling list or string of semicolon-separated values
+* ``bool`` - ``True`` is 1, yes, true
+* ``dict`` - list-comma where keys are separated from values by ``=``
+* ``section`` - values are read from a dedicated (sub)section
+
+
+Special directives:
+
+* ``attr:`` - Value is read from a module attribute.  ``attr:`` supports
+  callables and iterables; unsupported types are cast using ``str()``.
+* ``file:`` - Value is read from a list of files and then concatenated
+
+
+.. note::
+    The ``file:`` directive is sandboxed and won't reach anything outside
+    the directory containing ``setup.py``.
+
+
+Metadata
+--------
+
+.. note::
+    The aliases given below are supported for compatibility reasons,
+    but their use is not advised.
+
+==============================  =================  =====
+Key                             Aliases            Type
+==============================  =================  =====
+name                                               str
+version                                            attr:, str
+url                             home-page          str
+download_url                    download-url       str
+project_urls                                       dict
+author                                             str
+author_email                    author-email       str
+maintainer                                         str
+maintainer_email                maintainer-email   str
+classifiers                     classifier         file:, list-comma
+license                                            file:, str
+description                     summary            file:, str
+long_description                long-description   file:, str
+long_description_content_type                      str
+keywords                                           list-comma
+platforms                       platform           list-comma
+provides                                           list-comma
+requires                                           list-comma
+obsoletes                                          list-comma
+==============================  =================  =====
+
+
+Options
+-------
+
+=======================  =====
+Key                      Type
+=======================  =====
+zip_safe                 bool
+setup_requires           list-semi
+install_requires         list-semi
+extras_require           section
+python_requires          str
+entry_points             file:, section
+use_2to3                 bool
+use_2to3_fixers          list-comma
+use_2to3_exclude_fixers  list-comma
+convert_2to3_doctests    list-comma
+scripts                  list-comma
+eager_resources          list-comma
+dependency_links         list-comma
+tests_require            list-semi
+include_package_data     bool
+packages                 find:, list-comma
+package_dir              dict
+package_data             section
+exclude_package_data     section
+namespace_packages       list-comma
+py_modules               list-comma
+=======================  =====
+
+.. note::
+
+    **packages** - The ``find:`` directive can be further configured
+    in a dedicated subsection ``options.packages.find``. This subsection
+    accepts the same keys as the `setuptools.find` function:
+    ``where``, ``include``, and ``exclude``.
+
+
+Configuration API
+=================
+
+Some automation tools may wish to access data from a configuration file.
+
+``Setuptools`` exposes a ``read_configuration()`` function for
+parsing ``metadata`` and ``options`` sections into a dictionary.
+
+
+.. code-block:: python
+
+    from setuptools.config import read_configuration
+
+    conf_dict = read_configuration('/home/user/dev/package/setup.cfg')
+
+
+By default, ``read_configuration()`` will read only the file provided
+in the first argument. To include values from other configuration files
+which could be in various places, set the ``find_others`` keyword argument
+to ``True``.
+
+If you have only a configuration file but not the whole package, you can still
+try to get data out of it with the help of the ``ignore_option_errors`` keyword
+argument. When it is set to ``True``, all options with errors possibly produced
+by directives, such as ``attr:`` and others, will be silently ignored.
+As a consequence, the resulting dictionary will include no such options.
+
+
+--------------------------------
+Extending and Reusing Setuptools
+--------------------------------
+
+Creating ``distutils`` Extensions
+=================================
+
+It can be hard to add new commands or setup arguments to the distutils.  But
+the ``setuptools`` package makes it a bit easier, by allowing you to distribute
+a distutils extension as a separate project, and then have projects that need
+the extension just refer to it in their ``setup_requires`` argument.
+
+With ``setuptools``, your distutils extension projects can hook in new
+commands and ``setup()`` arguments just by defining "entry points".  These
+are mappings from command or argument names to a specification of where to
+import a handler from.  (See the section on `Dynamic Discovery of Services and
+Plugins`_ above for some more background on entry points.)
+
+
+Adding Commands
+---------------
+
+You can add new ``setup`` commands by defining entry points in the
+``distutils.commands`` group.  For example, if you wanted to add a ``foo``
+command, you might add something like this to your distutils extension
+project's setup script::
+
+    setup(
+        # ...
+        entry_points={
+            "distutils.commands": [
+                "foo = mypackage.some_module:foo",
+            ],
+        },
+    )
+
+(Assuming, of course, that the ``foo`` class in ``mypackage.some_module`` is
+a ``setuptools.Command`` subclass.)
+
+Once a project containing such entry points has been activated on ``sys.path``,
+(e.g. by running "install" or "develop" with a site-packages installation
+directory) the command(s) will be available to any ``setuptools``-based setup
+scripts.  It is not necessary to use the ``--command-packages`` option or
+to monkeypatch the ``distutils.command`` package to install your commands;
+``setuptools`` automatically adds a wrapper to the distutils to search for
+entry points in the active distributions on ``sys.path``.  In fact, this is
+how setuptools' own commands are installed: the setuptools project's setup
+script defines entry points for them!
+
+
+Adding ``setup()`` Arguments
+----------------------------
+
+Sometimes, your commands may need additional arguments to the ``setup()``
+call.  You can enable this by defining entry points in the
+``distutils.setup_keywords`` group.  For example, if you wanted a ``setup()``
+argument called ``bar_baz``, you might add something like this to your
+distutils extension project's setup script::
+
+    setup(
+        # ...
+        entry_points={
+            "distutils.commands": [
+                "foo = mypackage.some_module:foo",
+            ],
+            "distutils.setup_keywords": [
+                "bar_baz = mypackage.some_module:validate_bar_baz",
+            ],
+        },
+    )
+
+The idea here is that the entry point defines a function that will be called
+to validate the ``setup()`` argument, if it's supplied.  The ``Distribution``
+object will have the initial value of the attribute set to ``None``, and the
+validation function will only be called if the ``setup()`` call sets it to
+a non-None value.  Here's an example validation function::
+
+    def assert_bool(dist, attr, value):
+        """Verify that value is True, False, 0, or 1"""
+        if bool(value) != value:
+            raise DistutilsSetupError(
+                "%r must be a boolean value (got %r)" % (attr,value)
+            )
+
+Your function should accept three arguments: the ``Distribution`` object,
+the attribute name, and the attribute value.  It should raise a
+``DistutilsSetupError`` (from the ``distutils.errors`` module) if the argument
+is invalid.  Remember, your function will only be called with non-None values,
+and the default value of arguments defined this way is always None.  So, your
+commands should always be prepared for the possibility that the attribute will
+be ``None`` when they access it later.
+
+If more than one active distribution defines an entry point for the same
+``setup()`` argument, *all* of them will be called.  This allows multiple
+distutils extensions to define a common argument, as long as they agree on
+what values of that argument are valid.
+
+Also note that as with commands, it is not necessary to subclass or monkeypatch
+the distutils ``Distribution`` class in order to add your arguments; it is
+sufficient to define the entry points in your extension, as long as any setup
+script using your extension lists your project in its ``setup_requires``
+argument.
+
+
+Adding new EGG-INFO Files
+-------------------------
+
+Some extensible applications or frameworks may want to allow third parties to
+develop plugins with application or framework-specific metadata included in
+the plugins' EGG-INFO directory, for easy access via the ``pkg_resources``
+metadata API.  The easiest way to allow this is to create a distutils extension
+to be used from the plugin projects' setup scripts (via ``setup_requires``)
+that defines a new setup keyword, and then uses that data to write an EGG-INFO
+file when the ``egg_info`` command is run.
+
+The ``egg_info`` command looks for extension points in an ``egg_info.writers``
+group, and calls them to write the files.  Here's a simple example of a
+distutils extension defining a setup argument ``foo_bar``, which is a list of
+lines that will be written to ``foo_bar.txt`` in the EGG-INFO directory of any
+project that uses the argument::
+
+    setup(
+        # ...
+        entry_points={
+            "distutils.setup_keywords": [
+                "foo_bar = setuptools.dist:assert_string_list",
+            ],
+            "egg_info.writers": [
+                "foo_bar.txt = setuptools.command.egg_info:write_arg",
+            ],
+        },
+    )
+
+This simple example makes use of two utility functions defined by setuptools
+for its own use: a routine to validate that a setup keyword is a sequence of
+strings, and another one that looks up a setup argument and writes it to
+a file.  Here's what the writer utility looks like::
+
+    def write_arg(cmd, basename, filename):
+        argname = os.path.splitext(basename)[0]
+        value = getattr(cmd.distribution, argname, None)
+        if value is not None:
+            value = '\n'.join(value) + '\n'
+        cmd.write_or_delete_file(argname, filename, value)
+
+As you can see, ``egg_info.writers`` entry points must be a function taking
+three arguments: a ``egg_info`` command instance, the basename of the file to
+write (e.g. ``foo_bar.txt``), and the actual full filename that should be
+written to.
+
+In general, writer functions should honor the command object's ``dry_run``
+setting when writing files, and use the ``distutils.log`` object to do any
+console output.  The easiest way to conform to this requirement is to use
+the ``cmd`` object's ``write_file()``, ``delete_file()``, and
+``write_or_delete_file()`` methods exclusively for your file operations.  See
+those methods' docstrings for more details.
+
+
+Adding Support for Revision Control Systems
+-------------------------------------------------
+
+If the files you want to include in the source distribution are tracked using
+Git, Mercurial or SVN, you can use the following packages to achieve that:
+
+- Git and Mercurial: `setuptools_scm <https://pypi.python.org/pypi/setuptools_scm>`_
+- SVN: `setuptools_svn <https://pypi.python.org/pypi/setuptools_svn>`_
+
+If you would like to create a plugin for ``setuptools`` to find files tracked
+by another revision control system, you can do so by adding an entry point to
+the ``setuptools.file_finders`` group.  The entry point should be a function
+accepting a single directory name, and should yield all the filenames within
+that directory (and any subdirectories thereof) that are under revision
+control.
+
+For example, if you were going to create a plugin for a revision control system
+called "foobar", you would write a function something like this:
+
+.. code-block:: python
+
+    def find_files_for_foobar(dirname):
+        # loop to yield paths that start with `dirname`
+
+And you would register it in a setup script using something like this::
+
+    entry_points={
+        "setuptools.file_finders": [
+            "foobar = my_foobar_module:find_files_for_foobar",
+        ]
+    }
+
+Then, anyone who wants to use your plugin can simply install it, and their
+local setuptools installation will be able to find the necessary files.
+
+It is not necessary to distribute source control plugins with projects that
+simply use the other source control system, or to specify the plugins in
+``setup_requires``.  When you create a source distribution with the ``sdist``
+command, setuptools automatically records what files were found in the
+``SOURCES.txt`` file.  That way, recipients of source distributions don't need
+to have revision control at all.  However, if someone is working on a package
+by checking out with that system, they will need the same plugin(s) that the
+original author is using.
+
+A few important points for writing revision control file finders:
+
+* Your finder function MUST return relative paths, created by appending to the
+  passed-in directory name.  Absolute paths are NOT allowed, nor are relative
+  paths that reference a parent directory of the passed-in directory.
+
+* Your finder function MUST accept an empty string as the directory name,
+  meaning the current directory.  You MUST NOT convert this to a dot; just
+  yield relative paths.  So, yielding a subdirectory named ``some/dir`` under
+  the current directory should NOT be rendered as ``./some/dir`` or
+  ``/somewhere/some/dir``, but *always* as simply ``some/dir``
+
+* Your finder function SHOULD NOT raise any errors, and SHOULD deal gracefully
+  with the absence of needed programs (i.e., ones belonging to the revision
+  control system itself.  It *may*, however, use ``distutils.log.warn()`` to
+  inform the user of the missing program(s).
+
+
+Subclassing ``Command``
+-----------------------
+
+Sorry, this section isn't written yet, and neither is a lot of what's below
+this point.
+
+XXX
+
+
+Reusing ``setuptools`` Code
+===========================
+
+``ez_setup``
+------------
+
+XXX
+
+
+``setuptools.archive_util``
+---------------------------
+
+XXX
+
+
+``setuptools.sandbox``
+----------------------
+
+XXX
+
+
+``setuptools.package_index``
+----------------------------
+
+XXX
+
+
+Mailing List and Bug Tracker
+============================
+
+Please use the `distutils-sig mailing list`_ for questions and discussion about
+setuptools, and the `setuptools bug tracker`_ ONLY for issues you have
+confirmed via the list are actual bugs, and which you have reduced to a minimal
+set of steps to reproduce.
+
+.. _distutils-sig mailing list: http://mail.python.org/pipermail/distutils-sig/
+.. _setuptools bug tracker: https://github.com/pypa/setuptools/
diff --git a/vendor/setuptools-39.0.1/easy_install.py b/vendor/setuptools-39.0.1/easy_install.py
new file mode 100755
index 00000000..d87e9840
--- /dev/null
+++ b/vendor/setuptools-39.0.1/easy_install.py
@@ -0,0 +1,5 @@
+"""Run the EasyInstall command"""
+
+if __name__ == '__main__':
+    from setuptools.command.easy_install import main
+    main()
diff --git a/vendor/setuptools-39.0.1/launcher.c b/vendor/setuptools-39.0.1/launcher.c
new file mode 100755
index 00000000..be69f0c6
--- /dev/null
+++ b/vendor/setuptools-39.0.1/launcher.c
@@ -0,0 +1,335 @@
+/*  Setuptools Script Launcher for Windows
+
+    This is a stub executable for Windows that functions somewhat like
+    Effbot's "exemaker", in that it runs a script with the same name but
+    a .py extension, using information from a #! line.  It differs in that
+    it spawns the actual Python executable, rather than attempting to
+    hook into the Python DLL.  This means that the script will run with
+    sys.executable set to the Python executable, where exemaker ends up with
+    sys.executable pointing to itself.  (Which means it won't work if you try
+    to run another Python process using sys.executable.)
+
+    To build/rebuild with mingw32, do this in the setuptools project directory:
+
+       gcc -DGUI=0           -mno-cygwin -O -s -o setuptools/cli.exe launcher.c
+       gcc -DGUI=1 -mwindows -mno-cygwin -O -s -o setuptools/gui.exe launcher.c
+
+    To build for Windows RT, install both Visual Studio Express for Windows 8
+    and for Windows Desktop (both freeware), create "win32" application using
+    "Windows Desktop" version, create new "ARM" target via
+    "Configuration Manager" menu and modify ".vcxproj" file by adding
+    "<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>" tag
+    as child of "PropertyGroup" tags that has "Debug|ARM" and "Release|ARM"
+    properties.
+
+    It links to msvcrt.dll, but this shouldn't be a problem since it doesn't
+    actually run Python in the same process.  Note that using 'exec' instead
+    of 'spawn' doesn't work, because on Windows this leads to the Python
+    executable running in the *background*, attached to the same console
+    window, meaning you get a command prompt back *before* Python even finishes
+    starting.  So, we have to use spawnv() and wait for Python to exit before
+    continuing.  :(
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <windows.h>
+#include <tchar.h>
+#include <fcntl.h>
+
+int child_pid=0;
+
+int fail(char *format, char *data) {
+    /* Print error message to stderr and return 2 */
+    fprintf(stderr, format, data);
+    return 2;
+}
+
+char *quoted(char *data) {
+    int i, ln = strlen(data), nb;
+
+    /* We allocate twice as much space as needed to deal with worse-case
+       of having to escape everything. */
+    char *result = calloc(ln*2+3, sizeof(char));
+    char *presult = result;
+
+    *presult++ = '"';
+    for (nb=0, i=0; i < ln; i++)
+      {
+        if (data[i] == '\\')
+          nb += 1;
+        else if (data[i] == '"')
+          {
+            for (; nb > 0; nb--)
+              *presult++ = '\\';
+            *presult++ = '\\';
+          }
+        else
+          nb = 0;
+        *presult++ = data[i];
+      }
+
+    for (; nb > 0; nb--)        /* Deal w trailing slashes */
+      *presult++ = '\\';
+
+    *presult++ = '"';
+    *presult++ = 0;
+    return result;
+}
+
+
+
+
+
+
+
+
+
+
+char *loadable_exe(char *exename) {
+    /* HINSTANCE hPython;  DLL handle for python executable */
+    char *result;
+
+    /* hPython = LoadLibraryEx(exename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+    if (!hPython) return NULL; */
+
+    /* Return the absolute filename for spawnv */
+    result = calloc(MAX_PATH, sizeof(char));
+    strncpy(result, exename, MAX_PATH);
+    /*if (result) GetModuleFileNameA(hPython, result, MAX_PATH);
+
+    FreeLibrary(hPython); */
+    return result;
+}
+
+
+char *find_exe(char *exename, char *script) {
+    char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
+    char path[_MAX_PATH], c, *result;
+
+    /* convert slashes to backslashes for uniform search below */
+    result = exename;
+    while (c = *result++) if (c=='/') result[-1] = '\\';
+
+    _splitpath(exename, drive, dir, fname, ext);
+    if (drive[0] || dir[0]=='\\') {
+        return loadable_exe(exename);   /* absolute path, use directly */
+    }
+    /* Use the script's parent directory, which should be the Python home
+       (This should only be used for bdist_wininst-installed scripts, because
+        easy_install-ed scripts use the absolute path to python[w].exe
+    */
+    _splitpath(script, drive, dir, fname, ext);
+    result = dir + strlen(dir) -1;
+    if (*result == '\\') result--;
+    while (*result != '\\' && result>=dir) *result-- = 0;
+    _makepath(path, drive, dir, exename, NULL);
+    return loadable_exe(path);
+}
+
+
+char **parse_argv(char *cmdline, int *argc)
+{
+    /* Parse a command line in-place using MS C rules */
+
+    char **result = calloc(strlen(cmdline), sizeof(char *));
+    char *output = cmdline;
+    char c;
+    int nb = 0;
+    int iq = 0;
+    *argc = 0;
+
+    result[0] = output;
+    while (isspace(*cmdline)) cmdline++;   /* skip leading spaces */
+
+    do {
+        c = *cmdline++;
+        if (!c || (isspace(c) && !iq)) {
+            while (nb) {*output++ = '\\'; nb--; }
+            *output++ = 0;
+            result[++*argc] = output;
+            if (!c) return result;
+            while (isspace(*cmdline)) cmdline++;  /* skip leading spaces */
+            if (!*cmdline) return result;  /* avoid empty arg if trailing ws */
+            continue;
+        }
+        if (c == '\\')
+            ++nb;   /* count \'s */
+        else {
+            if (c == '"') {
+                if (!(nb & 1)) { iq = !iq; c = 0; }  /* skip " unless odd # of \ */
+                nb = nb >> 1;   /* cut \'s in half */
+            }
+            while (nb) {*output++ = '\\'; nb--; }
+            if (c) *output++ = c;
+        }
+    } while (1);
+}
+
+void pass_control_to_child(DWORD control_type) {
+    /*
+     * distribute-issue207
+     * passes the control event to child process (Python)
+     */
+    if (!child_pid) {
+        return;
+    }
+    GenerateConsoleCtrlEvent(child_pid,0);
+}
+
+BOOL control_handler(DWORD control_type) {
+    /* 
+     * distribute-issue207
+     * control event handler callback function
+     */
+    switch (control_type) {
+        case CTRL_C_EVENT:
+            pass_control_to_child(0);
+            break;
+    }
+    return TRUE;
+}
+
+int create_and_wait_for_subprocess(char* command) {
+    /*
+     * distribute-issue207
+     * launches child process (Python)
+     */
+    DWORD return_value = 0;
+    LPSTR commandline = command;
+    STARTUPINFOA s_info;
+    PROCESS_INFORMATION p_info;
+    ZeroMemory(&p_info, sizeof(p_info));
+    ZeroMemory(&s_info, sizeof(s_info));
+    s_info.cb = sizeof(STARTUPINFO);
+    // set-up control handler callback funciotn
+    SetConsoleCtrlHandler((PHANDLER_ROUTINE) control_handler, TRUE);
+    if (!CreateProcessA(NULL, commandline, NULL, NULL, TRUE, 0, NULL, NULL, &s_info, &p_info)) {
+        fprintf(stderr, "failed to create process.\n");
+        return 0;
+    }   
+    child_pid = p_info.dwProcessId;
+    // wait for Python to exit
+    WaitForSingleObject(p_info.hProcess, INFINITE);
+    if (!GetExitCodeProcess(p_info.hProcess, &return_value)) {
+        fprintf(stderr, "failed to get exit code from process.\n");
+        return 0;
+    }
+    return return_value;
+}
+
+char* join_executable_and_args(char *executable, char **args, int argc)
+{
+    /*
+     * distribute-issue207
+     * CreateProcess needs a long string of the executable and command-line arguments,
+     * so we need to convert it from the args that was built
+     */
+    int len,counter;
+    char* cmdline;
+    
+    len=strlen(executable)+2;
+    for (counter=1; counter<argc; counter++) {
+        len+=strlen(args[counter])+1;
+    }
+
+    cmdline = (char*)calloc(len, sizeof(char));
+    sprintf(cmdline, "%s", executable);
+    len=strlen(executable);
+    for (counter=1; counter<argc; counter++) {
+        sprintf(cmdline+len, " %s", args[counter]);
+        len+=strlen(args[counter])+1;
+    }
+    return cmdline;
+}
+
+int run(int argc, char **argv, int is_gui) {
+
+    char python[256];   /* python executable's filename*/
+    char *pyopt;        /* Python option */
+    char script[256];   /* the script's filename */
+
+    int scriptf;        /* file descriptor for script file */
+
+    char **newargs, **newargsp, **parsedargs; /* argument array for exec */
+    char *ptr, *end;    /* working pointers for string manipulation */
+    char *cmdline;
+    int i, parsedargc;              /* loop counter */
+
+    /* compute script name from our .exe name*/
+    GetModuleFileNameA(NULL, script, sizeof(script));
+    end = script + strlen(script);
+    while( end>script && *end != '.')
+        *end-- = '\0';
+    *end-- = '\0';
+    strcat(script, (GUI ? "-script.pyw" : "-script.py"));
+
+    /* figure out the target python executable */
+
+    scriptf = open(script, O_RDONLY);
+    if (scriptf == -1) {
+        return fail("Cannot open %s\n", script);
+    }
+    end = python + read(scriptf, python, sizeof(python));
+    close(scriptf);
+
+    ptr = python-1;
+    while(++ptr < end && *ptr && *ptr!='\n' && *ptr!='\r') {;}
+
+    *ptr-- = '\0';
+
+    if (strncmp(python, "#!", 2)) {
+        /* default to python.exe if no #! header */
+        strcpy(python, "#!python.exe");
+    }
+
+    parsedargs = parse_argv(python+2, &parsedargc);
+
+    /* Using spawnv() can fail strangely if you e.g. find the Cygwin
+       Python, so we'll make sure Windows can find and load it */
+
+    ptr = find_exe(parsedargs[0], script);
+    if (!ptr) {
+        return fail("Cannot find Python executable %s\n", parsedargs[0]);
+    }
+
+    /* printf("Python executable: %s\n", ptr); */
+
+    /* Argument array needs to be
+       parsedargc + argc, plus 1 for null sentinel */
+
+    newargs = (char **)calloc(parsedargc + argc + 1, sizeof(char *));
+    newargsp = newargs;
+
+    *newargsp++ = quoted(ptr);
+    for (i = 1; i<parsedargc; i++) *newargsp++ = quoted(parsedargs[i]);
+
+    *newargsp++ = quoted(script);
+    for (i = 1; i < argc; i++)     *newargsp++ = quoted(argv[i]);
+
+    *newargsp++ = NULL;
+
+    /* printf("args 0: %s\nargs 1: %s\n", newargs[0], newargs[1]); */
+
+    if (is_gui) {
+        /* Use exec, we don't need to wait for the GUI to finish */
+        execv(ptr, (const char * const *)(newargs));
+        return fail("Could not exec %s", ptr);   /* shouldn't get here! */
+    }
+
+    /*
+     * distribute-issue207: using CreateProcessA instead of spawnv
+     */
+    cmdline = join_executable_and_args(ptr, newargs, parsedargc + argc);
+    return create_and_wait_for_subprocess(cmdline);
+}
+
+int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR lpCmd, int nShow) {
+    return run(__argc, __argv, GUI);
+}
+
+int main(int argc, char** argv) {
+    return run(argc, argv, GUI);
+}
+
diff --git a/vendor/setuptools-39.0.1/msvc-build-launcher.cmd b/vendor/setuptools-39.0.1/msvc-build-launcher.cmd
new file mode 100644
index 00000000..92da290e
--- /dev/null
+++ b/vendor/setuptools-39.0.1/msvc-build-launcher.cmd
@@ -0,0 +1,39 @@
+@echo off
+
+REM Use old Windows SDK 6.1 so created .exe will be compatible with
+REM old Windows versions.
+REM Windows SDK 6.1 may be downloaded at:
+REM  http://www.microsoft.com/en-us/download/details.aspx?id=11310
+set PATH_OLD=%PATH%
+
+REM The SDK creates a false install of Visual Studio at one of these locations
+set PATH=C:\Program Files\Microsoft Visual Studio 9.0\VC\bin;%PATH%
+set PATH=C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin;%PATH%
+
+REM set up the environment to compile to x86
+call VCVARS32
+if "%ERRORLEVEL%"=="0" (
+  cl /D "GUI=0" /D "WIN32_LEAN_AND_MEAN" launcher.c /O2 /link /MACHINE:x86 /SUBSYSTEM:CONSOLE /out:setuptools/cli-32.exe
+  cl /D "GUI=1" /D "WIN32_LEAN_AND_MEAN" launcher.c /O2 /link /MACHINE:x86 /SUBSYSTEM:WINDOWS /out:setuptools/gui-32.exe
+) else (
+  echo Windows SDK 6.1 not found to build Windows 32-bit version
+)
+
+REM buildout (and possibly other implementations) currently depend on
+REM the 32-bit launcher scripts without the -32 in the filename, so copy them
+REM there for now.
+copy setuptools/cli-32.exe setuptools/cli.exe
+copy setuptools/gui-32.exe setuptools/gui.exe
+
+REM now for 64-bit
+REM Use the x86_amd64 profile, which is the 32-bit cross compiler for amd64
+call VCVARSx86_amd64
+if "%ERRORLEVEL%"=="0" (
+  cl /D "GUI=0" /D "WIN32_LEAN_AND_MEAN" launcher.c /O2 /link /MACHINE:x64 /SUBSYSTEM:CONSOLE /out:setuptools/cli-64.exe
+  cl /D "GUI=1" /D "WIN32_LEAN_AND_MEAN" launcher.c /O2 /link /MACHINE:x64 /SUBSYSTEM:WINDOWS /out:setuptools/gui-64.exe
+) else (
+  echo Windows SDK 6.1 not found to build Windows 64-bit version
+)
+
+set PATH=%PATH_OLD%
+
diff --git a/vendor/setuptools-39.0.1/pavement.py b/vendor/setuptools-39.0.1/pavement.py
new file mode 100644
index 00000000..84e5825d
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pavement.py
@@ -0,0 +1,62 @@
+import re
+
+from paver.easy import task, path as Path
+import pip
+
+
+def remove_all(paths):
+    for path in paths:
+        path.rmtree() if path.isdir() else path.remove()
+
+
+@task
+def update_vendored():
+    update_pkg_resources()
+    update_setuptools()
+
+
+def rewrite_packaging(pkg_files, new_root):
+    """
+    Rewrite imports in packaging to redirect to vendored copies.
+    """
+    for file in pkg_files.glob('*.py'):
+        text = file.text()
+        text = re.sub(r' (pyparsing|six)', rf' {new_root}.\1', text)
+        file.write_text(text)
+
+
+def clean(vendor):
+    """
+    Remove all files out of the vendor directory except the meta
+    data (as pip uninstall doesn't support -t).
+    """
+    remove_all(
+        path
+        for path in vendor.glob('*')
+        if path.basename() != 'vendored.txt'
+    )
+
+
+def install(vendor):
+    clean(vendor)
+    install_args = [
+        'install',
+        '-r', str(vendor / 'vendored.txt'),
+        '-t', str(vendor),
+    ]
+    pip.main(install_args)
+    remove_all(vendor.glob('*.dist-info'))
+    remove_all(vendor.glob('*.egg-info'))
+    (vendor / '__init__.py').write_text('')
+
+
+def update_pkg_resources():
+    vendor = Path('pkg_resources/_vendor')
+    install(vendor)
+    rewrite_packaging(vendor / 'packaging', 'pkg_resources.extern')
+
+
+def update_setuptools():
+    vendor = Path('setuptools/_vendor')
+    install(vendor)
+    rewrite_packaging(vendor / 'packaging', 'setuptools.extern')
diff --git a/vendor/setuptools-39.0.1/pkg_resources/__init__.py b/vendor/setuptools-39.0.1/pkg_resources/__init__.py
new file mode 100644
index 00000000..8d95bd29
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/__init__.py
@@ -0,0 +1,3125 @@
+# coding: utf-8
+"""
+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.
+"""
+
+from __future__ import absolute_import
+
+import sys
+import os
+import io
+import time
+import re
+import types
+import zipfile
+import zipimport
+import warnings
+import stat
+import functools
+import pkgutil
+import operator
+import platform
+import collections
+import plistlib
+import email.parser
+import errno
+import tempfile
+import textwrap
+import itertools
+import inspect
+from pkgutil import get_importer
+
+try:
+    import _imp
+except ImportError:
+    # Python 3.2 compatibility
+    import imp as _imp
+
+from pkg_resources.extern import six
+from pkg_resources.extern.six.moves import urllib, map, filter
+
+# 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
+
+try:
+    import importlib.machinery as importlib_machinery
+    # access attribute to force import under delayed import mechanisms.
+    importlib_machinery.__name__
+except ImportError:
+    importlib_machinery = None
+
+from . import py31compat
+from pkg_resources.extern import appdirs
+from pkg_resources.extern import packaging
+__import__('pkg_resources.extern.packaging.version')
+__import__('pkg_resources.extern.packaging.specifiers')
+__import__('pkg_resources.extern.packaging.requirements')
+__import__('pkg_resources.extern.packaging.markers')
+
+
+if (3, 0) < sys.version_info < (3, 3):
+    raise RuntimeError("Python 3.3 or later is required")
+
+if six.PY2:
+    # Those builtin exceptions are only defined in Python 3
+    PermissionError = None
+    NotADirectoryError = None
+
+# declare some globals that will be defined later to
+# satisfy the linters.
+require = None
+working_set = None
+add_activation_listener = None
+resources_stream = None
+cleanup_resources = None
+resource_dir = None
+resource_stream = None
+set_extraction_path = None
+resource_isdir = None
+resource_string = None
+iter_entry_points = None
+resource_listdir = None
+resource_filename = None
+resource_exists = None
+_distribution_finders = None
+_namespace_handlers = None
+_namespace_packages = None
+
+
+class PEP440Warning(RuntimeWarning):
+    """
+    Used when there is an issue with a version or specifier not complying with
+    PEP 440.
+    """
+
+
+def parse_version(v):
+    try:
+        return packaging.version.Version(v)
+    except packaging.version.InvalidVersion:
+        return packaging.version.LegacyVersion(v)
+
+
+_state_vars = {}
+
+
+def _declare_state(vartype, **kw):
+    globals().update(kw)
+    _state_vars.update(dict.fromkeys(kw, 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:
+            # not Mac OS X
+            pass
+    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',
+
+    # Warnings
+    'PEP440Warning',
+
+    # 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', 'invalid_marker', 'evaluate_marker',
+
+    # 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.
+
+    Should be initialized with the installed Distribution and the requested
+    Requirement.
+    """
+
+    _template = "{self.dist} is installed but {self.req} is required"
+
+    @property
+    def dist(self):
+        return self.args[0]
+
+    @property
+    def req(self):
+        return self.args[1]
+
+    def report(self):
+        return self._template.format(**locals())
+
+    def with_context(self, required_by):
+        """
+        If required_by is non-empty, return a version of self that is a
+        ContextualVersionConflict.
+        """
+        if not required_by:
+            return self
+        args = self.args + (required_by,)
+        return ContextualVersionConflict(*args)
+
+
+class ContextualVersionConflict(VersionConflict):
+    """
+    A VersionConflict that accepts a third parameter, the set of the
+    requirements that required the installed Distribution.
+    """
+
+    _template = VersionConflict._template + ' by {self.required_by}'
+
+    @property
+    def required_by(self):
+        return self.args[2]
+
+
+class DistributionNotFound(ResolutionError):
+    """A requested distribution was not found"""
+
+    _template = ("The '{self.req}' distribution was not found "
+                 "and is required by {self.requirers_str}")
+
+    @property
+    def req(self):
+        return self.args[0]
+
+    @property
+    def requirers(self):
+        return self.args[1]
+
+    @property
+    def requirers_str(self):
+        if not self.requirers:
+            return 'the application'
+        return ', '.join(self.requirers)
+
+    def report(self):
+        return self._template.format(**locals())
+
+    def __str__(self):
+        return self.report()
+
+
+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:
+        version = platform.mac_ver()[0]
+        # fallback for MacPorts
+        if version == '':
+            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:
+        # Python 2.7 or >=3.2
+        from sysconfig import get_platform
+    except ImportError:
+        from distutils.util 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+)-(.*)")
+# XXX backward compat
+get_platform = get_build_platform
+
+
+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:
+        # easy case
+        return True
+
+    # 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":
+                    return True
+            # egg isn't macosx or legacy darwin
+            return False
+
+        # 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)
+
+
+# backward compatibility
+run_main = run_script
+
+
+def get_distribution(dist):
+    """Return a current distribution object for a Requirement or string"""
+    if isinstance(dist, six.string_types):
+        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)
+
+    @classmethod
+    def _build_master(cls):
+        """
+        Prepare the master working set.
+        """
+        ws = cls()
+        try:
+            from __main__ import __requires__
+        except ImportError:
+            # The main program does not list any requirements
+            return ws
+
+        # ensure the requirements are met
+        try:
+            ws.require(__requires__)
+        except VersionConflict:
+            return cls._build_from_requirements(__requires__)
+
+        return ws
+
+    @classmethod
+    def _build_from_requirements(cls, req_spec):
+        """
+        Build a working set from a requirement spec. Rewrites sys.path.
+        """
+        # try it without defaults already on sys.path
+        # by starting with an empty path
+        ws = cls([])
+        reqs = parse_requirements(req_spec)
+        dists = ws.resolve(reqs, Environment())
+        for dist in dists:
+            ws.add(dist)
+
+        # add any missing entries from sys.path
+        for entry in sys.path:
+            if entry not in ws.entries:
+                ws.add_entry(entry)
+
+        # then copy back to sys.path
+        sys.path[:] = ws.entries
+        return ws
+
+    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:
+            # XXX add more info
+            raise VersionConflict(dist, req)
+        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 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, replace=False):
+        """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, unless `replace=True`.
+        If it's added, any callbacks registered with the ``subscribe()`` method
+        will be called.
+        """
+        if insert:
+            dist.insert_on(self.entries, entry, replace=replace)
+
+        if entry is None:
+            entry = dist.location
+        keys = self.entry_keys.setdefault(entry, [])
+        keys2 = self.entry_keys.setdefault(dist.location, [])
+        if not replace and dist.key in self.by_key:
+            # ignore hidden distros
+            return
+
+        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,
+                replace_conflicting=False, extras=None):
+        """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``.
+
+        Unless `replace_conflicting=True`, raises a VersionConflict exception
+        if
+        any requirements are found on the path that have the correct name but
+        the wrong version.  Otherwise, if an `installer` is supplied it will be
+        invoked to obtain the correct version of the requirement and activate
+        it.
+
+        `extras` is a list of the extras to be used with these requirements.
+        This is important because extra requirements may look like `my_req;
+        extra = "my_extra"`, which would otherwise be interpreted as a purely
+        optional requirement.  Instead, we want to be able to assert that these
+        requirements are truly required.
+        """
+
+        # set up the stack
+        requirements = list(requirements)[::-1]
+        # set of processed requirements
+        processed = {}
+        # key -> dist
+        best = {}
+        to_activate = []
+
+        req_extras = _ReqExtras()
+
+        # Mapping of requirement to set of distributions that required it;
+        # useful for reporting info about conflicts.
+        required_by = collections.defaultdict(set)
+
+        while requirements:
+            # process dependencies breadth-first
+            req = requirements.pop(0)
+            if req in processed:
+                # Ignore cyclic or redundant dependencies
+                continue
+
+            if not req_extras.markers_pass(req, extras):
+                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 or (dist not in req and replace_conflicting):
+                    ws = self
+                    if env is None:
+                        if dist is None:
+                            env = Environment(self.entries)
+                        else:
+                            # Use an empty environment and workingset to avoid
+                            # any further conflicts with the conflicting
+                            # distribution
+                            env = Environment([])
+                            ws = WorkingSet([])
+                    dist = best[req.key] = env.best_match(
+                        req, ws, installer,
+                        replace_conflicting=replace_conflicting
+                    )
+                    if dist is None:
+                        requirers = required_by.get(req, None)
+                        raise DistributionNotFound(req, requirers)
+                to_activate.append(dist)
+            if dist not in req:
+                # Oops, the "best" so far conflicts with a dependency
+                dependent_req = required_by[req]
+                raise VersionConflict(dist, req).with_context(dependent_req)
+
+            # push the new requirements onto the stack
+            new_requirements = dist.requires(req.extras)[::-1]
+            requirements.extend(new_requirements)
+
+            # Register the new requirements needed by req
+            for new_requirement in new_requirements:
+                required_by[new_requirement].add(req.project_name)
+                req_extras[new_requirement] = req.extras
+
+            processed[req] = True
+
+        # return list of distros to activate
+        return 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)
+            )
+            # add plugins+libs to sys.path
+            map(working_set.add, distributions)
+            # display errors
+            print('Could not load', 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)
+        # scan project names in alphabetic order
+        plugin_projects.sort()
+
+        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__([])
+        # put all our entries in shadow_set
+        list(map(shadow_set.add, self))
+
+        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:
+                    # save error info
+                    error_info[dist] = v
+                    if fallback:
+                        # try the next older version of project
+                        continue
+                    else:
+                        # give up on this project, keep going
+                        break
+
+                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, existing=True):
+        """Invoke `callback` for all distributions
+
+        If `existing=True` (default),
+        call on all existing ones, as well.
+        """
+        if callback in self.callbacks:
+            return
+        self.callbacks.append(callback)
+        if not existing:
+            return
+        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, e_k_b_c):
+        entries, keys, by_key, callbacks = e_k_b_c
+        self.entries = entries[:]
+        self.entry_keys = keys.copy()
+        self.by_key = by_key.copy()
+        self.callbacks = callbacks[:]
+
+
+class _ReqExtras(dict):
+    """
+    Map each requirement to the extras that demanded it.
+    """
+
+    def markers_pass(self, req, extras=None):
+        """
+        Evaluate markers for req against each extra that
+        demanded it.
+
+        Return False if the req has a marker and fails
+        evaluation. Otherwise, return True.
+        """
+        extra_evals = (
+            req.marker.evaluate({'extra': extra})
+            for extra in self.get(req, ()) + (extras or (None,))
+        )
+        return not req.marker or any(extra_evals)
+
+
+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. ``'3.3'``);
+        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.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.
+        """
+        py_compat = (
+            self.python is None
+            or dist.py_version is None
+            or dist.py_version == self.python
+        )
+        return py_compat 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`
+
+        Uses case-insensitive `project_name` comparison, assuming all the
+        project's distributions use their project's name converted to all
+        lowercase as their key.
+
+        """
+        distribution_key = project_name.lower()
+        return self._distmap.get(distribution_key, [])
+
+    def add(self, dist):
+        """Add `dist` if we ``can_add()`` it and it has not already been added
+        """
+        if self.can_add(dist) and dist.has_version():
+            dists = self._distmap.setdefault(dist.key, [])
+            if dist not in dists:
+                dists.append(dist)
+                dists.sort(key=operator.attrgetter('hashcmp'), reverse=True)
+
+    def best_match(
+            self, req, working_set, installer=None, replace_conflicting=False):
+        """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.
+        """
+        try:
+            dist = working_set.find(req)
+        except VersionConflict:
+            if not replace_conflicting:
+                raise
+            dist = None
+        if dist is not None:
+            return dist
+        for dist in self[req.key]:
+            if dist in req:
+                return dist
+        # try to download/install
+        return self.obtain(req, installer)
+
+    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 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
+
+
+# XXX backward compatibility
+AvailableDistributions = Environment
+
+
+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()
+
+        tmpl = textwrap.dedent("""
+            Can't extract file(s) to egg cache
+
+            The following error occurred while trying to extract file(s)
+            to the Python egg cache:
+
+              {old_exc}
+
+            The Python egg cache directory is currently set to:
+
+              {cache_path}
+
+            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.
+            """).lstrip()
+        err = ExtractionError(tmpl.format(**locals()))
+        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 Exception:
+            self.extraction_error()
+
+        self._warn_unsafe_extraction_path(extract_path)
+
+        self.cached_files[target_path] = 1
+        return target_path
+
+    @staticmethod
+    def _warn_unsafe_extraction_path(path):
+        """
+        If the default extraction path is overridden and set to an insecure
+        location, such as /tmp, it opens up an opportunity for an attacker to
+        replace an extracted file with an unauthorized payload. Warn the user
+        if a known insecure location is used.
+
+        See Distribute #375 for more details.
+        """
+        if os.name == 'nt' and not path.startswith(os.environ['windir']):
+            # On Windows, permissions are generally restrictive by default
+            #  and temp directories are not writable by other users, so
+            #  bypass the warning.
+            return
+        mode = os.stat(path).st_mode
+        if mode & stat.S_IWOTH or mode & stat.S_IWGRP:
+            msg = (
+                "%s is writable by group/others and vulnerable to attack "
+                "when "
+                "used with get_resource_filename. Consider a more secure "
+                "location (set with .set_extraction_path or the "
+                "PYTHON_EGG_CACHE environment variable)." % path
+            )
+            warnings.warn(msg, UserWarning)
+
+    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():
+    """
+    Return the ``PYTHON_EGG_CACHE`` environment variable
+    or a platform-relevant user cache dir for an app
+    named "Python-Eggs".
+    """
+    return (
+        os.environ.get('PYTHON_EGG_CACHE')
+        or appdirs.user_cache_dir(appname='Python-Eggs')
+    )
+
+
+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
+    """
+    try:
+        # normalize the version
+        return str(packaging.version.Version(version))
+    except packaging.version.InvalidVersion:
+        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('-', '_')
+
+
+def invalid_marker(text):
+    """
+    Validate text as a PEP 508 environment marker; return an exception
+    if invalid or False otherwise.
+    """
+    try:
+        evaluate_marker(text)
+    except SyntaxError as e:
+        e.filename = None
+        e.lineno = None
+        return e
+    return False
+
+
+def evaluate_marker(text, extra=None):
+    """
+    Evaluate a PEP 508 environment marker.
+    Return a boolean indicating the marker result in this environment.
+    Raise SyntaxError if marker is invalid.
+
+    This implementation uses the 'pyparsing' module.
+    """
+    try:
+        marker = packaging.markers.Marker(text)
+        return marker.evaluate()
+    except packaging.markers.InvalidMarker as e:
+        raise SyntaxError(e)
+
+
+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 io.BytesIO(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))
+
+    def get_metadata(self, name):
+        if not self.egg_info:
+            return ""
+        value = self._get(self._fn(self.egg_info, name))
+        return value.decode('utf-8') if six.PY3 else value
+
+    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(
+                "Script {script!r} not found in metadata at {self.egg_info!r}"
+                .format(**locals()),
+            )
+        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):
+            source = open(script_filename).read()
+            code = compile(source, script_filename, 'exec')
+            exec(code, 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 _is_egg_path(path):
+                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):
+        with open(path, 'rb') as stream:
+            return stream.read()
+
+    @classmethod
+    def _register(cls):
+        loader_cls = getattr(
+            importlib_machinery,
+            'SourceFileLoader',
+            type(None),
+        )
+        register_loader_type(loader_cls, cls)
+
+
+DefaultProvider._register()
+
+
+class EmptyProvider(NullProvider):
+    """Provider that returns nothing for all requests"""
+
+    module_path = None
+
+    _isdir = _has = lambda self, path: False
+
+    def _get(self, path):
+        return ''
+
+    def _listdir(self, path):
+        return []
+
+    def __init__(self):
+        pass
+
+
+empty_provider = EmptyProvider()
+
+
+class ZipManifests(dict):
+    """
+    zip manifest builder
+    """
+
+    @classmethod
+    def build(cls, path):
+        """
+        Build a dictionary similar to the zipimport directory
+        caches, except instead of tuples, store ZipInfo objects.
+
+        Use a platform-specific path separator (os.sep) for the path keys
+        for compatibility with pypy on Windows.
+        """
+        with zipfile.ZipFile(path) as zfile:
+            items = (
+                (
+                    name.replace('/', os.sep),
+                    zfile.getinfo(name),
+                )
+                for name in zfile.namelist()
+            )
+            return dict(items)
+
+    load = build
+
+
+class MemoizedZipManifests(ZipManifests):
+    """
+    Memoized zipfile manifests.
+    """
+    manifest_mod = collections.namedtuple('manifest_mod', 'manifest mtime')
+
+    def load(self, path):
+        """
+        Load a manifest at path or return a suitable manifest already loaded.
+        """
+        path = os.path.normpath(path)
+        mtime = os.stat(path).st_mtime
+
+        if path not in self or self[path].mtime != mtime:
+            manifest = self.build(path)
+            self[path] = self.manifest_mod(manifest, mtime)
+
+        return self[path].manifest
+
+
+class ZipProvider(EggProvider):
+    """Resource support for zips and eggs"""
+
+    eagers = None
+    _zip_manifests = MemoizedZipManifests()
+
+    def __init__(self, module):
+        EggProvider.__init__(self, module)
+        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
+        fspath = fspath.rstrip(os.sep)
+        if fspath == self.loader.archive:
+            return ''
+        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.
+        # pseudo-fs path
+        fspath = self.zip_pre + zip_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)
+        )
+
+    @property
+    def zipinfo(self):
+        return self._zip_manifests.load(self.loader.archive)
+
+    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)
+
+    @staticmethod
+    def _get_date_and_size(zip_stat):
+        size = zip_stat.file_size
+        # ymdhms+wday, yday, dst
+        date_time = zip_stat.date_time + (0, 0, -1)
+        # 1980 offset already done
+        timestamp = time.mktime(date_time)
+        return timestamp, size
+
+    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 the extracted directory name
+            return os.path.dirname(last)
+
+        timestamp, size = self._get_date_and_size(self.zipinfo[zip_path])
+
+        if not WRITE_SUPPORT:
+            raise IOError('"os.rename" and "os.unlink" are not supported '
+                          'on this platform')
+        try:
+
+            real_path = manager.get_cache_path(
+                self.egg_name, self._parts(zip_path)
+            )
+
+            if self._is_current(real_path, zip_path):
+                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):
+                    if self._is_current(real_path, zip_path):
+                        # the file became current since it was checked above,
+                        #  so proceed.
+                        return real_path
+                    # Windows, del old file and retry
+                    elif os.name == 'nt':
+                        unlink(real_path)
+                        rename(tmpnam, real_path)
+                        return real_path
+                raise
+
+        except os.error:
+            # report a user-friendly error
+            manager.extraction_error()
+
+        return real_path
+
+    def _is_current(self, file_path, zip_path):
+        """
+        Return True if the file_path is current for this zip_path
+        """
+        timestamp, size = self._get_date_and_size(self.zipinfo[zip_path])
+        if not os.path.isfile(file_path):
+            return False
+        stat = os.stat(file_path)
+        if stat.st_size != size or stat.st_mtime != timestamp:
+            return False
+        # check that the contents match
+        zip_contents = self.loader.get_data(zip_path)
+        with open(file_path, 'rb') as f:
+            file_contents = f.read()
+        return zip_contents == file_contents
+
+    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' and os.path.isfile(self.path)
+
+    def get_metadata(self, name):
+        if name != 'PKG-INFO':
+            raise KeyError("No metadata except PKG-INFO is available")
+
+        with io.open(self.path, encoding='utf-8', errors="replace") as f:
+            metadata = f.read()
+        self._warn_on_replacement(metadata)
+        return metadata
+
+    def _warn_on_replacement(self, metadata):
+        # Python 2.7 compat for: replacement_char = '�'
+        replacement_char = b'\xef\xbf\xbd'.decode('utf-8')
+        if replacement_char in metadata:
+            tmpl = "{self.path} could not be properly decoded in UTF-8"
+            msg = tmpl.format(**locals())
+            warnings.warn(msg)
+
+    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.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()
+
+
+_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_eggs_in_zip(importer, path_item, only=False):
+    """
+    Find eggs in zip files; possibly multiple nested eggs.
+    """
+    if importer.archive.endswith('.whl'):
+        # wheels are not supported with this finder
+        # they don't have PKG-INFO metadata, and won't ever contain eggs
+        return
+    metadata = EggMetadata(importer)
+    if metadata.has_metadata('PKG-INFO'):
+        yield Distribution.from_filename(path_item, metadata=metadata)
+    if only:
+        # don't yield nested distros
+        return
+    for subitem in metadata.resource_listdir('/'):
+        if _is_egg_path(subitem):
+            subpath = os.path.join(path_item, subitem)
+            dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath)
+            for dist in dists:
+                yield dist
+        elif subitem.lower().endswith('.dist-info'):
+            subpath = os.path.join(path_item, subitem)
+            submeta = EggMetadata(zipimport.zipimporter(subpath))
+            submeta.egg_info = subpath
+            yield Distribution.from_location(path_item, subitem, submeta)
+
+
+register_finder(zipimport.zipimporter, find_eggs_in_zip)
+
+
+def find_nothing(importer, path_item, only=False):
+    return ()
+
+
+register_finder(object, find_nothing)
+
+
+def _by_version_descending(names):
+    """
+    Given a list of filenames, return them in descending order
+    by version number.
+
+    >>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg'
+    >>> _by_version_descending(names)
+    ['Python-2.7.10.egg', 'Python-2.7.2.egg', 'foo', 'bar']
+    >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg'
+    >>> _by_version_descending(names)
+    ['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg']
+    >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.post1.egg'
+    >>> _by_version_descending(names)
+    ['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg']
+    """
+    def _by_version(name):
+        """
+        Parse each component of the filename
+        """
+        name, ext = os.path.splitext(name)
+        parts = itertools.chain(name.split('-'), [ext])
+        return [packaging.version.parse(part) for part in parts]
+
+    return sorted(names, key=_by_version, reverse=True)
+
+
+def find_on_path(importer, path_item, only=False):
+    """Yield distributions accessible on a sys.path directory"""
+    path_item = _normalize_cached(path_item)
+
+    if _is_unpacked_egg(path_item):
+        yield Distribution.from_filename(
+            path_item, metadata=PathMetadata(
+                path_item, os.path.join(path_item, 'EGG-INFO')
+            )
+        )
+        return
+
+    entries = safe_listdir(path_item)
+
+    # for performance, before sorting by version,
+    # screen entries for only those that will yield
+    # distributions
+    filtered = (
+        entry
+        for entry in entries
+        if dist_factory(path_item, entry, only)
+    )
+
+    # scan for .egg and .egg-info in directory
+    path_item_entries = _by_version_descending(filtered)
+    for entry in path_item_entries:
+        fullpath = os.path.join(path_item, entry)
+        factory = dist_factory(path_item, entry, only)
+        for dist in factory(fullpath):
+            yield dist
+
+
+def dist_factory(path_item, entry, only):
+    """
+    Return a dist_factory for a path_item and entry
+    """
+    lower = entry.lower()
+    is_meta = any(map(lower.endswith, ('.egg-info', '.dist-info')))
+    return (
+        distributions_from_metadata
+        if is_meta else
+        find_distributions
+        if not only and _is_egg_path(entry) else
+        resolve_egg_link
+        if not only and lower.endswith('.egg-link') else
+        NoDists()
+    )
+
+
+class NoDists:
+    """
+    >>> bool(NoDists())
+    False
+
+    >>> list(NoDists()('anything'))
+    []
+    """
+    def __bool__(self):
+        return False
+    if six.PY2:
+        __nonzero__ = __bool__
+
+    def __call__(self, fullpath):
+        return iter(())
+
+
+def safe_listdir(path):
+    """
+    Attempt to list contents of path, but suppress some exceptions.
+    """
+    try:
+        return os.listdir(path)
+    except (PermissionError, NotADirectoryError):
+        pass
+    except OSError as e:
+        # Ignore the directory if does not exist, not a directory or
+        # permission denied
+        ignorable = (
+            e.errno in (errno.ENOTDIR, errno.EACCES, errno.ENOENT)
+            # Python 2 on Windows needs to be handled this way :(
+            or getattr(e, "winerror", None) == 267
+        )
+        if not ignorable:
+            raise
+    return ()
+
+
+def distributions_from_metadata(path):
+    root = os.path.dirname(path)
+    if os.path.isdir(path):
+        if len(os.listdir(path)) == 0:
+            # empty metadata dir; skip
+            return
+        metadata = PathMetadata(root, path)
+    else:
+        metadata = FileMetadata(path)
+    entry = os.path.basename(path)
+    yield Distribution.from_location(
+        root, entry, metadata, precedence=DEVELOP_DIST,
+    )
+
+
+def non_empty_lines(path):
+    """
+    Yield non-empty lines from file at path
+    """
+    with open(path) as f:
+        for line in f:
+            line = line.strip()
+            if line:
+                yield line
+
+
+def resolve_egg_link(path):
+    """
+    Given a path to an .egg-link, resolve distributions
+    present in the referenced path.
+    """
+    referenced_paths = non_empty_lines(path)
+    resolved_paths = (
+        os.path.join(os.path.dirname(path), ref)
+        for ref in referenced_paths
+    )
+    dist_groups = map(find_distributions, resolved_paths)
+    return next(dist_groups, ())
+
+
+register_finder(pkgutil.ImpImporter, find_on_path)
+
+if hasattr(importlib_machinery, 'FileFinder'):
+    register_finder(importlib_machinery.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)
+        _rebuild_mod_path(path, packageName, module)
+    return subpath
+
+
+def _rebuild_mod_path(orig_path, package_name, module):
+    """
+    Rebuild module.__path__ ensuring that all entries are ordered
+    corresponding to their sys.path order
+    """
+    sys_path = [_normalize_cached(p) for p in sys.path]
+
+    def safe_sys_path_index(entry):
+        """
+        Workaround for #520 and #513.
+        """
+        try:
+            return sys_path.index(entry)
+        except ValueError:
+            return float('inf')
+
+    def position_in_sys_path(path):
+        """
+        Return the ordinal of the path based on its position in sys.path
+        """
+        path_parts = path.split(os.sep)
+        module_parts = package_name.count('.') + 1
+        parts = path_parts[:-module_parts]
+        return safe_sys_path_index(_normalize_cached(os.sep.join(parts)))
+
+    if not isinstance(orig_path, list):
+        # Is this behavior useful when module.__path__ is not a list?
+        return
+
+    orig_path.sort(key=position_in_sys_path)
+    module.__path__[:] = [_normalize_cached(p) for p in orig_path]
+
+
+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(pkgutil.ImpImporter, file_ns_handler)
+register_namespace_handler(zipimport.zipimporter, file_ns_handler)
+
+if hasattr(importlib_machinery, 'FileFinder'):
+    register_namespace_handler(importlib_machinery.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 _is_egg_path(path):
+    """
+    Determine if given path appears to be an egg.
+    """
+    return path.lower().endswith('.egg')
+
+
+def _is_unpacked_egg(path):
+    """
+    Determine if given path appears to be an unpacked egg.
+    """
+    return (
+        _is_egg_path(path) and
+        os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO'))
+    )
+
+
+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 string or sequence"""
+    if isinstance(strs, six.string_types):
+        for s in strs.splitlines():
+            s = s.strip()
+            # skip blank lines/comments
+            if s and not s.startswith('#'):
+                yield s
+    else:
+        for ss in strs:
+            for s in yield_lines(ss):
+                yield s
+
+
+MODULE = re.compile(r"\w+(\.\w+)*$").match
+EGG_NAME = re.compile(
+    r"""
+    (?P<name>[^-]+) (
+        -(?P<ver>[^-]+) (
+            -py(?P<pyver>[^-]+) (
+                -(?P<plat>.+)
+            )?
+        )?
+    )?
+    """,
+    re.VERBOSE | re.IGNORECASE,
+).match
+
+
+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 = tuple(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, *args, **kwargs):
+        """
+        Require packages for this EntryPoint, then resolve it.
+        """
+        if not require or args or kwargs:
+            warnings.warn(
+                "Parameters to load are deprecated.  Call .resolve and "
+                ".require separately.",
+                DeprecationWarning,
+                stacklevel=2,
+            )
+        if require:
+            self.require(*args, **kwargs)
+        return self.resolve()
+
+    def resolve(self):
+        """
+        Resolve the entry point from its module and attrs.
+        """
+        module = __import__(self.module_name, fromlist=['__name__'], level=0)
+        try:
+            return functools.reduce(getattr, self.attrs, module)
+        except AttributeError as exc:
+            raise ImportError(str(exc))
+
+    def require(self, env=None, installer=None):
+        if self.extras and not self.dist:
+            raise UnknownExtra("Can't require() without a distribution", self)
+
+        # Get the requirements for this entry point with all its extras and
+        # then resolve them. We have to pass `extras` along when resolving so
+        # that the working set knows what extras we want. Otherwise, for
+        # dist-info distributions, the working set will assume that the
+        # requirements for that extra are purely optional and skip over them.
+        reqs = self.dist.requires(self.extras)
+        items = working_set.resolve(reqs, env, installer, extras=self.extras)
+        list(map(working_set.add, items))
+
+    pattern = re.compile(
+        r'\s*'
+        r'(?P<name>.+?)\s*'
+        r'=\s*'
+        r'(?P<module>[\w.]+)\s*'
+        r'(:\s*(?P<attr>[\w.]+))?\s*'
+        r'(?P<extras>\[.*\])?\s*$'
+    )
+
+    @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
+        """
+        m = cls.pattern.match(src)
+        if not m:
+            msg = "EntryPoint must be in 'name=module:attrs [extras]' format"
+            raise ValueError(msg, src)
+        res = m.groupdict()
+        extras = cls._parse_extras(res['extras'])
+        attrs = res['attr'].split('.') if res['attr'] else ()
+        return cls(res['name'], res['module'], attrs, extras, dist)
+
+    @classmethod
+    def _parse_extras(cls, extras_spec):
+        if not extras_spec:
+            return ()
+        req = Requirement.parse('x' + extras_spec)
+        if req.specs:
+            raise ValueError()
+        return req.extras
+
+    @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
+
+    @classmethod
+    def parse_map(cls, data, dist=None):
+        """Parse a map of entry point groups"""
+        if isinstance(data, dict):
+            data = 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
+
+
+def _remove_md5_fragment(location):
+    if not location:
+        return ''
+    parsed = urllib.parse.urlparse(location)
+    if parsed[-1].startswith('md5='):
+        return urllib.parse.urlunparse(parsed[:-1] + ('',))
+    return location
+
+
+def _version_from_file(lines):
+    """
+    Given an iterable of lines from a Metadata file, return
+    the value of the Version field, if present, or None otherwise.
+    """
+    def is_version_line(line):
+        return line.lower().startswith('version:')
+    version_lines = filter(is_version_line, lines)
+    line = next(iter(version_lines), '')
+    _, _, value = line.partition(':')
+    return safe_version(value.strip()) or None
+
+
+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:
+            cls = _distributionImpl[ext.lower()]
+
+            match = EGG_NAME(basename)
+            if match:
+                project_name, version, py_version, platform = match.group(
+                    'name', 'ver', 'pyver', 'plat'
+                )
+        return cls(
+            location, metadata, project_name=project_name, version=version,
+            py_version=py_version, platform=platform, **kw
+        )._reload_version()
+
+    def _reload_version(self):
+        return self
+
+    @property
+    def hashcmp(self):
+        return (
+            self.parsed_version,
+            self.precedence,
+            self.key,
+            _remove_md5_fragment(self.location),
+            self.py_version or '',
+            self.platform or '',
+        )
+
+    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
+
+    @property
+    def parsed_version(self):
+        if not hasattr(self, "_parsed_version"):
+            self._parsed_version = parse_version(self.version)
+
+        return self._parsed_version
+
+    def _warn_legacy_version(self):
+        LV = packaging.version.LegacyVersion
+        is_legacy = isinstance(self._parsed_version, LV)
+        if not is_legacy:
+            return
+
+        # While an empty version is technically a legacy version and
+        # is not a valid PEP 440 version, it's also unlikely to
+        # actually come from someone and instead it is more likely that
+        # it comes from setuptools attempting to parse a filename and
+        # including it in the list. So for that we'll gate this warning
+        # on if the version is anything at all or not.
+        if not self.version:
+            return
+
+        tmpl = textwrap.dedent("""
+            '{project_name} ({version})' is being parsed as a legacy,
+            non PEP 440,
+            version. You may find odd behavior and sort order.
+            In particular it will be sorted as less than 0.0. It
+            is recommended to migrate to PEP 440 compatible
+            versions.
+            """).strip().replace('\n', ' ')
+
+        warnings.warn(tmpl.format(**vars(self)), PEP440Warning)
+
+    @property
+    def version(self):
+        try:
+            return self._version
+        except AttributeError:
+            version = _version_from_file(self._get_metadata(self.PKG_INFO))
+            if version is None:
+                tmpl = "Missing 'Version:' header and/or %s file"
+                raise ValueError(tmpl % self.PKG_INFO, self)
+            return version
+
+    @property
+    def _dep_map(self):
+        """
+        A map of extra to its list of (direct) requirements
+        for this distribution, including the null extra.
+        """
+        try:
+            return self.__dep_map
+        except AttributeError:
+            self.__dep_map = self._filter_extras(self._build_dep_map())
+        return self.__dep_map
+
+    @staticmethod
+    def _filter_extras(dm):
+        """
+        Given a mapping of extras to dependencies, strip off
+        environment markers and filter out any dependencies
+        not matching the markers.
+        """
+        for extra in list(filter(None, dm)):
+            new_extra = extra
+            reqs = dm.pop(extra)
+            new_extra, _, marker = extra.partition(':')
+            fails_marker = marker and (
+                invalid_marker(marker)
+                or not evaluate_marker(marker)
+            )
+            if fails_marker:
+                reqs = []
+            new_extra = safe_extra(new_extra) or None
+
+            dm.setdefault(new_extra, []).extend(reqs)
+        return dm
+
+    def _build_dep_map(self):
+        dm = {}
+        for name in 'requires.txt', 'depends.txt':
+            for extra, reqs in split_sections(self._get_metadata(name)):
+                dm.setdefault(extra, []).extend(parse_requirements(reqs))
+        return dm
+
+    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, replace=False):
+        """Ensure distribution is importable on `path` (default=sys.path)"""
+        if path is None:
+            path = sys.path
+        self.insert_on(path, replace=replace)
+        if path is sys.path:
+            fixup_namespace_packages(self.location)
+            for pkg in self._get_metadata('namespace_packages.txt'):
+                if pkg in sys.modules:
+                    declare_namespace(pkg)
+
+    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
+        )
+
+    def as_requirement(self):
+        """Return a ``Requirement`` that matches this distribution exactly"""
+        if isinstance(self.parsed_version, packaging.version.Version):
+            spec = "%s==%s" % (self.project_name, self.parsed_version)
+        else:
+            spec = "%s===%s" % (self.project_name, self.parsed_version)
+
+        return Requirement.parse(spec)
+
+    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, replace=False):
+        """Ensure self.location is on path
+
+        If replace=False (default):
+            - If location is already in path anywhere, do nothing.
+            - Else:
+              - If it's an egg and its parent directory is on path,
+                insert just ahead of the parent.
+              - Else: add to the end of path.
+        If replace=True:
+            - If location is already on path anywhere (not eggs)
+              or higher priority than its parent (eggs)
+              do nothing.
+            - Else:
+              - If it's an egg and its parent directory is on path,
+                insert just ahead of the parent,
+                removing any lower-priority entries.
+              - Else: add it to the front of path.
+        """
+
+        loc = loc or self.location
+        if not loc:
+            return
+
+        nloc = _normalize_cached(loc)
+        bdir = os.path.dirname(nloc)
+        npath = [(p and _normalize_cached(p) or p) for p in path]
+
+        for p, item in enumerate(npath):
+            if item == nloc:
+                if replace:
+                    break
+                else:
+                    # don't modify path (even removing duplicates) if
+                    # found and not replace
+                    return
+            elif item == bdir and self.precedence == EGG_DIST:
+                # if it's an .egg, give it precedence over its directory
+                # UNLESS it's already been added to sys.path and replace=False
+                if (not replace) and nloc in npath[p:]:
+                    return
+                if path is sys.path:
+                    self.check_version_conflict()
+                path.insert(p, loc)
+                npath.insert(p, nloc)
+                break
+        else:
+            if path is sys.path:
+                self.check_version_conflict()
+            if replace:
+                path.insert(0, loc)
+            else:
+                path.append(loc)
+            return
+
+        # p is the spot where we found or inserted loc; now remove duplicates
+        while True:
+            try:
+                np = npath.index(nloc, p + 1)
+            except ValueError:
+                break
+            else:
+                del npath[np], path[np]
+                # ha!
+                p = np
+
+        return
+
+    def check_version_conflict(self):
+        if self.key == 'setuptools':
+            # ignore the inevitable setuptools self-conflicts  :(
+            return
+
+        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"""
+        names = 'project_name version py_version platform location precedence'
+        for attr in names.split():
+            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]
+
+
+class EggInfoDistribution(Distribution):
+    def _reload_version(self):
+        """
+        Packages installed by distutils (e.g. numpy or scipy),
+        which uses an old safe_version, and so
+        their version numbers can get mangled when
+        converted to filenames (e.g., 1.11.0.dev0+2329eae to
+        1.11.0.dev0_2329eae). These distributions will not be
+        parsed properly
+        downstream by Distribution and safe_version, so
+        take an extra step and try to get the version number from
+        the metadata file itself instead of the filename.
+        """
+        md_version = _version_from_file(self._get_metadata(self.PKG_INFO))
+        if md_version:
+            self._version = md_version
+        return self
+
+
+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:
+            metadata = self.get_metadata(self.PKG_INFO)
+            self._pkg_info = email.parser.Parser().parsestr(metadata)
+            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 _compute_dependencies(self):
+        """Recompute this distribution's dependencies."""
+        dm = self.__dep_map = {None: []}
+
+        reqs = []
+        # Including any condition expressions
+        for req in self._parsed_pkg_info.get_all('Requires-Dist') or []:
+            reqs.extend(parse_requirements(req))
+
+        def reqs_for_extra(extra):
+            for req in reqs:
+                if not req.marker or req.marker.evaluate({'extra': extra}):
+                    yield req
+
+        common = frozenset(reqs_for_extra(None))
+        dm[None].extend(common)
+
+        for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []:
+            s_extra = safe_extra(extra.strip())
+            dm[s_extra] = list(frozenset(reqs_for_extra(extra)) - common)
+
+        return dm
+
+
+_distributionImpl = {
+    '.egg': Distribution,
+    '.egg-info': EggInfoDistribution,
+    '.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
+    warnings.warn(stacklevel=level + 1, *args, **kw)
+
+
+class RequirementParseError(ValueError):
+    def __str__(self):
+        return ' '.join(self.args)
+
+
+def parse_requirements(strs):
+    """Yield ``Requirement`` objects for each specification in `strs`
+
+    `strs` must be a string, or a (possibly-nested) iterable thereof.
+    """
+    # create a steppable iterator, so we can handle \-continuations
+    lines = iter(yield_lines(strs))
+
+    for line in lines:
+        # Drop comments -- a hash without a space may be in a URL.
+        if ' #' in line:
+            line = line[:line.find(' #')]
+        # If there is a line continuation, drop it, and append the next line.
+        if line.endswith('\\'):
+            line = line[:-2].strip()
+            try:
+                line += next(lines)
+            except StopIteration:
+                return
+        yield Requirement(line)
+
+
+class Requirement(packaging.requirements.Requirement):
+    def __init__(self, requirement_string):
+        """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!"""
+        try:
+            super(Requirement, self).__init__(requirement_string)
+        except packaging.requirements.InvalidRequirement as e:
+            raise RequirementParseError(str(e))
+        self.unsafe_name = self.name
+        project_name = safe_name(self.name)
+        self.project_name, self.key = project_name, project_name.lower()
+        self.specs = [
+            (spec.operator, spec.version) for spec in self.specifier]
+        self.extras = tuple(map(safe_extra, self.extras))
+        self.hashCmp = (
+            self.key,
+            self.specifier,
+            frozenset(self.extras),
+            str(self.marker) if self.marker else None,
+        )
+        self.__hash = hash(self.hashCmp)
+
+    def __eq__(self, other):
+        return (
+            isinstance(other, Requirement) and
+            self.hashCmp == other.hashCmp
+        )
+
+    def __ne__(self, other):
+        return not self == other
+
+    def __contains__(self, item):
+        if isinstance(item, Distribution):
+            if item.key != self.key:
+                return False
+
+            item = item.version
+
+        # Allow prereleases always in order to match the previous behavior of
+        # this method. In the future this should be smarter and follow PEP 440
+        # more accurately.
+        return self.specifier.contains(item, prereleases=True)
+
+    def __hash__(self):
+        return self.__hash
+
+    def __repr__(self):
+        return "Requirement.parse(%r)" % str(self)
+
+    @staticmethod
+    def parse(s):
+        req, = parse_requirements(s)
+        return req
+
+
+def _always_object(classes):
+    """
+    Ensure object appears in the mro even
+    for old-style classes.
+    """
+    if object not in classes:
+        return classes + (object,)
+    return classes
+
+
+def _find_adapter(registry, ob):
+    """Return an adapter factory for `ob` from `registry`"""
+    types = _always_object(inspect.getmro(getattr(ob, '__class__', type(ob))))
+    for t in types:
+        if t in registry:
+            return registry[t]
+
+
+def ensure_directory(path):
+    """Ensure that the parent directory of `path` exists"""
+    dirname = os.path.dirname(path)
+    py31compat.makedirs(dirname, exist_ok=True)
+
+
+def _bypass_ensure_directory(path):
+    """Sandbox-bypassing version of ensure_directory()"""
+    if not WRITE_SUPPORT:
+        raise IOError('"os.mkdir" not supported on this platform.')
+    dirname, filename = split(path)
+    if dirname and filename and not isdir(dirname):
+        _bypass_ensure_directory(dirname)
+        mkdir(dirname, 0o755)
+
+
+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):
+    old_open = os.open
+    try:
+        # temporarily bypass sandboxing
+        os.open = os_open
+        return tempfile.mkstemp(*args, **kw)
+    finally:
+        # and then put it back
+        os.open = old_open
+
+
+# Silence the PEP440Warning by default, so that end users don't get hit by it
+# randomly just because they use pkg_resources. We want to append the rule
+# because we want earlier uses of filterwarnings to take precedence over this
+# one.
+warnings.filterwarnings("ignore", category=PEP440Warning, append=True)
+
+
+# from jaraco.functools 1.3
+def _call_aside(f, *args, **kwargs):
+    f(*args, **kwargs)
+    return f
+
+
+@_call_aside
+def _initialize(g=globals()):
+    "Set up global resource manager (deliberately not state-saved)"
+    manager = ResourceManager()
+    g['_manager'] = manager
+    g.update(
+        (name, getattr(manager, name))
+        for name in dir(manager)
+        if not name.startswith('_')
+    )
+
+
+@_call_aside
+def _initialize_master_working_set():
+    """
+    Prepare the master working set and make the ``require()``
+    API available.
+
+    This function has explicit effects on the global state
+    of pkg_resources. It is intended to be invoked once at
+    the initialization of this module.
+
+    Invocation by other packages is unsupported and done
+    at their own risk.
+    """
+    working_set = WorkingSet._build_master()
+    _declare_state('object', working_set=working_set)
+
+    require = working_set.require
+    iter_entry_points = working_set.iter_entry_points
+    add_activation_listener = working_set.subscribe
+    run_script = working_set.run_script
+    # backward compatibility
+    run_main = run_script
+    # Activate all distributions already on sys.path with replace=False and
+    # ensure that all distributions added to the working set in the future
+    # (e.g. by calling ``require()``) will get activated as well,
+    # with higher priority (replace=True).
+    tuple(
+        dist.activate(replace=False)
+        for dist in working_set
+    )
+    add_activation_listener(
+        lambda dist: dist.activate(replace=True),
+        existing=False,
+    )
+    working_set.entries = []
+    # match order
+    list(map(working_set.add_entry, sys.path))
+    globals().update(locals())
diff --git a/vendor/setuptools-39.0.1/pkg_resources/_vendor/__init__.py b/vendor/setuptools-39.0.1/pkg_resources/_vendor/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/vendor/setuptools-39.0.1/pkg_resources/_vendor/appdirs.py b/vendor/setuptools-39.0.1/pkg_resources/_vendor/appdirs.py
new file mode 100644
index 00000000..f4dba095
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/_vendor/appdirs.py
@@ -0,0 +1,552 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (c) 2005-2010 ActiveState Software Inc.
+# Copyright (c) 2013 Eddy Petrișor
+
+"""Utilities for determining application-specific dirs.
+
+See <http://github.com/ActiveState/appdirs> for details and usage.
+"""
+# Dev Notes:
+# - MSDN on where to store app data files:
+#   http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120
+# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html
+# - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+
+__version_info__ = (1, 4, 0)
+__version__ = '.'.join(map(str, __version_info__))
+
+
+import sys
+import os
+
+PY3 = sys.version_info[0] == 3
+
+if PY3:
+    unicode = str
+
+if sys.platform.startswith('java'):
+    import platform
+    os_name = platform.java_ver()[3][0]
+    if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc.
+        system = 'win32'
+    elif os_name.startswith('Mac'): # "Mac OS X", etc.
+        system = 'darwin'
+    else: # "Linux", "SunOS", "FreeBSD", etc.
+        # Setting this to "linux2" is not ideal, but only Windows or Mac
+        # are actually checked for and the rest of the module expects
+        # *sys.platform* style strings.
+        system = 'linux2'
+else:
+    system = sys.platform
+
+
+
+def user_data_dir(appname=None, appauthor=None, version=None, roaming=False):
+    r"""Return full path to the user-specific data dir for this application.
+
+        "appname" is the name of application.
+            If None, just the system directory is returned.
+        "appauthor" (only used on Windows) is the name of the
+            appauthor or distributing body for this application. Typically
+            it is the owning company name. This falls back to appname. You may
+            pass False to disable it.
+        "version" is an optional version path element to append to the
+            path. You might want to use this if you want multiple versions
+            of your app to be able to run independently. If used, this
+            would typically be "<major>.<minor>".
+            Only applied when appname is present.
+        "roaming" (boolean, default False) can be set True to use the Windows
+            roaming appdata directory. That means that for users on a Windows
+            network setup for roaming profiles, this user data will be
+            sync'd on login. See
+            <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>
+            for a discussion of issues.
+
+    Typical user data directories are:
+        Mac OS X:               ~/Library/Application Support/<AppName>
+        Unix:                   ~/.local/share/<AppName>    # or in $XDG_DATA_HOME, if defined
+        Win XP (not roaming):   C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName>
+        Win XP (roaming):       C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>
+        Win 7  (not roaming):   C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>
+        Win 7  (roaming):       C:\Users\<username>\AppData\Roaming\<AppAuthor>\<AppName>
+
+    For Unix, we follow the XDG spec and support $XDG_DATA_HOME.
+    That means, by default "~/.local/share/<AppName>".
+    """
+    if system == "win32":
+        if appauthor is None:
+            appauthor = appname
+        const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA"
+        path = os.path.normpath(_get_win_folder(const))
+        if appname:
+            if appauthor is not False:
+                path = os.path.join(path, appauthor, appname)
+            else:
+                path = os.path.join(path, appname)
+    elif system == 'darwin':
+        path = os.path.expanduser('~/Library/Application Support/')
+        if appname:
+            path = os.path.join(path, appname)
+    else:
+        path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share"))
+        if appname:
+            path = os.path.join(path, appname)
+    if appname and version:
+        path = os.path.join(path, version)
+    return path
+
+
+def site_data_dir(appname=None, appauthor=None, version=None, multipath=False):
+    """Return full path to the user-shared data dir for this application.
+
+        "appname" is the name of application.
+            If None, just the system directory is returned.
+        "appauthor" (only used on Windows) is the name of the
+            appauthor or distributing body for this application. Typically
+            it is the owning company name. This falls back to appname. You may
+            pass False to disable it.
+        "version" is an optional version path element to append to the
+            path. You might want to use this if you want multiple versions
+            of your app to be able to run independently. If used, this
+            would typically be "<major>.<minor>".
+            Only applied when appname is present.
+        "multipath" is an optional parameter only applicable to *nix
+            which indicates that the entire list of data dirs should be
+            returned. By default, the first item from XDG_DATA_DIRS is
+            returned, or '/usr/local/share/<AppName>',
+            if XDG_DATA_DIRS is not set
+
+    Typical user data directories are:
+        Mac OS X:   /Library/Application Support/<AppName>
+        Unix:       /usr/local/share/<AppName> or /usr/share/<AppName>
+        Win XP:     C:\Documents and Settings\All Users\Application Data\<AppAuthor>\<AppName>
+        Vista:      (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.)
+        Win 7:      C:\ProgramData\<AppAuthor>\<AppName>   # Hidden, but writeable on Win 7.
+
+    For Unix, this is using the $XDG_DATA_DIRS[0] default.
+
+    WARNING: Do not use this on Windows. See the Vista-Fail note above for why.
+    """
+    if system == "win32":
+        if appauthor is None:
+            appauthor = appname
+        path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA"))
+        if appname:
+            if appauthor is not False:
+                path = os.path.join(path, appauthor, appname)
+            else:
+                path = os.path.join(path, appname)
+    elif system == 'darwin':
+        path = os.path.expanduser('/Library/Application Support')
+        if appname:
+            path = os.path.join(path, appname)
+    else:
+        # XDG default for $XDG_DATA_DIRS
+        # only first, if multipath is False
+        path = os.getenv('XDG_DATA_DIRS',
+                         os.pathsep.join(['/usr/local/share', '/usr/share']))
+        pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)]
+        if appname:
+            if version:
+                appname = os.path.join(appname, version)
+            pathlist = [os.sep.join([x, appname]) for x in pathlist]
+
+        if multipath:
+            path = os.pathsep.join(pathlist)
+        else:
+            path = pathlist[0]
+        return path
+
+    if appname and version:
+        path = os.path.join(path, version)
+    return path
+
+
+def user_config_dir(appname=None, appauthor=None, version=None, roaming=False):
+    r"""Return full path to the user-specific config dir for this application.
+
+        "appname" is the name of application.
+            If None, just the system directory is returned.
+        "appauthor" (only used on Windows) is the name of the
+            appauthor or distributing body for this application. Typically
+            it is the owning company name. This falls back to appname. You may
+            pass False to disable it.
+        "version" is an optional version path element to append to the
+            path. You might want to use this if you want multiple versions
+            of your app to be able to run independently. If used, this
+            would typically be "<major>.<minor>".
+            Only applied when appname is present.
+        "roaming" (boolean, default False) can be set True to use the Windows
+            roaming appdata directory. That means that for users on a Windows
+            network setup for roaming profiles, this user data will be
+            sync'd on login. See
+            <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>
+            for a discussion of issues.
+
+    Typical user data directories are:
+        Mac OS X:               same as user_data_dir
+        Unix:                   ~/.config/<AppName>     # or in $XDG_CONFIG_HOME, if defined
+        Win *:                  same as user_data_dir
+
+    For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME.
+    That means, by deafult "~/.config/<AppName>".
+    """
+    if system in ["win32", "darwin"]:
+        path = user_data_dir(appname, appauthor, None, roaming)
+    else:
+        path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config"))
+        if appname:
+            path = os.path.join(path, appname)
+    if appname and version:
+        path = os.path.join(path, version)
+    return path
+
+
+def site_config_dir(appname=None, appauthor=None, version=None, multipath=False):
+    """Return full path to the user-shared data dir for this application.
+
+        "appname" is the name of application.
+            If None, just the system directory is returned.
+        "appauthor" (only used on Windows) is the name of the
+            appauthor or distributing body for this application. Typically
+            it is the owning company name. This falls back to appname. You may
+            pass False to disable it.
+        "version" is an optional version path element to append to the
+            path. You might want to use this if you want multiple versions
+            of your app to be able to run independently. If used, this
+            would typically be "<major>.<minor>".
+            Only applied when appname is present.
+        "multipath" is an optional parameter only applicable to *nix
+            which indicates that the entire list of config dirs should be
+            returned. By default, the first item from XDG_CONFIG_DIRS is
+            returned, or '/etc/xdg/<AppName>', if XDG_CONFIG_DIRS is not set
+
+    Typical user data directories are:
+        Mac OS X:   same as site_data_dir
+        Unix:       /etc/xdg/<AppName> or $XDG_CONFIG_DIRS[i]/<AppName> for each value in
+                    $XDG_CONFIG_DIRS
+        Win *:      same as site_data_dir
+        Vista:      (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.)
+
+    For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False
+
+    WARNING: Do not use this on Windows. See the Vista-Fail note above for why.
+    """
+    if system in ["win32", "darwin"]:
+        path = site_data_dir(appname, appauthor)
+        if appname and version:
+            path = os.path.join(path, version)
+    else:
+        # XDG default for $XDG_CONFIG_DIRS
+        # only first, if multipath is False
+        path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg')
+        pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)]
+        if appname:
+            if version:
+                appname = os.path.join(appname, version)
+            pathlist = [os.sep.join([x, appname]) for x in pathlist]
+
+        if multipath:
+            path = os.pathsep.join(pathlist)
+        else:
+            path = pathlist[0]
+    return path
+
+
+def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True):
+    r"""Return full path to the user-specific cache dir for this application.
+
+        "appname" is the name of application.
+            If None, just the system directory is returned.
+        "appauthor" (only used on Windows) is the name of the
+            appauthor or distributing body for this application. Typically
+            it is the owning company name. This falls back to appname. You may
+            pass False to disable it.
+        "version" is an optional version path element to append to the
+            path. You might want to use this if you want multiple versions
+            of your app to be able to run independently. If used, this
+            would typically be "<major>.<minor>".
+            Only applied when appname is present.
+        "opinion" (boolean) can be False to disable the appending of
+            "Cache" to the base app data dir for Windows. See
+            discussion below.
+
+    Typical user cache directories are:
+        Mac OS X:   ~/Library/Caches/<AppName>
+        Unix:       ~/.cache/<AppName> (XDG default)
+        Win XP:     C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Cache
+        Vista:      C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Cache
+
+    On Windows the only suggestion in the MSDN docs is that local settings go in
+    the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming
+    app data dir (the default returned by `user_data_dir` above). Apps typically
+    put cache data somewhere *under* the given dir here. Some examples:
+        ...\Mozilla\Firefox\Profiles\<ProfileName>\Cache
+        ...\Acme\SuperApp\Cache\1.0
+    OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value.
+    This can be disabled with the `opinion=False` option.
+    """
+    if system == "win32":
+        if appauthor is None:
+            appauthor = appname
+        path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA"))
+        if appname:
+            if appauthor is not False:
+                path = os.path.join(path, appauthor, appname)
+            else:
+                path = os.path.join(path, appname)
+            if opinion:
+                path = os.path.join(path, "Cache")
+    elif system == 'darwin':
+        path = os.path.expanduser('~/Library/Caches')
+        if appname:
+            path = os.path.join(path, appname)
+    else:
+        path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache'))
+        if appname:
+            path = os.path.join(path, appname)
+    if appname and version:
+        path = os.path.join(path, version)
+    return path
+
+
+def user_log_dir(appname=None, appauthor=None, version=None, opinion=True):
+    r"""Return full path to the user-specific log dir for this application.
+
+        "appname" is the name of application.
+            If None, just the system directory is returned.
+        "appauthor" (only used on Windows) is the name of the
+            appauthor or distributing body for this application. Typically
+            it is the owning company name. This falls back to appname. You may
+            pass False to disable it.
+        "version" is an optional version path element to append to the
+            path. You might want to use this if you want multiple versions
+            of your app to be able to run independently. If used, this
+            would typically be "<major>.<minor>".
+            Only applied when appname is present.
+        "opinion" (boolean) can be False to disable the appending of
+            "Logs" to the base app data dir for Windows, and "log" to the
+            base cache dir for Unix. See discussion below.
+
+    Typical user cache directories are:
+        Mac OS X:   ~/Library/Logs/<AppName>
+        Unix:       ~/.cache/<AppName>/log  # or under $XDG_CACHE_HOME if defined
+        Win XP:     C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Logs
+        Vista:      C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Logs
+
+    On Windows the only suggestion in the MSDN docs is that local settings
+    go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in
+    examples of what some windows apps use for a logs dir.)
+
+    OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA`
+    value for Windows and appends "log" to the user cache dir for Unix.
+    This can be disabled with the `opinion=False` option.
+    """
+    if system == "darwin":
+        path = os.path.join(
+            os.path.expanduser('~/Library/Logs'),
+            appname)
+    elif system == "win32":
+        path = user_data_dir(appname, appauthor, version)
+        version = False
+        if opinion:
+            path = os.path.join(path, "Logs")
+    else:
+        path = user_cache_dir(appname, appauthor, version)
+        version = False
+        if opinion:
+            path = os.path.join(path, "log")
+    if appname and version:
+        path = os.path.join(path, version)
+    return path
+
+
+class AppDirs(object):
+    """Convenience wrapper for getting application dirs."""
+    def __init__(self, appname, appauthor=None, version=None, roaming=False,
+                 multipath=False):
+        self.appname = appname
+        self.appauthor = appauthor
+        self.version = version
+        self.roaming = roaming
+        self.multipath = multipath
+
+    @property
+    def user_data_dir(self):
+        return user_data_dir(self.appname, self.appauthor,
+                             version=self.version, roaming=self.roaming)
+
+    @property
+    def site_data_dir(self):
+        return site_data_dir(self.appname, self.appauthor,
+                             version=self.version, multipath=self.multipath)
+
+    @property
+    def user_config_dir(self):
+        return user_config_dir(self.appname, self.appauthor,
+                               version=self.version, roaming=self.roaming)
+
+    @property
+    def site_config_dir(self):
+        return site_config_dir(self.appname, self.appauthor,
+                             version=self.version, multipath=self.multipath)
+
+    @property
+    def user_cache_dir(self):
+        return user_cache_dir(self.appname, self.appauthor,
+                              version=self.version)
+
+    @property
+    def user_log_dir(self):
+        return user_log_dir(self.appname, self.appauthor,
+                            version=self.version)
+
+
+#---- internal support stuff
+
+def _get_win_folder_from_registry(csidl_name):
+    """This is a fallback technique at best. I'm not sure if using the
+    registry for this guarantees us the correct answer for all CSIDL_*
+    names.
+    """
+    import _winreg
+
+    shell_folder_name = {
+        "CSIDL_APPDATA": "AppData",
+        "CSIDL_COMMON_APPDATA": "Common AppData",
+        "CSIDL_LOCAL_APPDATA": "Local AppData",
+    }[csidl_name]
+
+    key = _winreg.OpenKey(
+        _winreg.HKEY_CURRENT_USER,
+        r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
+    )
+    dir, type = _winreg.QueryValueEx(key, shell_folder_name)
+    return dir
+
+
+def _get_win_folder_with_pywin32(csidl_name):
+    from win32com.shell import shellcon, shell
+    dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0)
+    # Try to make this a unicode path because SHGetFolderPath does
+    # not return unicode strings when there is unicode data in the
+    # path.
+    try:
+        dir = unicode(dir)
+
+        # Downgrade to short path name if have highbit chars. See
+        # <http://bugs.activestate.com/show_bug.cgi?id=85099>.
+        has_high_char = False
+        for c in dir:
+            if ord(c) > 255:
+                has_high_char = True
+                break
+        if has_high_char:
+            try:
+                import win32api
+                dir = win32api.GetShortPathName(dir)
+            except ImportError:
+                pass
+    except UnicodeError:
+        pass
+    return dir
+
+
+def _get_win_folder_with_ctypes(csidl_name):
+    import ctypes
+
+    csidl_const = {
+        "CSIDL_APPDATA": 26,
+        "CSIDL_COMMON_APPDATA": 35,
+        "CSIDL_LOCAL_APPDATA": 28,
+    }[csidl_name]
+
+    buf = ctypes.create_unicode_buffer(1024)
+    ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf)
+
+    # Downgrade to short path name if have highbit chars. See
+    # <http://bugs.activestate.com/show_bug.cgi?id=85099>.
+    has_high_char = False
+    for c in buf:
+        if ord(c) > 255:
+            has_high_char = True
+            break
+    if has_high_char:
+        buf2 = ctypes.create_unicode_buffer(1024)
+        if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024):
+            buf = buf2
+
+    return buf.value
+
+def _get_win_folder_with_jna(csidl_name):
+    import array
+    from com.sun import jna
+    from com.sun.jna.platform import win32
+
+    buf_size = win32.WinDef.MAX_PATH * 2
+    buf = array.zeros('c', buf_size)
+    shell = win32.Shell32.INSTANCE
+    shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf)
+    dir = jna.Native.toString(buf.tostring()).rstrip("\0")
+
+    # Downgrade to short path name if have highbit chars. See
+    # <http://bugs.activestate.com/show_bug.cgi?id=85099>.
+    has_high_char = False
+    for c in dir:
+        if ord(c) > 255:
+            has_high_char = True
+            break
+    if has_high_char:
+        buf = array.zeros('c', buf_size)
+        kernel = win32.Kernel32.INSTANCE
+        if kernal.GetShortPathName(dir, buf, buf_size):
+            dir = jna.Native.toString(buf.tostring()).rstrip("\0")
+
+    return dir
+
+if system == "win32":
+    try:
+        import win32com.shell
+        _get_win_folder = _get_win_folder_with_pywin32
+    except ImportError:
+        try:
+            from ctypes import windll
+            _get_win_folder = _get_win_folder_with_ctypes
+        except ImportError:
+            try:
+                import com.sun.jna
+                _get_win_folder = _get_win_folder_with_jna
+            except ImportError:
+                _get_win_folder = _get_win_folder_from_registry
+
+
+#---- self test code
+
+if __name__ == "__main__":
+    appname = "MyApp"
+    appauthor = "MyCompany"
+
+    props = ("user_data_dir", "site_data_dir",
+             "user_config_dir", "site_config_dir",
+             "user_cache_dir", "user_log_dir")
+
+    print("-- app dirs (with optional 'version')")
+    dirs = AppDirs(appname, appauthor, version="1.0")
+    for prop in props:
+        print("%s: %s" % (prop, getattr(dirs, prop)))
+
+    print("\n-- app dirs (without optional 'version')")
+    dirs = AppDirs(appname, appauthor)
+    for prop in props:
+        print("%s: %s" % (prop, getattr(dirs, prop)))
+
+    print("\n-- app dirs (without optional 'appauthor')")
+    dirs = AppDirs(appname)
+    for prop in props:
+        print("%s: %s" % (prop, getattr(dirs, prop)))
+
+    print("\n-- app dirs (with disabled 'appauthor')")
+    dirs = AppDirs(appname, appauthor=False)
+    for prop in props:
+        print("%s: %s" % (prop, getattr(dirs, prop)))
diff --git a/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/__about__.py b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/__about__.py
new file mode 100644
index 00000000..95d330ef
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/__about__.py
@@ -0,0 +1,21 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+__all__ = [
+    "__title__", "__summary__", "__uri__", "__version__", "__author__",
+    "__email__", "__license__", "__copyright__",
+]
+
+__title__ = "packaging"
+__summary__ = "Core utilities for Python packages"
+__uri__ = "https://github.com/pypa/packaging"
+
+__version__ = "16.8"
+
+__author__ = "Donald Stufft and individual contributors"
+__email__ = "donald@stufft.io"
+
+__license__ = "BSD or Apache License, Version 2.0"
+__copyright__ = "Copyright 2014-2016 %s" % __author__
diff --git a/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/__init__.py b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/__init__.py
new file mode 100644
index 00000000..5ee62202
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/__init__.py
@@ -0,0 +1,14 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+from .__about__ import (
+    __author__, __copyright__, __email__, __license__, __summary__, __title__,
+    __uri__, __version__
+)
+
+__all__ = [
+    "__title__", "__summary__", "__uri__", "__version__", "__author__",
+    "__email__", "__license__", "__copyright__",
+]
diff --git a/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/_compat.py b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/_compat.py
new file mode 100644
index 00000000..210bb80b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/_compat.py
@@ -0,0 +1,30 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import sys
+
+
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
+
+# flake8: noqa
+
+if PY3:
+    string_types = str,
+else:
+    string_types = basestring,
+
+
+def with_metaclass(meta, *bases):
+    """
+    Create a base class with a metaclass.
+    """
+    # This requires a bit of explanation: the basic idea is to make a dummy
+    # metaclass for one level of class instantiation that replaces itself with
+    # the actual metaclass.
+    class metaclass(meta):
+        def __new__(cls, name, this_bases, d):
+            return meta(name, bases, d)
+    return type.__new__(metaclass, 'temporary_class', (), {})
diff --git a/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/_structures.py b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/_structures.py
new file mode 100644
index 00000000..ccc27861
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/_structures.py
@@ -0,0 +1,68 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+
+class Infinity(object):
+
+    def __repr__(self):
+        return "Infinity"
+
+    def __hash__(self):
+        return hash(repr(self))
+
+    def __lt__(self, other):
+        return False
+
+    def __le__(self, other):
+        return False
+
+    def __eq__(self, other):
+        return isinstance(other, self.__class__)
+
+    def __ne__(self, other):
+        return not isinstance(other, self.__class__)
+
+    def __gt__(self, other):
+        return True
+
+    def __ge__(self, other):
+        return True
+
+    def __neg__(self):
+        return NegativeInfinity
+
+Infinity = Infinity()
+
+
+class NegativeInfinity(object):
+
+    def __repr__(self):
+        return "-Infinity"
+
+    def __hash__(self):
+        return hash(repr(self))
+
+    def __lt__(self, other):
+        return True
+
+    def __le__(self, other):
+        return True
+
+    def __eq__(self, other):
+        return isinstance(other, self.__class__)
+
+    def __ne__(self, other):
+        return not isinstance(other, self.__class__)
+
+    def __gt__(self, other):
+        return False
+
+    def __ge__(self, other):
+        return False
+
+    def __neg__(self):
+        return Infinity
+
+NegativeInfinity = NegativeInfinity()
diff --git a/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/markers.py b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/markers.py
new file mode 100644
index 00000000..892e578e
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/markers.py
@@ -0,0 +1,301 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import operator
+import os
+import platform
+import sys
+
+from pkg_resources.extern.pyparsing import ParseException, ParseResults, stringStart, stringEnd
+from pkg_resources.extern.pyparsing import ZeroOrMore, Group, Forward, QuotedString
+from pkg_resources.extern.pyparsing import Literal as L  # noqa
+
+from ._compat import string_types
+from .specifiers import Specifier, InvalidSpecifier
+
+
+__all__ = [
+    "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName",
+    "Marker", "default_environment",
+]
+
+
+class InvalidMarker(ValueError):
+    """
+    An invalid marker was found, users should refer to PEP 508.
+    """
+
+
+class UndefinedComparison(ValueError):
+    """
+    An invalid operation was attempted on a value that doesn't support it.
+    """
+
+
+class UndefinedEnvironmentName(ValueError):
+    """
+    A name was attempted to be used that does not exist inside of the
+    environment.
+    """
+
+
+class Node(object):
+
+    def __init__(self, value):
+        self.value = value
+
+    def __str__(self):
+        return str(self.value)
+
+    def __repr__(self):
+        return "<{0}({1!r})>".format(self.__class__.__name__, str(self))
+
+    def serialize(self):
+        raise NotImplementedError
+
+
+class Variable(Node):
+
+    def serialize(self):
+        return str(self)
+
+
+class Value(Node):
+
+    def serialize(self):
+        return '"{0}"'.format(self)
+
+
+class Op(Node):
+
+    def serialize(self):
+        return str(self)
+
+
+VARIABLE = (
+    L("implementation_version") |
+    L("platform_python_implementation") |
+    L("implementation_name") |
+    L("python_full_version") |
+    L("platform_release") |
+    L("platform_version") |
+    L("platform_machine") |
+    L("platform_system") |
+    L("python_version") |
+    L("sys_platform") |
+    L("os_name") |
+    L("os.name") |  # PEP-345
+    L("sys.platform") |  # PEP-345
+    L("platform.version") |  # PEP-345
+    L("platform.machine") |  # PEP-345
+    L("platform.python_implementation") |  # PEP-345
+    L("python_implementation") |  # undocumented setuptools legacy
+    L("extra")
+)
+ALIASES = {
+    'os.name': 'os_name',
+    'sys.platform': 'sys_platform',
+    'platform.version': 'platform_version',
+    'platform.machine': 'platform_machine',
+    'platform.python_implementation': 'platform_python_implementation',
+    'python_implementation': 'platform_python_implementation'
+}
+VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0])))
+
+VERSION_CMP = (
+    L("===") |
+    L("==") |
+    L(">=") |
+    L("<=") |
+    L("!=") |
+    L("~=") |
+    L(">") |
+    L("<")
+)
+
+MARKER_OP = VERSION_CMP | L("not in") | L("in")
+MARKER_OP.setParseAction(lambda s, l, t: Op(t[0]))
+
+MARKER_VALUE = QuotedString("'") | QuotedString('"')
+MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0]))
+
+BOOLOP = L("and") | L("or")
+
+MARKER_VAR = VARIABLE | MARKER_VALUE
+
+MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR)
+MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0]))
+
+LPAREN = L("(").suppress()
+RPAREN = L(")").suppress()
+
+MARKER_EXPR = Forward()
+MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN)
+MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR)
+
+MARKER = stringStart + MARKER_EXPR + stringEnd
+
+
+def _coerce_parse_result(results):
+    if isinstance(results, ParseResults):
+        return [_coerce_parse_result(i) for i in results]
+    else:
+        return results
+
+
+def _format_marker(marker, first=True):
+    assert isinstance(marker, (list, tuple, string_types))
+
+    # Sometimes we have a structure like [[...]] which is a single item list
+    # where the single item is itself it's own list. In that case we want skip
+    # the rest of this function so that we don't get extraneous () on the
+    # outside.
+    if (isinstance(marker, list) and len(marker) == 1 and
+            isinstance(marker[0], (list, tuple))):
+        return _format_marker(marker[0])
+
+    if isinstance(marker, list):
+        inner = (_format_marker(m, first=False) for m in marker)
+        if first:
+            return " ".join(inner)
+        else:
+            return "(" + " ".join(inner) + ")"
+    elif isinstance(marker, tuple):
+        return " ".join([m.serialize() for m in marker])
+    else:
+        return marker
+
+
+_operators = {
+    "in": lambda lhs, rhs: lhs in rhs,
+    "not in": lambda lhs, rhs: lhs not in rhs,
+    "<": operator.lt,
+    "<=": operator.le,
+    "==": operator.eq,
+    "!=": operator.ne,
+    ">=": operator.ge,
+    ">": operator.gt,
+}
+
+
+def _eval_op(lhs, op, rhs):
+    try:
+        spec = Specifier("".join([op.serialize(), rhs]))
+    except InvalidSpecifier:
+        pass
+    else:
+        return spec.contains(lhs)
+
+    oper = _operators.get(op.serialize())
+    if oper is None:
+        raise UndefinedComparison(
+            "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs)
+        )
+
+    return oper(lhs, rhs)
+
+
+_undefined = object()
+
+
+def _get_env(environment, name):
+    value = environment.get(name, _undefined)
+
+    if value is _undefined:
+        raise UndefinedEnvironmentName(
+            "{0!r} does not exist in evaluation environment.".format(name)
+        )
+
+    return value
+
+
+def _evaluate_markers(markers, environment):
+    groups = [[]]
+
+    for marker in markers:
+        assert isinstance(marker, (list, tuple, string_types))
+
+        if isinstance(marker, list):
+            groups[-1].append(_evaluate_markers(marker, environment))
+        elif isinstance(marker, tuple):
+            lhs, op, rhs = marker
+
+            if isinstance(lhs, Variable):
+                lhs_value = _get_env(environment, lhs.value)
+                rhs_value = rhs.value
+            else:
+                lhs_value = lhs.value
+                rhs_value = _get_env(environment, rhs.value)
+
+            groups[-1].append(_eval_op(lhs_value, op, rhs_value))
+        else:
+            assert marker in ["and", "or"]
+            if marker == "or":
+                groups.append([])
+
+    return any(all(item) for item in groups)
+
+
+def format_full_version(info):
+    version = '{0.major}.{0.minor}.{0.micro}'.format(info)
+    kind = info.releaselevel
+    if kind != 'final':
+        version += kind[0] + str(info.serial)
+    return version
+
+
+def default_environment():
+    if hasattr(sys, 'implementation'):
+        iver = format_full_version(sys.implementation.version)
+        implementation_name = sys.implementation.name
+    else:
+        iver = '0'
+        implementation_name = ''
+
+    return {
+        "implementation_name": implementation_name,
+        "implementation_version": iver,
+        "os_name": os.name,
+        "platform_machine": platform.machine(),
+        "platform_release": platform.release(),
+        "platform_system": platform.system(),
+        "platform_version": platform.version(),
+        "python_full_version": platform.python_version(),
+        "platform_python_implementation": platform.python_implementation(),
+        "python_version": platform.python_version()[:3],
+        "sys_platform": sys.platform,
+    }
+
+
+class Marker(object):
+
+    def __init__(self, marker):
+        try:
+            self._markers = _coerce_parse_result(MARKER.parseString(marker))
+        except ParseException as e:
+            err_str = "Invalid marker: {0!r}, parse error at {1!r}".format(
+                marker, marker[e.loc:e.loc + 8])
+            raise InvalidMarker(err_str)
+
+    def __str__(self):
+        return _format_marker(self._markers)
+
+    def __repr__(self):
+        return "<Marker({0!r})>".format(str(self))
+
+    def evaluate(self, environment=None):
+        """Evaluate a marker.
+
+        Return the boolean from evaluating the given marker against the
+        environment. environment is an optional argument to override all or
+        part of the determined environment.
+
+        The environment is determined from the current Python process.
+        """
+        current_environment = default_environment()
+        if environment is not None:
+            current_environment.update(environment)
+
+        return _evaluate_markers(self._markers, current_environment)
diff --git a/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/requirements.py b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/requirements.py
new file mode 100644
index 00000000..0c8c4a38
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/requirements.py
@@ -0,0 +1,127 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import string
+import re
+
+from pkg_resources.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException
+from pkg_resources.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine
+from pkg_resources.extern.pyparsing import Literal as L  # noqa
+from pkg_resources.extern.six.moves.urllib import parse as urlparse
+
+from .markers import MARKER_EXPR, Marker
+from .specifiers import LegacySpecifier, Specifier, SpecifierSet
+
+
+class InvalidRequirement(ValueError):
+    """
+    An invalid requirement was found, users should refer to PEP 508.
+    """
+
+
+ALPHANUM = Word(string.ascii_letters + string.digits)
+
+LBRACKET = L("[").suppress()
+RBRACKET = L("]").suppress()
+LPAREN = L("(").suppress()
+RPAREN = L(")").suppress()
+COMMA = L(",").suppress()
+SEMICOLON = L(";").suppress()
+AT = L("@").suppress()
+
+PUNCTUATION = Word("-_.")
+IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM)
+IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END))
+
+NAME = IDENTIFIER("name")
+EXTRA = IDENTIFIER
+
+URI = Regex(r'[^ ]+')("url")
+URL = (AT + URI)
+
+EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA)
+EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras")
+
+VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE)
+VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE)
+
+VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY
+VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE),
+                       joinString=",", adjacent=False)("_raw_spec")
+_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY))
+_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '')
+
+VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier")
+VERSION_SPEC.setParseAction(lambda s, l, t: t[1])
+
+MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker")
+MARKER_EXPR.setParseAction(
+    lambda s, l, t: Marker(s[t._original_start:t._original_end])
+)
+MARKER_SEPERATOR = SEMICOLON
+MARKER = MARKER_SEPERATOR + MARKER_EXPR
+
+VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER)
+URL_AND_MARKER = URL + Optional(MARKER)
+
+NAMED_REQUIREMENT = \
+    NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER)
+
+REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd
+
+
+class Requirement(object):
+    """Parse a requirement.
+
+    Parse a given requirement string into its parts, such as name, specifier,
+    URL, and extras. Raises InvalidRequirement on a badly-formed requirement
+    string.
+    """
+
+    # TODO: Can we test whether something is contained within a requirement?
+    #       If so how do we do that? Do we need to test against the _name_ of
+    #       the thing as well as the version? What about the markers?
+    # TODO: Can we normalize the name and extra name?
+
+    def __init__(self, requirement_string):
+        try:
+            req = REQUIREMENT.parseString(requirement_string)
+        except ParseException as e:
+            raise InvalidRequirement(
+                "Invalid requirement, parse error at \"{0!r}\"".format(
+                    requirement_string[e.loc:e.loc + 8]))
+
+        self.name = req.name
+        if req.url:
+            parsed_url = urlparse.urlparse(req.url)
+            if not (parsed_url.scheme and parsed_url.netloc) or (
+                    not parsed_url.scheme and not parsed_url.netloc):
+                raise InvalidRequirement("Invalid URL given")
+            self.url = req.url
+        else:
+            self.url = None
+        self.extras = set(req.extras.asList() if req.extras else [])
+        self.specifier = SpecifierSet(req.specifier)
+        self.marker = req.marker if req.marker else None
+
+    def __str__(self):
+        parts = [self.name]
+
+        if self.extras:
+            parts.append("[{0}]".format(",".join(sorted(self.extras))))
+
+        if self.specifier:
+            parts.append(str(self.specifier))
+
+        if self.url:
+            parts.append("@ {0}".format(self.url))
+
+        if self.marker:
+            parts.append("; {0}".format(self.marker))
+
+        return "".join(parts)
+
+    def __repr__(self):
+        return "<Requirement({0!r})>".format(str(self))
diff --git a/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/specifiers.py b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/specifiers.py
new file mode 100644
index 00000000..7f5a76cf
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/specifiers.py
@@ -0,0 +1,774 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import abc
+import functools
+import itertools
+import re
+
+from ._compat import string_types, with_metaclass
+from .version import Version, LegacyVersion, parse
+
+
+class InvalidSpecifier(ValueError):
+    """
+    An invalid specifier was found, users should refer to PEP 440.
+    """
+
+
+class BaseSpecifier(with_metaclass(abc.ABCMeta, object)):
+
+    @abc.abstractmethod
+    def __str__(self):
+        """
+        Returns the str representation of this Specifier like object. This
+        should be representative of the Specifier itself.
+        """
+
+    @abc.abstractmethod
+    def __hash__(self):
+        """
+        Returns a hash value for this Specifier like object.
+        """
+
+    @abc.abstractmethod
+    def __eq__(self, other):
+        """
+        Returns a boolean representing whether or not the two Specifier like
+        objects are equal.
+        """
+
+    @abc.abstractmethod
+    def __ne__(self, other):
+        """
+        Returns a boolean representing whether or not the two Specifier like
+        objects are not equal.
+        """
+
+    @abc.abstractproperty
+    def prereleases(self):
+        """
+        Returns whether or not pre-releases as a whole are allowed by this
+        specifier.
+        """
+
+    @prereleases.setter
+    def prereleases(self, value):
+        """
+        Sets whether or not pre-releases as a whole are allowed by this
+        specifier.
+        """
+
+    @abc.abstractmethod
+    def contains(self, item, prereleases=None):
+        """
+        Determines if the given item is contained within this specifier.
+        """
+
+    @abc.abstractmethod
+    def filter(self, iterable, prereleases=None):
+        """
+        Takes an iterable of items and filters them so that only items which
+        are contained within this specifier are allowed in it.
+        """
+
+
+class _IndividualSpecifier(BaseSpecifier):
+
+    _operators = {}
+
+    def __init__(self, spec="", prereleases=None):
+        match = self._regex.search(spec)
+        if not match:
+            raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec))
+
+        self._spec = (
+            match.group("operator").strip(),
+            match.group("version").strip(),
+        )
+
+        # Store whether or not this Specifier should accept prereleases
+        self._prereleases = prereleases
+
+    def __repr__(self):
+        pre = (
+            ", prereleases={0!r}".format(self.prereleases)
+            if self._prereleases is not None
+            else ""
+        )
+
+        return "<{0}({1!r}{2})>".format(
+            self.__class__.__name__,
+            str(self),
+            pre,
+        )
+
+    def __str__(self):
+        return "{0}{1}".format(*self._spec)
+
+    def __hash__(self):
+        return hash(self._spec)
+
+    def __eq__(self, other):
+        if isinstance(other, string_types):
+            try:
+                other = self.__class__(other)
+            except InvalidSpecifier:
+                return NotImplemented
+        elif not isinstance(other, self.__class__):
+            return NotImplemented
+
+        return self._spec == other._spec
+
+    def __ne__(self, other):
+        if isinstance(other, string_types):
+            try:
+                other = self.__class__(other)
+            except InvalidSpecifier:
+                return NotImplemented
+        elif not isinstance(other, self.__class__):
+            return NotImplemented
+
+        return self._spec != other._spec
+
+    def _get_operator(self, op):
+        return getattr(self, "_compare_{0}".format(self._operators[op]))
+
+    def _coerce_version(self, version):
+        if not isinstance(version, (LegacyVersion, Version)):
+            version = parse(version)
+        return version
+
+    @property
+    def operator(self):
+        return self._spec[0]
+
+    @property
+    def version(self):
+        return self._spec[1]
+
+    @property
+    def prereleases(self):
+        return self._prereleases
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+    def __contains__(self, item):
+        return self.contains(item)
+
+    def contains(self, item, prereleases=None):
+        # Determine if prereleases are to be allowed or not.
+        if prereleases is None:
+            prereleases = self.prereleases
+
+        # Normalize item to a Version or LegacyVersion, this allows us to have
+        # a shortcut for ``"2.0" in Specifier(">=2")
+        item = self._coerce_version(item)
+
+        # Determine if we should be supporting prereleases in this specifier
+        # or not, if we do not support prereleases than we can short circuit
+        # logic if this version is a prereleases.
+        if item.is_prerelease and not prereleases:
+            return False
+
+        # Actually do the comparison to determine if this item is contained
+        # within this Specifier or not.
+        return self._get_operator(self.operator)(item, self.version)
+
+    def filter(self, iterable, prereleases=None):
+        yielded = False
+        found_prereleases = []
+
+        kw = {"prereleases": prereleases if prereleases is not None else True}
+
+        # Attempt to iterate over all the values in the iterable and if any of
+        # them match, yield them.
+        for version in iterable:
+            parsed_version = self._coerce_version(version)
+
+            if self.contains(parsed_version, **kw):
+                # If our version is a prerelease, and we were not set to allow
+                # prereleases, then we'll store it for later incase nothing
+                # else matches this specifier.
+                if (parsed_version.is_prerelease and not
+                        (prereleases or self.prereleases)):
+                    found_prereleases.append(version)
+                # Either this is not a prerelease, or we should have been
+                # accepting prereleases from the begining.
+                else:
+                    yielded = True
+                    yield version
+
+        # Now that we've iterated over everything, determine if we've yielded
+        # any values, and if we have not and we have any prereleases stored up
+        # then we will go ahead and yield the prereleases.
+        if not yielded and found_prereleases:
+            for version in found_prereleases:
+                yield version
+
+
+class LegacySpecifier(_IndividualSpecifier):
+
+    _regex_str = (
+        r"""
+        (?P<operator>(==|!=|<=|>=|<|>))
+        \s*
+        (?P<version>
+            [^,;\s)]* # Since this is a "legacy" specifier, and the version
+                      # string can be just about anything, we match everything
+                      # except for whitespace, a semi-colon for marker support,
+                      # a closing paren since versions can be enclosed in
+                      # them, and a comma since it's a version separator.
+        )
+        """
+    )
+
+    _regex = re.compile(
+        r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
+
+    _operators = {
+        "==": "equal",
+        "!=": "not_equal",
+        "<=": "less_than_equal",
+        ">=": "greater_than_equal",
+        "<": "less_than",
+        ">": "greater_than",
+    }
+
+    def _coerce_version(self, version):
+        if not isinstance(version, LegacyVersion):
+            version = LegacyVersion(str(version))
+        return version
+
+    def _compare_equal(self, prospective, spec):
+        return prospective == self._coerce_version(spec)
+
+    def _compare_not_equal(self, prospective, spec):
+        return prospective != self._coerce_version(spec)
+
+    def _compare_less_than_equal(self, prospective, spec):
+        return prospective <= self._coerce_version(spec)
+
+    def _compare_greater_than_equal(self, prospective, spec):
+        return prospective >= self._coerce_version(spec)
+
+    def _compare_less_than(self, prospective, spec):
+        return prospective < self._coerce_version(spec)
+
+    def _compare_greater_than(self, prospective, spec):
+        return prospective > self._coerce_version(spec)
+
+
+def _require_version_compare(fn):
+    @functools.wraps(fn)
+    def wrapped(self, prospective, spec):
+        if not isinstance(prospective, Version):
+            return False
+        return fn(self, prospective, spec)
+    return wrapped
+
+
+class Specifier(_IndividualSpecifier):
+
+    _regex_str = (
+        r"""
+        (?P<operator>(~=|==|!=|<=|>=|<|>|===))
+        (?P<version>
+            (?:
+                # The identity operators allow for an escape hatch that will
+                # do an exact string match of the version you wish to install.
+                # This will not be parsed by PEP 440 and we cannot determine
+                # any semantic meaning from it. This operator is discouraged
+                # but included entirely as an escape hatch.
+                (?<====)  # Only match for the identity operator
+                \s*
+                [^\s]*    # We just match everything, except for whitespace
+                          # since we are only testing for strict identity.
+            )
+            |
+            (?:
+                # The (non)equality operators allow for wild card and local
+                # versions to be specified so we have to define these two
+                # operators separately to enable that.
+                (?<===|!=)            # Only match for equals and not equals
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)*   # release
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+
+                # You cannot use a wild card and a dev or local version
+                # together so group them with a | and make them optional.
+                (?:
+                    (?:[-_\.]?dev[-_\.]?[0-9]*)?         # dev release
+                    (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local
+                    |
+                    \.\*  # Wild card syntax of .*
+                )?
+            )
+            |
+            (?:
+                # The compatible operator requires at least two digits in the
+                # release segment.
+                (?<=~=)               # Only match for the compatible operator
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)+   # release  (We have a + instead of a *)
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
+            )
+            |
+            (?:
+                # All other operators only allow a sub set of what the
+                # (non)equality operators do. Specifically they do not allow
+                # local versions to be specified nor do they allow the prefix
+                # matching wild cards.
+                (?<!==|!=|~=)         # We have special cases for these
+                                      # operators so we want to make sure they
+                                      # don't match here.
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)*   # release
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
+            )
+        )
+        """
+    )
+
+    _regex = re.compile(
+        r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
+
+    _operators = {
+        "~=": "compatible",
+        "==": "equal",
+        "!=": "not_equal",
+        "<=": "less_than_equal",
+        ">=": "greater_than_equal",
+        "<": "less_than",
+        ">": "greater_than",
+        "===": "arbitrary",
+    }
+
+    @_require_version_compare
+    def _compare_compatible(self, prospective, spec):
+        # Compatible releases have an equivalent combination of >= and ==. That
+        # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to
+        # implement this in terms of the other specifiers instead of
+        # implementing it ourselves. The only thing we need to do is construct
+        # the other specifiers.
+
+        # We want everything but the last item in the version, but we want to
+        # ignore post and dev releases and we want to treat the pre-release as
+        # it's own separate segment.
+        prefix = ".".join(
+            list(
+                itertools.takewhile(
+                    lambda x: (not x.startswith("post") and not
+                               x.startswith("dev")),
+                    _version_split(spec),
+                )
+            )[:-1]
+        )
+
+        # Add the prefix notation to the end of our string
+        prefix += ".*"
+
+        return (self._get_operator(">=")(prospective, spec) and
+                self._get_operator("==")(prospective, prefix))
+
+    @_require_version_compare
+    def _compare_equal(self, prospective, spec):
+        # We need special logic to handle prefix matching
+        if spec.endswith(".*"):
+            # In the case of prefix matching we want to ignore local segment.
+            prospective = Version(prospective.public)
+            # Split the spec out by dots, and pretend that there is an implicit
+            # dot in between a release segment and a pre-release segment.
+            spec = _version_split(spec[:-2])  # Remove the trailing .*
+
+            # Split the prospective version out by dots, and pretend that there
+            # is an implicit dot in between a release segment and a pre-release
+            # segment.
+            prospective = _version_split(str(prospective))
+
+            # Shorten the prospective version to be the same length as the spec
+            # so that we can determine if the specifier is a prefix of the
+            # prospective version or not.
+            prospective = prospective[:len(spec)]
+
+            # Pad out our two sides with zeros so that they both equal the same
+            # length.
+            spec, prospective = _pad_version(spec, prospective)
+        else:
+            # Convert our spec string into a Version
+            spec = Version(spec)
+
+            # If the specifier does not have a local segment, then we want to
+            # act as if the prospective version also does not have a local
+            # segment.
+            if not spec.local:
+                prospective = Version(prospective.public)
+
+        return prospective == spec
+
+    @_require_version_compare
+    def _compare_not_equal(self, prospective, spec):
+        return not self._compare_equal(prospective, spec)
+
+    @_require_version_compare
+    def _compare_less_than_equal(self, prospective, spec):
+        return prospective <= Version(spec)
+
+    @_require_version_compare
+    def _compare_greater_than_equal(self, prospective, spec):
+        return prospective >= Version(spec)
+
+    @_require_version_compare
+    def _compare_less_than(self, prospective, spec):
+        # Convert our spec to a Version instance, since we'll want to work with
+        # it as a version.
+        spec = Version(spec)
+
+        # Check to see if the prospective version is less than the spec
+        # version. If it's not we can short circuit and just return False now
+        # instead of doing extra unneeded work.
+        if not prospective < spec:
+            return False
+
+        # This special case is here so that, unless the specifier itself
+        # includes is a pre-release version, that we do not accept pre-release
+        # versions for the version mentioned in the specifier (e.g. <3.1 should
+        # not match 3.1.dev0, but should match 3.0.dev0).
+        if not spec.is_prerelease and prospective.is_prerelease:
+            if Version(prospective.base_version) == Version(spec.base_version):
+                return False
+
+        # If we've gotten to here, it means that prospective version is both
+        # less than the spec version *and* it's not a pre-release of the same
+        # version in the spec.
+        return True
+
+    @_require_version_compare
+    def _compare_greater_than(self, prospective, spec):
+        # Convert our spec to a Version instance, since we'll want to work with
+        # it as a version.
+        spec = Version(spec)
+
+        # Check to see if the prospective version is greater than the spec
+        # version. If it's not we can short circuit and just return False now
+        # instead of doing extra unneeded work.
+        if not prospective > spec:
+            return False
+
+        # This special case is here so that, unless the specifier itself
+        # includes is a post-release version, that we do not accept
+        # post-release versions for the version mentioned in the specifier
+        # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0).
+        if not spec.is_postrelease and prospective.is_postrelease:
+            if Version(prospective.base_version) == Version(spec.base_version):
+                return False
+
+        # Ensure that we do not allow a local version of the version mentioned
+        # in the specifier, which is techincally greater than, to match.
+        if prospective.local is not None:
+            if Version(prospective.base_version) == Version(spec.base_version):
+                return False
+
+        # If we've gotten to here, it means that prospective version is both
+        # greater than the spec version *and* it's not a pre-release of the
+        # same version in the spec.
+        return True
+
+    def _compare_arbitrary(self, prospective, spec):
+        return str(prospective).lower() == str(spec).lower()
+
+    @property
+    def prereleases(self):
+        # If there is an explicit prereleases set for this, then we'll just
+        # blindly use that.
+        if self._prereleases is not None:
+            return self._prereleases
+
+        # Look at all of our specifiers and determine if they are inclusive
+        # operators, and if they are if they are including an explicit
+        # prerelease.
+        operator, version = self._spec
+        if operator in ["==", ">=", "<=", "~=", "==="]:
+            # The == specifier can include a trailing .*, if it does we
+            # want to remove before parsing.
+            if operator == "==" and version.endswith(".*"):
+                version = version[:-2]
+
+            # Parse the version, and if it is a pre-release than this
+            # specifier allows pre-releases.
+            if parse(version).is_prerelease:
+                return True
+
+        return False
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+
+_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$")
+
+
+def _version_split(version):
+    result = []
+    for item in version.split("."):
+        match = _prefix_regex.search(item)
+        if match:
+            result.extend(match.groups())
+        else:
+            result.append(item)
+    return result
+
+
+def _pad_version(left, right):
+    left_split, right_split = [], []
+
+    # Get the release segment of our versions
+    left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left)))
+    right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right)))
+
+    # Get the rest of our versions
+    left_split.append(left[len(left_split[0]):])
+    right_split.append(right[len(right_split[0]):])
+
+    # Insert our padding
+    left_split.insert(
+        1,
+        ["0"] * max(0, len(right_split[0]) - len(left_split[0])),
+    )
+    right_split.insert(
+        1,
+        ["0"] * max(0, len(left_split[0]) - len(right_split[0])),
+    )
+
+    return (
+        list(itertools.chain(*left_split)),
+        list(itertools.chain(*right_split)),
+    )
+
+
+class SpecifierSet(BaseSpecifier):
+
+    def __init__(self, specifiers="", prereleases=None):
+        # Split on , to break each indidivual specifier into it's own item, and
+        # strip each item to remove leading/trailing whitespace.
+        specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
+
+        # Parsed each individual specifier, attempting first to make it a
+        # Specifier and falling back to a LegacySpecifier.
+        parsed = set()
+        for specifier in specifiers:
+            try:
+                parsed.add(Specifier(specifier))
+            except InvalidSpecifier:
+                parsed.add(LegacySpecifier(specifier))
+
+        # Turn our parsed specifiers into a frozen set and save them for later.
+        self._specs = frozenset(parsed)
+
+        # Store our prereleases value so we can use it later to determine if
+        # we accept prereleases or not.
+        self._prereleases = prereleases
+
+    def __repr__(self):
+        pre = (
+            ", prereleases={0!r}".format(self.prereleases)
+            if self._prereleases is not None
+            else ""
+        )
+
+        return "<SpecifierSet({0!r}{1})>".format(str(self), pre)
+
+    def __str__(self):
+        return ",".join(sorted(str(s) for s in self._specs))
+
+    def __hash__(self):
+        return hash(self._specs)
+
+    def __and__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        specifier = SpecifierSet()
+        specifier._specs = frozenset(self._specs | other._specs)
+
+        if self._prereleases is None and other._prereleases is not None:
+            specifier._prereleases = other._prereleases
+        elif self._prereleases is not None and other._prereleases is None:
+            specifier._prereleases = self._prereleases
+        elif self._prereleases == other._prereleases:
+            specifier._prereleases = self._prereleases
+        else:
+            raise ValueError(
+                "Cannot combine SpecifierSets with True and False prerelease "
+                "overrides."
+            )
+
+        return specifier
+
+    def __eq__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif isinstance(other, _IndividualSpecifier):
+            other = SpecifierSet(str(other))
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        return self._specs == other._specs
+
+    def __ne__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif isinstance(other, _IndividualSpecifier):
+            other = SpecifierSet(str(other))
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        return self._specs != other._specs
+
+    def __len__(self):
+        return len(self._specs)
+
+    def __iter__(self):
+        return iter(self._specs)
+
+    @property
+    def prereleases(self):
+        # If we have been given an explicit prerelease modifier, then we'll
+        # pass that through here.
+        if self._prereleases is not None:
+            return self._prereleases
+
+        # If we don't have any specifiers, and we don't have a forced value,
+        # then we'll just return None since we don't know if this should have
+        # pre-releases or not.
+        if not self._specs:
+            return None
+
+        # Otherwise we'll see if any of the given specifiers accept
+        # prereleases, if any of them do we'll return True, otherwise False.
+        return any(s.prereleases for s in self._specs)
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+    def __contains__(self, item):
+        return self.contains(item)
+
+    def contains(self, item, prereleases=None):
+        # Ensure that our item is a Version or LegacyVersion instance.
+        if not isinstance(item, (LegacyVersion, Version)):
+            item = parse(item)
+
+        # Determine if we're forcing a prerelease or not, if we're not forcing
+        # one for this particular filter call, then we'll use whatever the
+        # SpecifierSet thinks for whether or not we should support prereleases.
+        if prereleases is None:
+            prereleases = self.prereleases
+
+        # We can determine if we're going to allow pre-releases by looking to
+        # see if any of the underlying items supports them. If none of them do
+        # and this item is a pre-release then we do not allow it and we can
+        # short circuit that here.
+        # Note: This means that 1.0.dev1 would not be contained in something
+        #       like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0
+        if not prereleases and item.is_prerelease:
+            return False
+
+        # We simply dispatch to the underlying specs here to make sure that the
+        # given version is contained within all of them.
+        # Note: This use of all() here means that an empty set of specifiers
+        #       will always return True, this is an explicit design decision.
+        return all(
+            s.contains(item, prereleases=prereleases)
+            for s in self._specs
+        )
+
+    def filter(self, iterable, prereleases=None):
+        # Determine if we're forcing a prerelease or not, if we're not forcing
+        # one for this particular filter call, then we'll use whatever the
+        # SpecifierSet thinks for whether or not we should support prereleases.
+        if prereleases is None:
+            prereleases = self.prereleases
+
+        # If we have any specifiers, then we want to wrap our iterable in the
+        # filter method for each one, this will act as a logical AND amongst
+        # each specifier.
+        if self._specs:
+            for spec in self._specs:
+                iterable = spec.filter(iterable, prereleases=bool(prereleases))
+            return iterable
+        # If we do not have any specifiers, then we need to have a rough filter
+        # which will filter out any pre-releases, unless there are no final
+        # releases, and which will filter out LegacyVersion in general.
+        else:
+            filtered = []
+            found_prereleases = []
+
+            for item in iterable:
+                # Ensure that we some kind of Version class for this item.
+                if not isinstance(item, (LegacyVersion, Version)):
+                    parsed_version = parse(item)
+                else:
+                    parsed_version = item
+
+                # Filter out any item which is parsed as a LegacyVersion
+                if isinstance(parsed_version, LegacyVersion):
+                    continue
+
+                # Store any item which is a pre-release for later unless we've
+                # already found a final version or we are accepting prereleases
+                if parsed_version.is_prerelease and not prereleases:
+                    if not filtered:
+                        found_prereleases.append(item)
+                else:
+                    filtered.append(item)
+
+            # If we've found no items except for pre-releases, then we'll go
+            # ahead and use the pre-releases
+            if not filtered and found_prereleases and prereleases is None:
+                return found_prereleases
+
+            return filtered
diff --git a/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/utils.py b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/utils.py
new file mode 100644
index 00000000..942387ce
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/utils.py
@@ -0,0 +1,14 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import re
+
+
+_canonicalize_regex = re.compile(r"[-_.]+")
+
+
+def canonicalize_name(name):
+    # This is taken from PEP 503.
+    return _canonicalize_regex.sub("-", name).lower()
diff --git a/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/version.py b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/version.py
new file mode 100644
index 00000000..83b5ee8c
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/_vendor/packaging/version.py
@@ -0,0 +1,393 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import collections
+import itertools
+import re
+
+from ._structures import Infinity
+
+
+__all__ = [
+    "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"
+]
+
+
+_Version = collections.namedtuple(
+    "_Version",
+    ["epoch", "release", "dev", "pre", "post", "local"],
+)
+
+
+def parse(version):
+    """
+    Parse the given version string and return either a :class:`Version` object
+    or a :class:`LegacyVersion` object depending on if the given version is
+    a valid PEP 440 version or a legacy version.
+    """
+    try:
+        return Version(version)
+    except InvalidVersion:
+        return LegacyVersion(version)
+
+
+class InvalidVersion(ValueError):
+    """
+    An invalid version was found, users should refer to PEP 440.
+    """
+
+
+class _BaseVersion(object):
+
+    def __hash__(self):
+        return hash(self._key)
+
+    def __lt__(self, other):
+        return self._compare(other, lambda s, o: s < o)
+
+    def __le__(self, other):
+        return self._compare(other, lambda s, o: s <= o)
+
+    def __eq__(self, other):
+        return self._compare(other, lambda s, o: s == o)
+
+    def __ge__(self, other):
+        return self._compare(other, lambda s, o: s >= o)
+
+    def __gt__(self, other):
+        return self._compare(other, lambda s, o: s > o)
+
+    def __ne__(self, other):
+        return self._compare(other, lambda s, o: s != o)
+
+    def _compare(self, other, method):
+        if not isinstance(other, _BaseVersion):
+            return NotImplemented
+
+        return method(self._key, other._key)
+
+
+class LegacyVersion(_BaseVersion):
+
+    def __init__(self, version):
+        self._version = str(version)
+        self._key = _legacy_cmpkey(self._version)
+
+    def __str__(self):
+        return self._version
+
+    def __repr__(self):
+        return "<LegacyVersion({0})>".format(repr(str(self)))
+
+    @property
+    def public(self):
+        return self._version
+
+    @property
+    def base_version(self):
+        return self._version
+
+    @property
+    def local(self):
+        return None
+
+    @property
+    def is_prerelease(self):
+        return False
+
+    @property
+    def is_postrelease(self):
+        return False
+
+
+_legacy_version_component_re = re.compile(
+    r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE,
+)
+
+_legacy_version_replacement_map = {
+    "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@",
+}
+
+
+def _parse_version_parts(s):
+    for part in _legacy_version_component_re.split(s):
+        part = _legacy_version_replacement_map.get(part, part)
+
+        if not part or part == ".":
+            continue
+
+        if part[:1] in "0123456789":
+            # pad for numeric comparison
+            yield part.zfill(8)
+        else:
+            yield "*" + part
+
+    # ensure that alpha/beta/candidate are before final
+    yield "*final"
+
+
+def _legacy_cmpkey(version):
+    # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch
+    # greater than or equal to 0. This will effectively put the LegacyVersion,
+    # which uses the defacto standard originally implemented by setuptools,
+    # as before all PEP 440 versions.
+    epoch = -1
+
+    # This scheme is taken from pkg_resources.parse_version setuptools prior to
+    # it's adoption of the packaging library.
+    parts = []
+    for part in _parse_version_parts(version.lower()):
+        if part.startswith("*"):
+            # remove "-" before a prerelease tag
+            if part < "*final":
+                while parts and parts[-1] == "*final-":
+                    parts.pop()
+
+            # remove trailing zeros from each series of numeric parts
+            while parts and parts[-1] == "00000000":
+                parts.pop()
+
+        parts.append(part)
+    parts = tuple(parts)
+
+    return epoch, parts
+
+# Deliberately not anchored to the start and end of the string, to make it
+# easier for 3rd party code to reuse
+VERSION_PATTERN = r"""
+    v?
+    (?:
+        (?:(?P<epoch>[0-9]+)!)?                           # epoch
+        (?P<release>[0-9]+(?:\.[0-9]+)*)                  # release segment
+        (?P<pre>                                          # pre-release
+            [-_\.]?
+            (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview))
+            [-_\.]?
+            (?P<pre_n>[0-9]+)?
+        )?
+        (?P<post>                                         # post release
+            (?:-(?P<post_n1>[0-9]+))
+            |
+            (?:
+                [-_\.]?
+                (?P<post_l>post|rev|r)
+                [-_\.]?
+                (?P<post_n2>[0-9]+)?
+            )
+        )?
+        (?P<dev>                                          # dev release
+            [-_\.]?
+            (?P<dev_l>dev)
+            [-_\.]?
+            (?P<dev_n>[0-9]+)?
+        )?
+    )
+    (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))?       # local version
+"""
+
+
+class Version(_BaseVersion):
+
+    _regex = re.compile(
+        r"^\s*" + VERSION_PATTERN + r"\s*$",
+        re.VERBOSE | re.IGNORECASE,
+    )
+
+    def __init__(self, version):
+        # Validate the version and parse it into pieces
+        match = self._regex.search(version)
+        if not match:
+            raise InvalidVersion("Invalid version: '{0}'".format(version))
+
+        # Store the parsed out pieces of the version
+        self._version = _Version(
+            epoch=int(match.group("epoch")) if match.group("epoch") else 0,
+            release=tuple(int(i) for i in match.group("release").split(".")),
+            pre=_parse_letter_version(
+                match.group("pre_l"),
+                match.group("pre_n"),
+            ),
+            post=_parse_letter_version(
+                match.group("post_l"),
+                match.group("post_n1") or match.group("post_n2"),
+            ),
+            dev=_parse_letter_version(
+                match.group("dev_l"),
+                match.group("dev_n"),
+            ),
+            local=_parse_local_version(match.group("local")),
+        )
+
+        # Generate a key which will be used for sorting
+        self._key = _cmpkey(
+            self._version.epoch,
+            self._version.release,
+            self._version.pre,
+            self._version.post,
+            self._version.dev,
+            self._version.local,
+        )
+
+    def __repr__(self):
+        return "<Version({0})>".format(repr(str(self)))
+
+    def __str__(self):
+        parts = []
+
+        # Epoch
+        if self._version.epoch != 0:
+            parts.append("{0}!".format(self._version.epoch))
+
+        # Release segment
+        parts.append(".".join(str(x) for x in self._version.release))
+
+        # Pre-release
+        if self._version.pre is not None:
+            parts.append("".join(str(x) for x in self._version.pre))
+
+        # Post-release
+        if self._version.post is not None:
+            parts.append(".post{0}".format(self._version.post[1]))
+
+        # Development release
+        if self._version.dev is not None:
+            parts.append(".dev{0}".format(self._version.dev[1]))
+
+        # Local version segment
+        if self._version.local is not None:
+            parts.append(
+                "+{0}".format(".".join(str(x) for x in self._version.local))
+            )
+
+        return "".join(parts)
+
+    @property
+    def public(self):
+        return str(self).split("+", 1)[0]
+
+    @property
+    def base_version(self):
+        parts = []
+
+        # Epoch
+        if self._version.epoch != 0:
+            parts.append("{0}!".format(self._version.epoch))
+
+        # Release segment
+        parts.append(".".join(str(x) for x in self._version.release))
+
+        return "".join(parts)
+
+    @property
+    def local(self):
+        version_string = str(self)
+        if "+" in version_string:
+            return version_string.split("+", 1)[1]
+
+    @property
+    def is_prerelease(self):
+        return bool(self._version.dev or self._version.pre)
+
+    @property
+    def is_postrelease(self):
+        return bool(self._version.post)
+
+
+def _parse_letter_version(letter, number):
+    if letter:
+        # We consider there to be an implicit 0 in a pre-release if there is
+        # not a numeral associated with it.
+        if number is None:
+            number = 0
+
+        # We normalize any letters to their lower case form
+        letter = letter.lower()
+
+        # We consider some words to be alternate spellings of other words and
+        # in those cases we want to normalize the spellings to our preferred
+        # spelling.
+        if letter == "alpha":
+            letter = "a"
+        elif letter == "beta":
+            letter = "b"
+        elif letter in ["c", "pre", "preview"]:
+            letter = "rc"
+        elif letter in ["rev", "r"]:
+            letter = "post"
+
+        return letter, int(number)
+    if not letter and number:
+        # We assume if we are given a number, but we are not given a letter
+        # then this is using the implicit post release syntax (e.g. 1.0-1)
+        letter = "post"
+
+        return letter, int(number)
+
+
+_local_version_seperators = re.compile(r"[\._-]")
+
+
+def _parse_local_version(local):
+    """
+    Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve").
+    """
+    if local is not None:
+        return tuple(
+            part.lower() if not part.isdigit() else int(part)
+            for part in _local_version_seperators.split(local)
+        )
+
+
+def _cmpkey(epoch, release, pre, post, dev, local):
+    # When we compare a release version, we want to compare it with all of the
+    # trailing zeros removed. So we'll use a reverse the list, drop all the now
+    # leading zeros until we come to something non zero, then take the rest
+    # re-reverse it back into the correct order and make it a tuple and use
+    # that for our sorting key.
+    release = tuple(
+        reversed(list(
+            itertools.dropwhile(
+                lambda x: x == 0,
+                reversed(release),
+            )
+        ))
+    )
+
+    # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
+    # We'll do this by abusing the pre segment, but we _only_ want to do this
+    # if there is not a pre or a post segment. If we have one of those then
+    # the normal sorting rules will handle this case correctly.
+    if pre is None and post is None and dev is not None:
+        pre = -Infinity
+    # Versions without a pre-release (except as noted above) should sort after
+    # those with one.
+    elif pre is None:
+        pre = Infinity
+
+    # Versions without a post segment should sort before those with one.
+    if post is None:
+        post = -Infinity
+
+    # Versions without a development segment should sort after those with one.
+    if dev is None:
+        dev = Infinity
+
+    if local is None:
+        # Versions without a local segment should sort before those with one.
+        local = -Infinity
+    else:
+        # Versions with a local segment need that segment parsed to implement
+        # the sorting rules in PEP440.
+        # - Alpha numeric segments sort before numeric segments
+        # - Alpha numeric segments sort lexicographically
+        # - Numeric segments sort numerically
+        # - Shorter versions sort before longer versions when the prefixes
+        #   match exactly
+        local = tuple(
+            (i, "") if isinstance(i, int) else (-Infinity, i)
+            for i in local
+        )
+
+    return epoch, release, pre, post, dev, local
diff --git a/vendor/setuptools-39.0.1/pkg_resources/_vendor/pyparsing.py b/vendor/setuptools-39.0.1/pkg_resources/_vendor/pyparsing.py
new file mode 100644
index 00000000..a2122435
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/_vendor/pyparsing.py
@@ -0,0 +1,5696 @@
+# module pyparsing.py
+#
+# Copyright (c) 2003-2016  Paul T. McGuire
+#
+# 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.
+#
+
+__doc__ = \
+"""
+pyparsing module - Classes and methods to define and execute parsing grammars
+
+The pyparsing module is an alternative approach to creating and executing simple grammars,
+vs. the traditional lex/yacc approach, or the use of regular expressions.  With pyparsing, you
+don't need to learn a new syntax for defining grammars or matching expressions - the parsing module
+provides a library of classes that you use to construct the grammar directly in Python.
+
+Here is a program to parse "Hello, World!" (or any greeting of the form 
+C{"<salutation>, <addressee>!"}), built up using L{Word}, L{Literal}, and L{And} elements 
+(L{'+'<ParserElement.__add__>} operator gives L{And} expressions, strings are auto-converted to
+L{Literal} expressions)::
+
+    from pyparsing import Word, alphas
+
+    # define grammar of a greeting
+    greet = Word(alphas) + "," + Word(alphas) + "!"
+
+    hello = "Hello, World!"
+    print (hello, "->", greet.parseString(hello))
+
+The program outputs the following::
+
+    Hello, World! -> ['Hello', ',', 'World', '!']
+
+The Python representation of the grammar is quite readable, owing to the self-explanatory
+class names, and the use of '+', '|' and '^' operators.
+
+The L{ParseResults} object returned from L{ParserElement.parseString<ParserElement.parseString>} can be accessed as a nested list, a dictionary, or an
+object with named attributes.
+
+The pyparsing module handles some of the problems that are typically vexing when writing text parsers:
+ - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello  ,  World  !", etc.)
+ - quoted strings
+ - embedded comments
+"""
+
+__version__ = "2.1.10"
+__versionTime__ = "07 Oct 2016 01:31 UTC"
+__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
+
+import string
+from weakref import ref as wkref
+import copy
+import sys
+import warnings
+import re
+import sre_constants
+import collections
+import pprint
+import traceback
+import types
+from datetime import datetime
+
+try:
+    from _thread import RLock
+except ImportError:
+    from threading import RLock
+
+try:
+    from collections import OrderedDict as _OrderedDict
+except ImportError:
+    try:
+        from ordereddict import OrderedDict as _OrderedDict
+    except ImportError:
+        _OrderedDict = None
+
+#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) )
+
+__all__ = [
+'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty',
+'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal',
+'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or',
+'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException',
+'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException',
+'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', 
+'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore',
+'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col',
+'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString',
+'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums',
+'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno',
+'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral',
+'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables',
+'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', 
+'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd',
+'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute',
+'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass',
+'CloseMatch', 'tokenMap', 'pyparsing_common',
+]
+
+system_version = tuple(sys.version_info)[:3]
+PY_3 = system_version[0] == 3
+if PY_3:
+    _MAX_INT = sys.maxsize
+    basestring = str
+    unichr = chr
+    _ustr = str
+
+    # build list of single arg builtins, that can be used as parse actions
+    singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max]
+
+else:
+    _MAX_INT = sys.maxint
+    range = xrange
+
+    def _ustr(obj):
+        """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries
+           str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It
+           then < returns the unicode object | encodes it with the default encoding | ... >.
+        """
+        if isinstance(obj,unicode):
+            return obj
+
+        try:
+            # If this works, then _ustr(obj) has the same behaviour as str(obj), so
+            # it won't break any existing code.
+            return str(obj)
+
+        except UnicodeEncodeError:
+            # Else encode it
+            ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace')
+            xmlcharref = Regex('&#\d+;')
+            xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:])
+            return xmlcharref.transformString(ret)
+
+    # build list of single arg builtins, tolerant of Python version, that can be used as parse actions
+    singleArgBuiltins = []
+    import __builtin__
+    for fname in "sum len sorted reversed list tuple set any all min max".split():
+        try:
+            singleArgBuiltins.append(getattr(__builtin__,fname))
+        except AttributeError:
+            continue
+            
+_generatorType = type((y for y in range(1)))
+ 
+def _xml_escape(data):
+    """Escape &, <, >, ", ', etc. in a string of data."""
+
+    # ampersand must be replaced first
+    from_symbols = '&><"\''
+    to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split())
+    for from_,to_ in zip(from_symbols, to_symbols):
+        data = data.replace(from_, to_)
+    return data
+
+class _Constants(object):
+    pass
+
+alphas     = string.ascii_uppercase + string.ascii_lowercase
+nums       = "0123456789"
+hexnums    = nums + "ABCDEFabcdef"
+alphanums  = alphas + nums
+_bslash    = chr(92)
+printables = "".join(c for c in string.printable if c not in string.whitespace)
+
+class ParseBaseException(Exception):
+    """base exception class for all parsing runtime exceptions"""
+    # Performance tuning: we construct a *lot* of these, so keep this
+    # constructor as small and fast as possible
+    def __init__( self, pstr, loc=0, msg=None, elem=None ):
+        self.loc = loc
+        if msg is None:
+            self.msg = pstr
+            self.pstr = ""
+        else:
+            self.msg = msg
+            self.pstr = pstr
+        self.parserElement = elem
+        self.args = (pstr, loc, msg)
+
+    @classmethod
+    def _from_exception(cls, pe):
+        """
+        internal factory method to simplify creating one type of ParseException 
+        from another - avoids having __init__ signature conflicts among subclasses
+        """
+        return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement)
+
+    def __getattr__( self, aname ):
+        """supported attributes by name are:
+            - lineno - returns the line number of the exception text
+            - col - returns the column number of the exception text
+            - line - returns the line containing the exception text
+        """
+        if( aname == "lineno" ):
+            return lineno( self.loc, self.pstr )
+        elif( aname in ("col", "column") ):
+            return col( self.loc, self.pstr )
+        elif( aname == "line" ):
+            return line( self.loc, self.pstr )
+        else:
+            raise AttributeError(aname)
+
+    def __str__( self ):
+        return "%s (at char %d), (line:%d, col:%d)" % \
+                ( self.msg, self.loc, self.lineno, self.column )
+    def __repr__( self ):
+        return _ustr(self)
+    def markInputline( self, markerString = ">!<" ):
+        """Extracts the exception line from the input string, and marks
+           the location of the exception with a special symbol.
+        """
+        line_str = self.line
+        line_column = self.column - 1
+        if markerString:
+            line_str = "".join((line_str[:line_column],
+                                markerString, line_str[line_column:]))
+        return line_str.strip()
+    def __dir__(self):
+        return "lineno col line".split() + dir(type(self))
+
+class ParseException(ParseBaseException):
+    """
+    Exception thrown when parse expressions don't match class;
+    supported attributes by name are:
+     - lineno - returns the line number of the exception text
+     - col - returns the column number of the exception text
+     - line - returns the line containing the exception text
+        
+    Example::
+        try:
+            Word(nums).setName("integer").parseString("ABC")
+        except ParseException as pe:
+            print(pe)
+            print("column: {}".format(pe.col))
+            
+    prints::
+       Expected integer (at char 0), (line:1, col:1)
+        column: 1
+    """
+    pass
+
+class ParseFatalException(ParseBaseException):
+    """user-throwable exception thrown when inconsistent parse content
+       is found; stops all parsing immediately"""
+    pass
+
+class ParseSyntaxException(ParseFatalException):
+    """just like L{ParseFatalException}, but thrown internally when an
+       L{ErrorStop<And._ErrorStop>} ('-' operator) indicates that parsing is to stop 
+       immediately because an unbacktrackable syntax error has been found"""
+    pass
+
+#~ class ReparseException(ParseBaseException):
+    #~ """Experimental class - parse actions can raise this exception to cause
+       #~ pyparsing to reparse the input string:
+        #~ - with a modified input string, and/or
+        #~ - with a modified start location
+       #~ Set the values of the ReparseException in the constructor, and raise the
+       #~ exception in a parse action to cause pyparsing to use the new string/location.
+       #~ Setting the values as None causes no change to be made.
+       #~ """
+    #~ def __init_( self, newstring, restartLoc ):
+        #~ self.newParseText = newstring
+        #~ self.reparseLoc = restartLoc
+
+class RecursiveGrammarException(Exception):
+    """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive"""
+    def __init__( self, parseElementList ):
+        self.parseElementTrace = parseElementList
+
+    def __str__( self ):
+        return "RecursiveGrammarException: %s" % self.parseElementTrace
+
+class _ParseResultsWithOffset(object):
+    def __init__(self,p1,p2):
+        self.tup = (p1,p2)
+    def __getitem__(self,i):
+        return self.tup[i]
+    def __repr__(self):
+        return repr(self.tup[0])
+    def setOffset(self,i):
+        self.tup = (self.tup[0],i)
+
+class ParseResults(object):
+    """
+    Structured parse results, to provide multiple means of access to the parsed data:
+       - as a list (C{len(results)})
+       - by list index (C{results[0], results[1]}, etc.)
+       - by attribute (C{results.<resultsName>} - see L{ParserElement.setResultsName})
+
+    Example::
+        integer = Word(nums)
+        date_str = (integer.setResultsName("year") + '/' 
+                        + integer.setResultsName("month") + '/' 
+                        + integer.setResultsName("day"))
+        # equivalent form:
+        # date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+
+        # parseString returns a ParseResults object
+        result = date_str.parseString("1999/12/31")
+
+        def test(s, fn=repr):
+            print("%s -> %s" % (s, fn(eval(s))))
+        test("list(result)")
+        test("result[0]")
+        test("result['month']")
+        test("result.day")
+        test("'month' in result")
+        test("'minutes' in result")
+        test("result.dump()", str)
+    prints::
+        list(result) -> ['1999', '/', '12', '/', '31']
+        result[0] -> '1999'
+        result['month'] -> '12'
+        result.day -> '31'
+        'month' in result -> True
+        'minutes' in result -> False
+        result.dump() -> ['1999', '/', '12', '/', '31']
+        - day: 31
+        - month: 12
+        - year: 1999
+    """
+    def __new__(cls, toklist=None, name=None, asList=True, modal=True ):
+        if isinstance(toklist, cls):
+            return toklist
+        retobj = object.__new__(cls)
+        retobj.__doinit = True
+        return retobj
+
+    # Performance tuning: we construct a *lot* of these, so keep this
+    # constructor as small and fast as possible
+    def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ):
+        if self.__doinit:
+            self.__doinit = False
+            self.__name = None
+            self.__parent = None
+            self.__accumNames = {}
+            self.__asList = asList
+            self.__modal = modal
+            if toklist is None:
+                toklist = []
+            if isinstance(toklist, list):
+                self.__toklist = toklist[:]
+            elif isinstance(toklist, _generatorType):
+                self.__toklist = list(toklist)
+            else:
+                self.__toklist = [toklist]
+            self.__tokdict = dict()
+
+        if name is not None and name:
+            if not modal:
+                self.__accumNames[name] = 0
+            if isinstance(name,int):
+                name = _ustr(name) # will always return a str, but use _ustr for consistency
+            self.__name = name
+            if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])):
+                if isinstance(toklist,basestring):
+                    toklist = [ toklist ]
+                if asList:
+                    if isinstance(toklist,ParseResults):
+                        self[name] = _ParseResultsWithOffset(toklist.copy(),0)
+                    else:
+                        self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0)
+                    self[name].__name = name
+                else:
+                    try:
+                        self[name] = toklist[0]
+                    except (KeyError,TypeError,IndexError):
+                        self[name] = toklist
+
+    def __getitem__( self, i ):
+        if isinstance( i, (int,slice) ):
+            return self.__toklist[i]
+        else:
+            if i not in self.__accumNames:
+                return self.__tokdict[i][-1][0]
+            else:
+                return ParseResults([ v[0] for v in self.__tokdict[i] ])
+
+    def __setitem__( self, k, v, isinstance=isinstance ):
+        if isinstance(v,_ParseResultsWithOffset):
+            self.__tokdict[k] = self.__tokdict.get(k,list()) + [v]
+            sub = v[0]
+        elif isinstance(k,(int,slice)):
+            self.__toklist[k] = v
+            sub = v
+        else:
+            self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)]
+            sub = v
+        if isinstance(sub,ParseResults):
+            sub.__parent = wkref(self)
+
+    def __delitem__( self, i ):
+        if isinstance(i,(int,slice)):
+            mylen = len( self.__toklist )
+            del self.__toklist[i]
+
+            # convert int to slice
+            if isinstance(i, int):
+                if i < 0:
+                    i += mylen
+                i = slice(i, i+1)
+            # get removed indices
+            removed = list(range(*i.indices(mylen)))
+            removed.reverse()
+            # fixup indices in token dictionary
+            for name,occurrences in self.__tokdict.items():
+                for j in removed:
+                    for k, (value, position) in enumerate(occurrences):
+                        occurrences[k] = _ParseResultsWithOffset(value, position - (position > j))
+        else:
+            del self.__tokdict[i]
+
+    def __contains__( self, k ):
+        return k in self.__tokdict
+
+    def __len__( self ): return len( self.__toklist )
+    def __bool__(self): return ( not not self.__toklist )
+    __nonzero__ = __bool__
+    def __iter__( self ): return iter( self.__toklist )
+    def __reversed__( self ): return iter( self.__toklist[::-1] )
+    def _iterkeys( self ):
+        if hasattr(self.__tokdict, "iterkeys"):
+            return self.__tokdict.iterkeys()
+        else:
+            return iter(self.__tokdict)
+
+    def _itervalues( self ):
+        return (self[k] for k in self._iterkeys())
+            
+    def _iteritems( self ):
+        return ((k, self[k]) for k in self._iterkeys())
+
+    if PY_3:
+        keys = _iterkeys       
+        """Returns an iterator of all named result keys (Python 3.x only)."""
+
+        values = _itervalues
+        """Returns an iterator of all named result values (Python 3.x only)."""
+
+        items = _iteritems
+        """Returns an iterator of all named result key-value tuples (Python 3.x only)."""
+
+    else:
+        iterkeys = _iterkeys
+        """Returns an iterator of all named result keys (Python 2.x only)."""
+
+        itervalues = _itervalues
+        """Returns an iterator of all named result values (Python 2.x only)."""
+
+        iteritems = _iteritems
+        """Returns an iterator of all named result key-value tuples (Python 2.x only)."""
+
+        def keys( self ):
+            """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x)."""
+            return list(self.iterkeys())
+
+        def values( self ):
+            """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x)."""
+            return list(self.itervalues())
+                
+        def items( self ):
+            """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x)."""
+            return list(self.iteritems())
+
+    def haskeys( self ):
+        """Since keys() returns an iterator, this method is helpful in bypassing
+           code that looks for the existence of any defined results names."""
+        return bool(self.__tokdict)
+        
+    def pop( self, *args, **kwargs):
+        """
+        Removes and returns item at specified index (default=C{last}).
+        Supports both C{list} and C{dict} semantics for C{pop()}. If passed no
+        argument or an integer argument, it will use C{list} semantics
+        and pop tokens from the list of parsed tokens. If passed a 
+        non-integer argument (most likely a string), it will use C{dict}
+        semantics and pop the corresponding value from any defined 
+        results names. A second default return value argument is 
+        supported, just as in C{dict.pop()}.
+
+        Example::
+            def remove_first(tokens):
+                tokens.pop(0)
+            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
+            print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321']
+
+            label = Word(alphas)
+            patt = label("LABEL") + OneOrMore(Word(nums))
+            print(patt.parseString("AAB 123 321").dump())
+
+            # Use pop() in a parse action to remove named result (note that corresponding value is not
+            # removed from list form of results)
+            def remove_LABEL(tokens):
+                tokens.pop("LABEL")
+                return tokens
+            patt.addParseAction(remove_LABEL)
+            print(patt.parseString("AAB 123 321").dump())
+        prints::
+            ['AAB', '123', '321']
+            - LABEL: AAB
+
+            ['AAB', '123', '321']
+        """
+        if not args:
+            args = [-1]
+        for k,v in kwargs.items():
+            if k == 'default':
+                args = (args[0], v)
+            else:
+                raise TypeError("pop() got an unexpected keyword argument '%s'" % k)
+        if (isinstance(args[0], int) or 
+                        len(args) == 1 or 
+                        args[0] in self):
+            index = args[0]
+            ret = self[index]
+            del self[index]
+            return ret
+        else:
+            defaultvalue = args[1]
+            return defaultvalue
+
+    def get(self, key, defaultValue=None):
+        """
+        Returns named result matching the given key, or if there is no
+        such name, then returns the given C{defaultValue} or C{None} if no
+        C{defaultValue} is specified.
+
+        Similar to C{dict.get()}.
+        
+        Example::
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
+
+            result = date_str.parseString("1999/12/31")
+            print(result.get("year")) # -> '1999'
+            print(result.get("hour", "not specified")) # -> 'not specified'
+            print(result.get("hour")) # -> None
+        """
+        if key in self:
+            return self[key]
+        else:
+            return defaultValue
+
+    def insert( self, index, insStr ):
+        """
+        Inserts new element at location index in the list of parsed tokens.
+        
+        Similar to C{list.insert()}.
+
+        Example::
+            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
+
+            # use a parse action to insert the parse location in the front of the parsed results
+            def insert_locn(locn, tokens):
+                tokens.insert(0, locn)
+            print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321']
+        """
+        self.__toklist.insert(index, insStr)
+        # fixup indices in token dictionary
+        for name,occurrences in self.__tokdict.items():
+            for k, (value, position) in enumerate(occurrences):
+                occurrences[k] = _ParseResultsWithOffset(value, position + (position > index))
+
+    def append( self, item ):
+        """
+        Add single element to end of ParseResults list of elements.
+
+        Example::
+            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
+            
+            # use a parse action to compute the sum of the parsed integers, and add it to the end
+            def append_sum(tokens):
+                tokens.append(sum(map(int, tokens)))
+            print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444]
+        """
+        self.__toklist.append(item)
+
+    def extend( self, itemseq ):
+        """
+        Add sequence of elements to end of ParseResults list of elements.
+
+        Example::
+            patt = OneOrMore(Word(alphas))
+            
+            # use a parse action to append the reverse of the matched strings, to make a palindrome
+            def make_palindrome(tokens):
+                tokens.extend(reversed([t[::-1] for t in tokens]))
+                return ''.join(tokens)
+            print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl'
+        """
+        if isinstance(itemseq, ParseResults):
+            self += itemseq
+        else:
+            self.__toklist.extend(itemseq)
+
+    def clear( self ):
+        """
+        Clear all elements and results names.
+        """
+        del self.__toklist[:]
+        self.__tokdict.clear()
+
+    def __getattr__( self, name ):
+        try:
+            return self[name]
+        except KeyError:
+            return ""
+            
+        if name in self.__tokdict:
+            if name not in self.__accumNames:
+                return self.__tokdict[name][-1][0]
+            else:
+                return ParseResults([ v[0] for v in self.__tokdict[name] ])
+        else:
+            return ""
+
+    def __add__( self, other ):
+        ret = self.copy()
+        ret += other
+        return ret
+
+    def __iadd__( self, other ):
+        if other.__tokdict:
+            offset = len(self.__toklist)
+            addoffset = lambda a: offset if a<0 else a+offset
+            otheritems = other.__tokdict.items()
+            otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) )
+                                for (k,vlist) in otheritems for v in vlist]
+            for k,v in otherdictitems:
+                self[k] = v
+                if isinstance(v[0],ParseResults):
+                    v[0].__parent = wkref(self)
+            
+        self.__toklist += other.__toklist
+        self.__accumNames.update( other.__accumNames )
+        return self
+
+    def __radd__(self, other):
+        if isinstance(other,int) and other == 0:
+            # useful for merging many ParseResults using sum() builtin
+            return self.copy()
+        else:
+            # this may raise a TypeError - so be it
+            return other + self
+        
+    def __repr__( self ):
+        return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) )
+
+    def __str__( self ):
+        return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']'
+
+    def _asStringList( self, sep='' ):
+        out = []
+        for item in self.__toklist:
+            if out and sep:
+                out.append(sep)
+            if isinstance( item, ParseResults ):
+                out += item._asStringList()
+            else:
+                out.append( _ustr(item) )
+        return out
+
+    def asList( self ):
+        """
+        Returns the parse results as a nested list of matching tokens, all converted to strings.
+
+        Example::
+            patt = OneOrMore(Word(alphas))
+            result = patt.parseString("sldkj lsdkj sldkj")
+            # even though the result prints in string-like form, it is actually a pyparsing ParseResults
+            print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj']
+            
+            # Use asList() to create an actual list
+            result_list = result.asList()
+            print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj']
+        """
+        return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist]
+
+    def asDict( self ):
+        """
+        Returns the named parse results as a nested dictionary.
+
+        Example::
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+            
+            result = date_str.parseString('12/31/1999')
+            print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]})
+            
+            result_dict = result.asDict()
+            print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'}
+
+            # even though a ParseResults supports dict-like access, sometime you just need to have a dict
+            import json
+            print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable
+            print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"}
+        """
+        if PY_3:
+            item_fn = self.items
+        else:
+            item_fn = self.iteritems
+            
+        def toItem(obj):
+            if isinstance(obj, ParseResults):
+                if obj.haskeys():
+                    return obj.asDict()
+                else:
+                    return [toItem(v) for v in obj]
+            else:
+                return obj
+                
+        return dict((k,toItem(v)) for k,v in item_fn())
+
+    def copy( self ):
+        """
+        Returns a new copy of a C{ParseResults} object.
+        """
+        ret = ParseResults( self.__toklist )
+        ret.__tokdict = self.__tokdict.copy()
+        ret.__parent = self.__parent
+        ret.__accumNames.update( self.__accumNames )
+        ret.__name = self.__name
+        return ret
+
+    def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ):
+        """
+        (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names.
+        """
+        nl = "\n"
+        out = []
+        namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items()
+                                                            for v in vlist)
+        nextLevelIndent = indent + "  "
+
+        # collapse out indents if formatting is not desired
+        if not formatted:
+            indent = ""
+            nextLevelIndent = ""
+            nl = ""
+
+        selfTag = None
+        if doctag is not None:
+            selfTag = doctag
+        else:
+            if self.__name:
+                selfTag = self.__name
+
+        if not selfTag:
+            if namedItemsOnly:
+                return ""
+            else:
+                selfTag = "ITEM"
+
+        out += [ nl, indent, "<", selfTag, ">" ]
+
+        for i,res in enumerate(self.__toklist):
+            if isinstance(res,ParseResults):
+                if i in namedItems:
+                    out += [ res.asXML(namedItems[i],
+                                        namedItemsOnly and doctag is None,
+                                        nextLevelIndent,
+                                        formatted)]
+                else:
+                    out += [ res.asXML(None,
+                                        namedItemsOnly and doctag is None,
+                                        nextLevelIndent,
+                                        formatted)]
+            else:
+                # individual token, see if there is a name for it
+                resTag = None
+                if i in namedItems:
+                    resTag = namedItems[i]
+                if not resTag:
+                    if namedItemsOnly:
+                        continue
+                    else:
+                        resTag = "ITEM"
+                xmlBodyText = _xml_escape(_ustr(res))
+                out += [ nl, nextLevelIndent, "<", resTag, ">",
+                                                xmlBodyText,
+                                                "</", resTag, ">" ]
+
+        out += [ nl, indent, "</", selfTag, ">" ]
+        return "".join(out)
+
+    def __lookup(self,sub):
+        for k,vlist in self.__tokdict.items():
+            for v,loc in vlist:
+                if sub is v:
+                    return k
+        return None
+
+    def getName(self):
+        """
+        Returns the results name for this token expression. Useful when several 
+        different expressions might match at a particular location.
+
+        Example::
+            integer = Word(nums)
+            ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d")
+            house_number_expr = Suppress('#') + Word(nums, alphanums)
+            user_data = (Group(house_number_expr)("house_number") 
+                        | Group(ssn_expr)("ssn")
+                        | Group(integer)("age"))
+            user_info = OneOrMore(user_data)
+            
+            result = user_info.parseString("22 111-22-3333 #221B")
+            for item in result:
+                print(item.getName(), ':', item[0])
+        prints::
+            age : 22
+            ssn : 111-22-3333
+            house_number : 221B
+        """
+        if self.__name:
+            return self.__name
+        elif self.__parent:
+            par = self.__parent()
+            if par:
+                return par.__lookup(self)
+            else:
+                return None
+        elif (len(self) == 1 and
+               len(self.__tokdict) == 1 and
+               next(iter(self.__tokdict.values()))[0][1] in (0,-1)):
+            return next(iter(self.__tokdict.keys()))
+        else:
+            return None
+
+    def dump(self, indent='', depth=0, full=True):
+        """
+        Diagnostic method for listing out the contents of a C{ParseResults}.
+        Accepts an optional C{indent} argument so that this string can be embedded
+        in a nested display of other data.
+
+        Example::
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+            
+            result = date_str.parseString('12/31/1999')
+            print(result.dump())
+        prints::
+            ['12', '/', '31', '/', '1999']
+            - day: 1999
+            - month: 31
+            - year: 12
+        """
+        out = []
+        NL = '\n'
+        out.append( indent+_ustr(self.asList()) )
+        if full:
+            if self.haskeys():
+                items = sorted((str(k), v) for k,v in self.items())
+                for k,v in items:
+                    if out:
+                        out.append(NL)
+                    out.append( "%s%s- %s: " % (indent,('  '*depth), k) )
+                    if isinstance(v,ParseResults):
+                        if v:
+                            out.append( v.dump(indent,depth+1) )
+                        else:
+                            out.append(_ustr(v))
+                    else:
+                        out.append(repr(v))
+            elif any(isinstance(vv,ParseResults) for vv in self):
+                v = self
+                for i,vv in enumerate(v):
+                    if isinstance(vv,ParseResults):
+                        out.append("\n%s%s[%d]:\n%s%s%s" % (indent,('  '*(depth)),i,indent,('  '*(depth+1)),vv.dump(indent,depth+1) ))
+                    else:
+                        out.append("\n%s%s[%d]:\n%s%s%s" % (indent,('  '*(depth)),i,indent,('  '*(depth+1)),_ustr(vv)))
+            
+        return "".join(out)
+
+    def pprint(self, *args, **kwargs):
+        """
+        Pretty-printer for parsed results as a list, using the C{pprint} module.
+        Accepts additional positional or keyword args as defined for the 
+        C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint})
+
+        Example::
+            ident = Word(alphas, alphanums)
+            num = Word(nums)
+            func = Forward()
+            term = ident | num | Group('(' + func + ')')
+            func <<= ident + Group(Optional(delimitedList(term)))
+            result = func.parseString("fna a,b,(fnb c,d,200),100")
+            result.pprint(width=40)
+        prints::
+            ['fna',
+             ['a',
+              'b',
+              ['(', 'fnb', ['c', 'd', '200'], ')'],
+              '100']]
+        """
+        pprint.pprint(self.asList(), *args, **kwargs)
+
+    # add support for pickle protocol
+    def __getstate__(self):
+        return ( self.__toklist,
+                 ( self.__tokdict.copy(),
+                   self.__parent is not None and self.__parent() or None,
+                   self.__accumNames,
+                   self.__name ) )
+
+    def __setstate__(self,state):
+        self.__toklist = state[0]
+        (self.__tokdict,
+         par,
+         inAccumNames,
+         self.__name) = state[1]
+        self.__accumNames = {}
+        self.__accumNames.update(inAccumNames)
+        if par is not None:
+            self.__parent = wkref(par)
+        else:
+            self.__parent = None
+
+    def __getnewargs__(self):
+        return self.__toklist, self.__name, self.__asList, self.__modal
+
+    def __dir__(self):
+        return (dir(type(self)) + list(self.keys()))
+
+collections.MutableMapping.register(ParseResults)
+
+def col (loc,strg):
+    """Returns current column within a string, counting newlines as line separators.
+   The first column is number 1.
+
+   Note: the default parsing behavior is to expand tabs in the input string
+   before starting the parsing process.  See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information
+   on parsing strings containing C{<TAB>}s, and suggested methods to maintain a
+   consistent view of the parsed string, the parse location, and line and column
+   positions within the parsed string.
+   """
+    s = strg
+    return 1 if 0<loc<len(s) and s[loc-1] == '\n' else loc - s.rfind("\n", 0, loc)
+
+def lineno(loc,strg):
+    """Returns current line number within a string, counting newlines as line separators.
+   The first line is number 1.
+
+   Note: the default parsing behavior is to expand tabs in the input string
+   before starting the parsing process.  See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information
+   on parsing strings containing C{<TAB>}s, and suggested methods to maintain a
+   consistent view of the parsed string, the parse location, and line and column
+   positions within the parsed string.
+   """
+    return strg.count("\n",0,loc) + 1
+
+def line( loc, strg ):
+    """Returns the line of text containing loc within a string, counting newlines as line separators.
+       """
+    lastCR = strg.rfind("\n", 0, loc)
+    nextCR = strg.find("\n", loc)
+    if nextCR >= 0:
+        return strg[lastCR+1:nextCR]
+    else:
+        return strg[lastCR+1:]
+
+def _defaultStartDebugAction( instring, loc, expr ):
+    print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )))
+
+def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ):
+    print ("Matched " + _ustr(expr) + " -> " + str(toks.asList()))
+
+def _defaultExceptionDebugAction( instring, loc, expr, exc ):
+    print ("Exception raised:" + _ustr(exc))
+
+def nullDebugAction(*args):
+    """'Do-nothing' debug action, to suppress debugging output during parsing."""
+    pass
+
+# Only works on Python 3.x - nonlocal is toxic to Python 2 installs
+#~ 'decorator to trim function calls to match the arity of the target'
+#~ def _trim_arity(func, maxargs=3):
+    #~ if func in singleArgBuiltins:
+        #~ return lambda s,l,t: func(t)
+    #~ limit = 0
+    #~ foundArity = False
+    #~ def wrapper(*args):
+        #~ nonlocal limit,foundArity
+        #~ while 1:
+            #~ try:
+                #~ ret = func(*args[limit:])
+                #~ foundArity = True
+                #~ return ret
+            #~ except TypeError:
+                #~ if limit == maxargs or foundArity:
+                    #~ raise
+                #~ limit += 1
+                #~ continue
+    #~ return wrapper
+
+# this version is Python 2.x-3.x cross-compatible
+'decorator to trim function calls to match the arity of the target'
+def _trim_arity(func, maxargs=2):
+    if func in singleArgBuiltins:
+        return lambda s,l,t: func(t)
+    limit = [0]
+    foundArity = [False]
+    
+    # traceback return data structure changed in Py3.5 - normalize back to plain tuples
+    if system_version[:2] >= (3,5):
+        def extract_stack(limit=0):
+            # special handling for Python 3.5.0 - extra deep call stack by 1
+            offset = -3 if system_version == (3,5,0) else -2
+            frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset]
+            return [(frame_summary.filename, frame_summary.lineno)]
+        def extract_tb(tb, limit=0):
+            frames = traceback.extract_tb(tb, limit=limit)
+            frame_summary = frames[-1]
+            return [(frame_summary.filename, frame_summary.lineno)]
+    else:
+        extract_stack = traceback.extract_stack
+        extract_tb = traceback.extract_tb
+    
+    # synthesize what would be returned by traceback.extract_stack at the call to 
+    # user's parse action 'func', so that we don't incur call penalty at parse time
+    
+    LINE_DIFF = 6
+    # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND 
+    # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!!
+    this_line = extract_stack(limit=2)[-1]
+    pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF)
+
+    def wrapper(*args):
+        while 1:
+            try:
+                ret = func(*args[limit[0]:])
+                foundArity[0] = True
+                return ret
+            except TypeError:
+                # re-raise TypeErrors if they did not come from our arity testing
+                if foundArity[0]:
+                    raise
+                else:
+                    try:
+                        tb = sys.exc_info()[-1]
+                        if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth:
+                            raise
+                    finally:
+                        del tb
+
+                if limit[0] <= maxargs:
+                    limit[0] += 1
+                    continue
+                raise
+
+    # copy func name to wrapper for sensible debug output
+    func_name = "<parse action>"
+    try:
+        func_name = getattr(func, '__name__', 
+                            getattr(func, '__class__').__name__)
+    except Exception:
+        func_name = str(func)
+    wrapper.__name__ = func_name
+
+    return wrapper
+
+class ParserElement(object):
+    """Abstract base level parser element class."""
+    DEFAULT_WHITE_CHARS = " \n\t\r"
+    verbose_stacktrace = False
+
+    @staticmethod
+    def setDefaultWhitespaceChars( chars ):
+        r"""
+        Overrides the default whitespace chars
+
+        Example::
+            # default whitespace chars are space, <TAB> and newline
+            OneOrMore(Word(alphas)).parseString("abc def\nghi jkl")  # -> ['abc', 'def', 'ghi', 'jkl']
+            
+            # change to just treat newline as significant
+            ParserElement.setDefaultWhitespaceChars(" \t")
+            OneOrMore(Word(alphas)).parseString("abc def\nghi jkl")  # -> ['abc', 'def']
+        """
+        ParserElement.DEFAULT_WHITE_CHARS = chars
+
+    @staticmethod
+    def inlineLiteralsUsing(cls):
+        """
+        Set class to be used for inclusion of string literals into a parser.
+        
+        Example::
+            # default literal class used is Literal
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
+
+            date_str.parseString("1999/12/31")  # -> ['1999', '/', '12', '/', '31']
+
+
+            # change to Suppress
+            ParserElement.inlineLiteralsUsing(Suppress)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
+
+            date_str.parseString("1999/12/31")  # -> ['1999', '12', '31']
+        """
+        ParserElement._literalStringClass = cls
+
+    def __init__( self, savelist=False ):
+        self.parseAction = list()
+        self.failAction = None
+        #~ self.name = "<unknown>"  # don't define self.name, let subclasses try/except upcall
+        self.strRepr = None
+        self.resultsName = None
+        self.saveAsList = savelist
+        self.skipWhitespace = True
+        self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
+        self.copyDefaultWhiteChars = True
+        self.mayReturnEmpty = False # used when checking for left-recursion
+        self.keepTabs = False
+        self.ignoreExprs = list()
+        self.debug = False
+        self.streamlined = False
+        self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index
+        self.errmsg = ""
+        self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all)
+        self.debugActions = ( None, None, None ) #custom debug actions
+        self.re = None
+        self.callPreparse = True # used to avoid redundant calls to preParse
+        self.callDuringTry = False
+
+    def copy( self ):
+        """
+        Make a copy of this C{ParserElement}.  Useful for defining different parse actions
+        for the same parsing pattern, using copies of the original parse element.
+        
+        Example::
+            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
+            integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K")
+            integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
+            
+            print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M"))
+        prints::
+            [5120, 100, 655360, 268435456]
+        Equivalent form of C{expr.copy()} is just C{expr()}::
+            integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
+        """
+        cpy = copy.copy( self )
+        cpy.parseAction = self.parseAction[:]
+        cpy.ignoreExprs = self.ignoreExprs[:]
+        if self.copyDefaultWhiteChars:
+            cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
+        return cpy
+
+    def setName( self, name ):
+        """
+        Define name for this expression, makes debugging and exception messages clearer.
+        
+        Example::
+            Word(nums).parseString("ABC")  # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1)
+            Word(nums).setName("integer").parseString("ABC")  # -> Exception: Expected integer (at char 0), (line:1, col:1)
+        """
+        self.name = name
+        self.errmsg = "Expected " + self.name
+        if hasattr(self,"exception"):
+            self.exception.msg = self.errmsg
+        return self
+
+    def setResultsName( self, name, listAllMatches=False ):
+        """
+        Define name for referencing matching tokens as a nested attribute
+        of the returned parse results.
+        NOTE: this returns a *copy* of the original C{ParserElement} object;
+        this is so that the client can define a basic element, such as an
+        integer, and reference it in multiple places with different names.
+
+        You can also set results names using the abbreviated syntax,
+        C{expr("name")} in place of C{expr.setResultsName("name")} - 
+        see L{I{__call__}<__call__>}.
+
+        Example::
+            date_str = (integer.setResultsName("year") + '/' 
+                        + integer.setResultsName("month") + '/' 
+                        + integer.setResultsName("day"))
+
+            # equivalent form:
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+        """
+        newself = self.copy()
+        if name.endswith("*"):
+            name = name[:-1]
+            listAllMatches=True
+        newself.resultsName = name
+        newself.modalResults = not listAllMatches
+        return newself
+
+    def setBreak(self,breakFlag = True):
+        """Method to invoke the Python pdb debugger when this element is
+           about to be parsed. Set C{breakFlag} to True to enable, False to
+           disable.
+        """
+        if breakFlag:
+            _parseMethod = self._parse
+            def breaker(instring, loc, doActions=True, callPreParse=True):
+                import pdb
+                pdb.set_trace()
+                return _parseMethod( instring, loc, doActions, callPreParse )
+            breaker._originalParseMethod = _parseMethod
+            self._parse = breaker
+        else:
+            if hasattr(self._parse,"_originalParseMethod"):
+                self._parse = self._parse._originalParseMethod
+        return self
+
+    def setParseAction( self, *fns, **kwargs ):
+        """
+        Define action to perform when successfully matching parse element definition.
+        Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)},
+        C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where:
+         - s   = the original string being parsed (see note below)
+         - loc = the location of the matching substring
+         - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object
+        If the functions in fns modify the tokens, they can return them as the return
+        value from fn, and the modified list of tokens will replace the original.
+        Otherwise, fn does not need to return any value.
+
+        Optional keyword arguments:
+         - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing
+
+        Note: the default parsing behavior is to expand tabs in the input string
+        before starting the parsing process.  See L{I{parseString}<parseString>} for more information
+        on parsing strings containing C{<TAB>}s, and suggested methods to maintain a
+        consistent view of the parsed string, the parse location, and line and column
+        positions within the parsed string.
+        
+        Example::
+            integer = Word(nums)
+            date_str = integer + '/' + integer + '/' + integer
+
+            date_str.parseString("1999/12/31")  # -> ['1999', '/', '12', '/', '31']
+
+            # use parse action to convert to ints at parse time
+            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
+            date_str = integer + '/' + integer + '/' + integer
+
+            # note that integer fields are now ints, not strings
+            date_str.parseString("1999/12/31")  # -> [1999, '/', 12, '/', 31]
+        """
+        self.parseAction = list(map(_trim_arity, list(fns)))
+        self.callDuringTry = kwargs.get("callDuringTry", False)
+        return self
+
+    def addParseAction( self, *fns, **kwargs ):
+        """
+        Add parse action to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}.
+        
+        See examples in L{I{copy}<copy>}.
+        """
+        self.parseAction += list(map(_trim_arity, list(fns)))
+        self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False)
+        return self
+
+    def addCondition(self, *fns, **kwargs):
+        """Add a boolean predicate function to expression's list of parse actions. See 
+        L{I{setParseAction}<setParseAction>} for function call signatures. Unlike C{setParseAction}, 
+        functions passed to C{addCondition} need to return boolean success/fail of the condition.
+
+        Optional keyword arguments:
+         - message = define a custom message to be used in the raised exception
+         - fatal   = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException
+         
+        Example::
+            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
+            year_int = integer.copy()
+            year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later")
+            date_str = year_int + '/' + integer + '/' + integer
+
+            result = date_str.parseString("1999/12/31")  # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1)
+        """
+        msg = kwargs.get("message", "failed user-defined condition")
+        exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException
+        for fn in fns:
+            def pa(s,l,t):
+                if not bool(_trim_arity(fn)(s,l,t)):
+                    raise exc_type(s,l,msg)
+            self.parseAction.append(pa)
+        self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False)
+        return self
+
+    def setFailAction( self, fn ):
+        """Define action to perform if parsing fails at this expression.
+           Fail acton fn is a callable function that takes the arguments
+           C{fn(s,loc,expr,err)} where:
+            - s = string being parsed
+            - loc = location where expression match was attempted and failed
+            - expr = the parse expression that failed
+            - err = the exception thrown
+           The function returns no value.  It may throw C{L{ParseFatalException}}
+           if it is desired to stop parsing immediately."""
+        self.failAction = fn
+        return self
+
+    def _skipIgnorables( self, instring, loc ):
+        exprsFound = True
+        while exprsFound:
+            exprsFound = False
+            for e in self.ignoreExprs:
+                try:
+                    while 1:
+                        loc,dummy = e._parse( instring, loc )
+                        exprsFound = True
+                except ParseException:
+                    pass
+        return loc
+
+    def preParse( self, instring, loc ):
+        if self.ignoreExprs:
+            loc = self._skipIgnorables( instring, loc )
+
+        if self.skipWhitespace:
+            wt = self.whiteChars
+            instrlen = len(instring)
+            while loc < instrlen and instring[loc] in wt:
+                loc += 1
+
+        return loc
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        return loc, []
+
+    def postParse( self, instring, loc, tokenlist ):
+        return tokenlist
+
+    #~ @profile
+    def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ):
+        debugging = ( self.debug ) #and doActions )
+
+        if debugging or self.failAction:
+            #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))
+            if (self.debugActions[0] ):
+                self.debugActions[0]( instring, loc, self )
+            if callPreParse and self.callPreparse:
+                preloc = self.preParse( instring, loc )
+            else:
+                preloc = loc
+            tokensStart = preloc
+            try:
+                try:
+                    loc,tokens = self.parseImpl( instring, preloc, doActions )
+                except IndexError:
+                    raise ParseException( instring, len(instring), self.errmsg, self )
+            except ParseBaseException as err:
+                #~ print ("Exception raised:", err)
+                if self.debugActions[2]:
+                    self.debugActions[2]( instring, tokensStart, self, err )
+                if self.failAction:
+                    self.failAction( instring, tokensStart, self, err )
+                raise
+        else:
+            if callPreParse and self.callPreparse:
+                preloc = self.preParse( instring, loc )
+            else:
+                preloc = loc
+            tokensStart = preloc
+            if self.mayIndexError or loc >= len(instring):
+                try:
+                    loc,tokens = self.parseImpl( instring, preloc, doActions )
+                except IndexError:
+                    raise ParseException( instring, len(instring), self.errmsg, self )
+            else:
+                loc,tokens = self.parseImpl( instring, preloc, doActions )
+
+        tokens = self.postParse( instring, loc, tokens )
+
+        retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults )
+        if self.parseAction and (doActions or self.callDuringTry):
+            if debugging:
+                try:
+                    for fn in self.parseAction:
+                        tokens = fn( instring, tokensStart, retTokens )
+                        if tokens is not None:
+                            retTokens = ParseResults( tokens,
+                                                      self.resultsName,
+                                                      asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
+                                                      modal=self.modalResults )
+                except ParseBaseException as err:
+                    #~ print "Exception raised in user parse action:", err
+                    if (self.debugActions[2] ):
+                        self.debugActions[2]( instring, tokensStart, self, err )
+                    raise
+            else:
+                for fn in self.parseAction:
+                    tokens = fn( instring, tokensStart, retTokens )
+                    if tokens is not None:
+                        retTokens = ParseResults( tokens,
+                                                  self.resultsName,
+                                                  asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
+                                                  modal=self.modalResults )
+
+        if debugging:
+            #~ print ("Matched",self,"->",retTokens.asList())
+            if (self.debugActions[1] ):
+                self.debugActions[1]( instring, tokensStart, loc, self, retTokens )
+
+        return loc, retTokens
+
+    def tryParse( self, instring, loc ):
+        try:
+            return self._parse( instring, loc, doActions=False )[0]
+        except ParseFatalException:
+            raise ParseException( instring, loc, self.errmsg, self)
+    
+    def canParseNext(self, instring, loc):
+        try:
+            self.tryParse(instring, loc)
+        except (ParseException, IndexError):
+            return False
+        else:
+            return True
+
+    class _UnboundedCache(object):
+        def __init__(self):
+            cache = {}
+            self.not_in_cache = not_in_cache = object()
+
+            def get(self, key):
+                return cache.get(key, not_in_cache)
+
+            def set(self, key, value):
+                cache[key] = value
+
+            def clear(self):
+                cache.clear()
+
+            self.get = types.MethodType(get, self)
+            self.set = types.MethodType(set, self)
+            self.clear = types.MethodType(clear, self)
+
+    if _OrderedDict is not None:
+        class _FifoCache(object):
+            def __init__(self, size):
+                self.not_in_cache = not_in_cache = object()
+
+                cache = _OrderedDict()
+
+                def get(self, key):
+                    return cache.get(key, not_in_cache)
+
+                def set(self, key, value):
+                    cache[key] = value
+                    if len(cache) > size:
+                        cache.popitem(False)
+
+                def clear(self):
+                    cache.clear()
+
+                self.get = types.MethodType(get, self)
+                self.set = types.MethodType(set, self)
+                self.clear = types.MethodType(clear, self)
+
+    else:
+        class _FifoCache(object):
+            def __init__(self, size):
+                self.not_in_cache = not_in_cache = object()
+
+                cache = {}
+                key_fifo = collections.deque([], size)
+
+                def get(self, key):
+                    return cache.get(key, not_in_cache)
+
+                def set(self, key, value):
+                    cache[key] = value
+                    if len(cache) > size:
+                        cache.pop(key_fifo.popleft(), None)
+                    key_fifo.append(key)
+
+                def clear(self):
+                    cache.clear()
+                    key_fifo.clear()
+
+                self.get = types.MethodType(get, self)
+                self.set = types.MethodType(set, self)
+                self.clear = types.MethodType(clear, self)
+
+    # argument cache for optimizing repeated calls when backtracking through recursive expressions
+    packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail
+    packrat_cache_lock = RLock()
+    packrat_cache_stats = [0, 0]
+
+    # this method gets repeatedly called during backtracking with the same arguments -
+    # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression
+    def _parseCache( self, instring, loc, doActions=True, callPreParse=True ):
+        HIT, MISS = 0, 1
+        lookup = (self, instring, loc, callPreParse, doActions)
+        with ParserElement.packrat_cache_lock:
+            cache = ParserElement.packrat_cache
+            value = cache.get(lookup)
+            if value is cache.not_in_cache:
+                ParserElement.packrat_cache_stats[MISS] += 1
+                try:
+                    value = self._parseNoCache(instring, loc, doActions, callPreParse)
+                except ParseBaseException as pe:
+                    # cache a copy of the exception, without the traceback
+                    cache.set(lookup, pe.__class__(*pe.args))
+                    raise
+                else:
+                    cache.set(lookup, (value[0], value[1].copy()))
+                    return value
+            else:
+                ParserElement.packrat_cache_stats[HIT] += 1
+                if isinstance(value, Exception):
+                    raise value
+                return (value[0], value[1].copy())
+
+    _parse = _parseNoCache
+
+    @staticmethod
+    def resetCache():
+        ParserElement.packrat_cache.clear()
+        ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats)
+
+    _packratEnabled = False
+    @staticmethod
+    def enablePackrat(cache_size_limit=128):
+        """Enables "packrat" parsing, which adds memoizing to the parsing logic.
+           Repeated parse attempts at the same string location (which happens
+           often in many complex grammars) can immediately return a cached value,
+           instead of re-executing parsing/validating code.  Memoizing is done of
+           both valid results and parsing exceptions.
+           
+           Parameters:
+            - cache_size_limit - (default=C{128}) - if an integer value is provided
+              will limit the size of the packrat cache; if None is passed, then
+              the cache size will be unbounded; if 0 is passed, the cache will
+              be effectively disabled.
+            
+           This speedup may break existing programs that use parse actions that
+           have side-effects.  For this reason, packrat parsing is disabled when
+           you first import pyparsing.  To activate the packrat feature, your
+           program must call the class method C{ParserElement.enablePackrat()}.  If
+           your program uses C{psyco} to "compile as you go", you must call
+           C{enablePackrat} before calling C{psyco.full()}.  If you do not do this,
+           Python will crash.  For best results, call C{enablePackrat()} immediately
+           after importing pyparsing.
+           
+           Example::
+               import pyparsing
+               pyparsing.ParserElement.enablePackrat()
+        """
+        if not ParserElement._packratEnabled:
+            ParserElement._packratEnabled = True
+            if cache_size_limit is None:
+                ParserElement.packrat_cache = ParserElement._UnboundedCache()
+            else:
+                ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit)
+            ParserElement._parse = ParserElement._parseCache
+
+    def parseString( self, instring, parseAll=False ):
+        """
+        Execute the parse expression with the given string.
+        This is the main interface to the client code, once the complete
+        expression has been built.
+
+        If you want the grammar to require that the entire input string be
+        successfully parsed, then set C{parseAll} to True (equivalent to ending
+        the grammar with C{L{StringEnd()}}).
+
+        Note: C{parseString} implicitly calls C{expandtabs()} on the input string,
+        in order to report proper column numbers in parse actions.
+        If the input string contains tabs and
+        the grammar uses parse actions that use the C{loc} argument to index into the
+        string being parsed, you can ensure you have a consistent view of the input
+        string by:
+         - calling C{parseWithTabs} on your grammar before calling C{parseString}
+           (see L{I{parseWithTabs}<parseWithTabs>})
+         - define your parse action using the full C{(s,loc,toks)} signature, and
+           reference the input string using the parse action's C{s} argument
+         - explictly expand the tabs in your input string before calling
+           C{parseString}
+        
+        Example::
+            Word('a').parseString('aaaaabaaa')  # -> ['aaaaa']
+            Word('a').parseString('aaaaabaaa', parseAll=True)  # -> Exception: Expected end of text
+        """
+        ParserElement.resetCache()
+        if not self.streamlined:
+            self.streamline()
+            #~ self.saveAsList = True
+        for e in self.ignoreExprs:
+            e.streamline()
+        if not self.keepTabs:
+            instring = instring.expandtabs()
+        try:
+            loc, tokens = self._parse( instring, 0 )
+            if parseAll:
+                loc = self.preParse( instring, loc )
+                se = Empty() + StringEnd()
+                se._parse( instring, loc )
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+        else:
+            return tokens
+
+    def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ):
+        """
+        Scan the input string for expression matches.  Each match will return the
+        matching tokens, start location, and end location.  May be called with optional
+        C{maxMatches} argument, to clip scanning after 'n' matches are found.  If
+        C{overlap} is specified, then overlapping matches will be reported.
+
+        Note that the start and end locations are reported relative to the string
+        being parsed.  See L{I{parseString}<parseString>} for more information on parsing
+        strings with embedded tabs.
+
+        Example::
+            source = "sldjf123lsdjjkf345sldkjf879lkjsfd987"
+            print(source)
+            for tokens,start,end in Word(alphas).scanString(source):
+                print(' '*start + '^'*(end-start))
+                print(' '*start + tokens[0])
+        
+        prints::
+        
+            sldjf123lsdjjkf345sldkjf879lkjsfd987
+            ^^^^^
+            sldjf
+                    ^^^^^^^
+                    lsdjjkf
+                              ^^^^^^
+                              sldkjf
+                                       ^^^^^^
+                                       lkjsfd
+        """
+        if not self.streamlined:
+            self.streamline()
+        for e in self.ignoreExprs:
+            e.streamline()
+
+        if not self.keepTabs:
+            instring = _ustr(instring).expandtabs()
+        instrlen = len(instring)
+        loc = 0
+        preparseFn = self.preParse
+        parseFn = self._parse
+        ParserElement.resetCache()
+        matches = 0
+        try:
+            while loc <= instrlen and matches < maxMatches:
+                try:
+                    preloc = preparseFn( instring, loc )
+                    nextLoc,tokens = parseFn( instring, preloc, callPreParse=False )
+                except ParseException:
+                    loc = preloc+1
+                else:
+                    if nextLoc > loc:
+                        matches += 1
+                        yield tokens, preloc, nextLoc
+                        if overlap:
+                            nextloc = preparseFn( instring, loc )
+                            if nextloc > loc:
+                                loc = nextLoc
+                            else:
+                                loc += 1
+                        else:
+                            loc = nextLoc
+                    else:
+                        loc = preloc+1
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def transformString( self, instring ):
+        """
+        Extension to C{L{scanString}}, to modify matching text with modified tokens that may
+        be returned from a parse action.  To use C{transformString}, define a grammar and
+        attach a parse action to it that modifies the returned token list.
+        Invoking C{transformString()} on a target string will then scan for matches,
+        and replace the matched text patterns according to the logic in the parse
+        action.  C{transformString()} returns the resulting transformed string.
+        
+        Example::
+            wd = Word(alphas)
+            wd.setParseAction(lambda toks: toks[0].title())
+            
+            print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york."))
+        Prints::
+            Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York.
+        """
+        out = []
+        lastE = 0
+        # force preservation of <TAB>s, to minimize unwanted transformation of string, and to
+        # keep string locs straight between transformString and scanString
+        self.keepTabs = True
+        try:
+            for t,s,e in self.scanString( instring ):
+                out.append( instring[lastE:s] )
+                if t:
+                    if isinstance(t,ParseResults):
+                        out += t.asList()
+                    elif isinstance(t,list):
+                        out += t
+                    else:
+                        out.append(t)
+                lastE = e
+            out.append(instring[lastE:])
+            out = [o for o in out if o]
+            return "".join(map(_ustr,_flatten(out)))
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def searchString( self, instring, maxMatches=_MAX_INT ):
+        """
+        Another extension to C{L{scanString}}, simplifying the access to the tokens found
+        to match the given parse expression.  May be called with optional
+        C{maxMatches} argument, to clip searching after 'n' matches are found.
+        
+        Example::
+            # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters
+            cap_word = Word(alphas.upper(), alphas.lower())
+            
+            print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))
+        prints::
+            ['More', 'Iron', 'Lead', 'Gold', 'I']
+        """
+        try:
+            return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ])
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False):
+        """
+        Generator method to split a string using the given expression as a separator.
+        May be called with optional C{maxsplit} argument, to limit the number of splits;
+        and the optional C{includeSeparators} argument (default=C{False}), if the separating
+        matching text should be included in the split results.
+        
+        Example::        
+            punc = oneOf(list(".,;:/-!?"))
+            print(list(punc.split("This, this?, this sentence, is badly punctuated!")))
+        prints::
+            ['This', ' this', '', ' this sentence', ' is badly punctuated', '']
+        """
+        splits = 0
+        last = 0
+        for t,s,e in self.scanString(instring, maxMatches=maxsplit):
+            yield instring[last:s]
+            if includeSeparators:
+                yield t[0]
+            last = e
+        yield instring[last:]
+
+    def __add__(self, other ):
+        """
+        Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement
+        converts them to L{Literal}s by default.
+        
+        Example::
+            greet = Word(alphas) + "," + Word(alphas) + "!"
+            hello = "Hello, World!"
+            print (hello, "->", greet.parseString(hello))
+        Prints::
+            Hello, World! -> ['Hello', ',', 'World', '!']
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return And( [ self, other ] )
+
+    def __radd__(self, other ):
+        """
+        Implementation of + operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other + self
+
+    def __sub__(self, other):
+        """
+        Implementation of - operator, returns C{L{And}} with error stop
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return And( [ self, And._ErrorStop(), other ] )
+
+    def __rsub__(self, other ):
+        """
+        Implementation of - operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other - self
+
+    def __mul__(self,other):
+        """
+        Implementation of * operator, allows use of C{expr * 3} in place of
+        C{expr + expr + expr}.  Expressions may also me multiplied by a 2-integer
+        tuple, similar to C{{min,max}} multipliers in regular expressions.  Tuples
+        may also include C{None} as in:
+         - C{expr*(n,None)} or C{expr*(n,)} is equivalent
+              to C{expr*n + L{ZeroOrMore}(expr)}
+              (read as "at least n instances of C{expr}")
+         - C{expr*(None,n)} is equivalent to C{expr*(0,n)}
+              (read as "0 to n instances of C{expr}")
+         - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)}
+         - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)}
+
+        Note that C{expr*(None,n)} does not raise an exception if
+        more than n exprs exist in the input stream; that is,
+        C{expr*(None,n)} does not enforce a maximum number of expr
+        occurrences.  If this behavior is desired, then write
+        C{expr*(None,n) + ~expr}
+        """
+        if isinstance(other,int):
+            minElements, optElements = other,0
+        elif isinstance(other,tuple):
+            other = (other + (None, None))[:2]
+            if other[0] is None:
+                other = (0, other[1])
+            if isinstance(other[0],int) and other[1] is None:
+                if other[0] == 0:
+                    return ZeroOrMore(self)
+                if other[0] == 1:
+                    return OneOrMore(self)
+                else:
+                    return self*other[0] + ZeroOrMore(self)
+            elif isinstance(other[0],int) and isinstance(other[1],int):
+                minElements, optElements = other
+                optElements -= minElements
+            else:
+                raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1]))
+        else:
+            raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other))
+
+        if minElements < 0:
+            raise ValueError("cannot multiply ParserElement by negative value")
+        if optElements < 0:
+            raise ValueError("second tuple value must be greater or equal to first tuple value")
+        if minElements == optElements == 0:
+            raise ValueError("cannot multiply ParserElement by 0 or (0,0)")
+
+        if (optElements):
+            def makeOptionalList(n):
+                if n>1:
+                    return Optional(self + makeOptionalList(n-1))
+                else:
+                    return Optional(self)
+            if minElements:
+                if minElements == 1:
+                    ret = self + makeOptionalList(optElements)
+                else:
+                    ret = And([self]*minElements) + makeOptionalList(optElements)
+            else:
+                ret = makeOptionalList(optElements)
+        else:
+            if minElements == 1:
+                ret = self
+            else:
+                ret = And([self]*minElements)
+        return ret
+
+    def __rmul__(self, other):
+        return self.__mul__(other)
+
+    def __or__(self, other ):
+        """
+        Implementation of | operator - returns C{L{MatchFirst}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return MatchFirst( [ self, other ] )
+
+    def __ror__(self, other ):
+        """
+        Implementation of | operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other | self
+
+    def __xor__(self, other ):
+        """
+        Implementation of ^ operator - returns C{L{Or}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return Or( [ self, other ] )
+
+    def __rxor__(self, other ):
+        """
+        Implementation of ^ operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other ^ self
+
+    def __and__(self, other ):
+        """
+        Implementation of & operator - returns C{L{Each}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return Each( [ self, other ] )
+
+    def __rand__(self, other ):
+        """
+        Implementation of & operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other & self
+
+    def __invert__( self ):
+        """
+        Implementation of ~ operator - returns C{L{NotAny}}
+        """
+        return NotAny( self )
+
+    def __call__(self, name=None):
+        """
+        Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}.
+        
+        If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be
+        passed as C{True}.
+           
+        If C{name} is omitted, same as calling C{L{copy}}.
+
+        Example::
+            # these are equivalent
+            userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno")
+            userdata = Word(alphas)("name") + Word(nums+"-")("socsecno")             
+        """
+        if name is not None:
+            return self.setResultsName(name)
+        else:
+            return self.copy()
+
+    def suppress( self ):
+        """
+        Suppresses the output of this C{ParserElement}; useful to keep punctuation from
+        cluttering up returned output.
+        """
+        return Suppress( self )
+
+    def leaveWhitespace( self ):
+        """
+        Disables the skipping of whitespace before matching the characters in the
+        C{ParserElement}'s defined pattern.  This is normally only used internally by
+        the pyparsing module, but may be needed in some whitespace-sensitive grammars.
+        """
+        self.skipWhitespace = False
+        return self
+
+    def setWhitespaceChars( self, chars ):
+        """
+        Overrides the default whitespace chars
+        """
+        self.skipWhitespace = True
+        self.whiteChars = chars
+        self.copyDefaultWhiteChars = False
+        return self
+
+    def parseWithTabs( self ):
+        """
+        Overrides default behavior to expand C{<TAB>}s to spaces before parsing the input string.
+        Must be called before C{parseString} when the input grammar contains elements that
+        match C{<TAB>} characters.
+        """
+        self.keepTabs = True
+        return self
+
+    def ignore( self, other ):
+        """
+        Define expression to be ignored (e.g., comments) while doing pattern
+        matching; may be called repeatedly, to define multiple comment or other
+        ignorable patterns.
+        
+        Example::
+            patt = OneOrMore(Word(alphas))
+            patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj']
+            
+            patt.ignore(cStyleComment)
+            patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd']
+        """
+        if isinstance(other, basestring):
+            other = Suppress(other)
+
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                self.ignoreExprs.append(other)
+        else:
+            self.ignoreExprs.append( Suppress( other.copy() ) )
+        return self
+
+    def setDebugActions( self, startAction, successAction, exceptionAction ):
+        """
+        Enable display of debugging messages while doing pattern matching.
+        """
+        self.debugActions = (startAction or _defaultStartDebugAction,
+                             successAction or _defaultSuccessDebugAction,
+                             exceptionAction or _defaultExceptionDebugAction)
+        self.debug = True
+        return self
+
+    def setDebug( self, flag=True ):
+        """
+        Enable display of debugging messages while doing pattern matching.
+        Set C{flag} to True to enable, False to disable.
+
+        Example::
+            wd = Word(alphas).setName("alphaword")
+            integer = Word(nums).setName("numword")
+            term = wd | integer
+            
+            # turn on debugging for wd
+            wd.setDebug()
+
+            OneOrMore(term).parseString("abc 123 xyz 890")
+        
+        prints::
+            Match alphaword at loc 0(1,1)
+            Matched alphaword -> ['abc']
+            Match alphaword at loc 3(1,4)
+            Exception raised:Expected alphaword (at char 4), (line:1, col:5)
+            Match alphaword at loc 7(1,8)
+            Matched alphaword -> ['xyz']
+            Match alphaword at loc 11(1,12)
+            Exception raised:Expected alphaword (at char 12), (line:1, col:13)
+            Match alphaword at loc 15(1,16)
+            Exception raised:Expected alphaword (at char 15), (line:1, col:16)
+
+        The output shown is that produced by the default debug actions - custom debug actions can be
+        specified using L{setDebugActions}. Prior to attempting
+        to match the C{wd} expression, the debugging message C{"Match <exprname> at loc <n>(<line>,<col>)"}
+        is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"}
+        message is shown. Also note the use of L{setName} to assign a human-readable name to the expression,
+        which makes debugging and exception messages easier to understand - for instance, the default
+        name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}.
+        """
+        if flag:
+            self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction )
+        else:
+            self.debug = False
+        return self
+
+    def __str__( self ):
+        return self.name
+
+    def __repr__( self ):
+        return _ustr(self)
+
+    def streamline( self ):
+        self.streamlined = True
+        self.strRepr = None
+        return self
+
+    def checkRecursion( self, parseElementList ):
+        pass
+
+    def validate( self, validateTrace=[] ):
+        """
+        Check defined expressions for valid structure, check for infinite recursive definitions.
+        """
+        self.checkRecursion( [] )
+
+    def parseFile( self, file_or_filename, parseAll=False ):
+        """
+        Execute the parse expression on the given file or filename.
+        If a filename is specified (instead of a file object),
+        the entire file is opened, read, and closed before parsing.
+        """
+        try:
+            file_contents = file_or_filename.read()
+        except AttributeError:
+            with open(file_or_filename, "r") as f:
+                file_contents = f.read()
+        try:
+            return self.parseString(file_contents, parseAll)
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def __eq__(self,other):
+        if isinstance(other, ParserElement):
+            return self is other or vars(self) == vars(other)
+        elif isinstance(other, basestring):
+            return self.matches(other)
+        else:
+            return super(ParserElement,self)==other
+
+    def __ne__(self,other):
+        return not (self == other)
+
+    def __hash__(self):
+        return hash(id(self))
+
+    def __req__(self,other):
+        return self == other
+
+    def __rne__(self,other):
+        return not (self == other)
+
+    def matches(self, testString, parseAll=True):
+        """
+        Method for quick testing of a parser against a test string. Good for simple 
+        inline microtests of sub expressions while building up larger parser.
+           
+        Parameters:
+         - testString - to test against this expression for a match
+         - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests
+            
+        Example::
+            expr = Word(nums)
+            assert expr.matches("100")
+        """
+        try:
+            self.parseString(_ustr(testString), parseAll=parseAll)
+            return True
+        except ParseBaseException:
+            return False
+                
+    def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False):
+        """
+        Execute the parse expression on a series of test strings, showing each
+        test, the parsed results or where the parse failed. Quick and easy way to
+        run a parse expression against a list of sample strings.
+           
+        Parameters:
+         - tests - a list of separate test strings, or a multiline string of test strings
+         - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests           
+         - comment - (default=C{'#'}) - expression for indicating embedded comments in the test 
+              string; pass None to disable comment filtering
+         - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline;
+              if False, only dump nested list
+         - printResults - (default=C{True}) prints test output to stdout
+         - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing
+
+        Returns: a (success, results) tuple, where success indicates that all tests succeeded
+        (or failed if C{failureTests} is True), and the results contain a list of lines of each 
+        test's output
+        
+        Example::
+            number_expr = pyparsing_common.number.copy()
+
+            result = number_expr.runTests('''
+                # unsigned integer
+                100
+                # negative integer
+                -100
+                # float with scientific notation
+                6.02e23
+                # integer with scientific notation
+                1e-12
+                ''')
+            print("Success" if result[0] else "Failed!")
+
+            result = number_expr.runTests('''
+                # stray character
+                100Z
+                # missing leading digit before '.'
+                -.100
+                # too many '.'
+                3.14.159
+                ''', failureTests=True)
+            print("Success" if result[0] else "Failed!")
+        prints::
+            # unsigned integer
+            100
+            [100]
+
+            # negative integer
+            -100
+            [-100]
+
+            # float with scientific notation
+            6.02e23
+            [6.02e+23]
+
+            # integer with scientific notation
+            1e-12
+            [1e-12]
+
+            Success
+            
+            # stray character
+            100Z
+               ^
+            FAIL: Expected end of text (at char 3), (line:1, col:4)
+
+            # missing leading digit before '.'
+            -.100
+            ^
+            FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1)
+
+            # too many '.'
+            3.14.159
+                ^
+            FAIL: Expected end of text (at char 4), (line:1, col:5)
+
+            Success
+
+        Each test string must be on a single line. If you want to test a string that spans multiple
+        lines, create a test like this::
+
+            expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines")
+        
+        (Note that this is a raw string literal, you must include the leading 'r'.)
+        """
+        if isinstance(tests, basestring):
+            tests = list(map(str.strip, tests.rstrip().splitlines()))
+        if isinstance(comment, basestring):
+            comment = Literal(comment)
+        allResults = []
+        comments = []
+        success = True
+        for t in tests:
+            if comment is not None and comment.matches(t, False) or comments and not t:
+                comments.append(t)
+                continue
+            if not t:
+                continue
+            out = ['\n'.join(comments), t]
+            comments = []
+            try:
+                t = t.replace(r'\n','\n')
+                result = self.parseString(t, parseAll=parseAll)
+                out.append(result.dump(full=fullDump))
+                success = success and not failureTests
+            except ParseBaseException as pe:
+                fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else ""
+                if '\n' in t:
+                    out.append(line(pe.loc, t))
+                    out.append(' '*(col(pe.loc,t)-1) + '^' + fatal)
+                else:
+                    out.append(' '*pe.loc + '^' + fatal)
+                out.append("FAIL: " + str(pe))
+                success = success and failureTests
+                result = pe
+            except Exception as exc:
+                out.append("FAIL-EXCEPTION: " + str(exc))
+                success = success and failureTests
+                result = exc
+
+            if printResults:
+                if fullDump:
+                    out.append('')
+                print('\n'.join(out))
+
+            allResults.append((t, result))
+        
+        return success, allResults
+
+        
+class Token(ParserElement):
+    """
+    Abstract C{ParserElement} subclass, for defining atomic matching patterns.
+    """
+    def __init__( self ):
+        super(Token,self).__init__( savelist=False )
+
+
+class Empty(Token):
+    """
+    An empty token, will always match.
+    """
+    def __init__( self ):
+        super(Empty,self).__init__()
+        self.name = "Empty"
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+
+
+class NoMatch(Token):
+    """
+    A token that will never match.
+    """
+    def __init__( self ):
+        super(NoMatch,self).__init__()
+        self.name = "NoMatch"
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+        self.errmsg = "Unmatchable token"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        raise ParseException(instring, loc, self.errmsg, self)
+
+
+class Literal(Token):
+    """
+    Token to exactly match a specified string.
+    
+    Example::
+        Literal('blah').parseString('blah')  # -> ['blah']
+        Literal('blah').parseString('blahfooblah')  # -> ['blah']
+        Literal('blah').parseString('bla')  # -> Exception: Expected "blah"
+    
+    For case-insensitive matching, use L{CaselessLiteral}.
+    
+    For keyword matching (force word break before and after the matched string),
+    use L{Keyword} or L{CaselessKeyword}.
+    """
+    def __init__( self, matchString ):
+        super(Literal,self).__init__()
+        self.match = matchString
+        self.matchLen = len(matchString)
+        try:
+            self.firstMatchChar = matchString[0]
+        except IndexError:
+            warnings.warn("null string passed to Literal; use Empty() instead",
+                            SyntaxWarning, stacklevel=2)
+            self.__class__ = Empty
+        self.name = '"%s"' % _ustr(self.match)
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = False
+        self.mayIndexError = False
+
+    # Performance tuning: this routine gets called a *lot*
+    # if this is a single character match string  and the first character matches,
+    # short-circuit as quickly as possible, and avoid calling startswith
+    #~ @profile
+    def parseImpl( self, instring, loc, doActions=True ):
+        if (instring[loc] == self.firstMatchChar and
+            (self.matchLen==1 or instring.startswith(self.match,loc)) ):
+            return loc+self.matchLen, self.match
+        raise ParseException(instring, loc, self.errmsg, self)
+_L = Literal
+ParserElement._literalStringClass = Literal
+
+class Keyword(Token):
+    """
+    Token to exactly match a specified string as a keyword, that is, it must be
+    immediately followed by a non-keyword character.  Compare with C{L{Literal}}:
+     - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}.
+     - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'}
+    Accepts two optional constructor arguments in addition to the keyword string:
+     - C{identChars} is a string of characters that would be valid identifier characters,
+          defaulting to all alphanumerics + "_" and "$"
+     - C{caseless} allows case-insensitive matching, default is C{False}.
+       
+    Example::
+        Keyword("start").parseString("start")  # -> ['start']
+        Keyword("start").parseString("starting")  # -> Exception
+
+    For case-insensitive matching, use L{CaselessKeyword}.
+    """
+    DEFAULT_KEYWORD_CHARS = alphanums+"_$"
+
+    def __init__( self, matchString, identChars=None, caseless=False ):
+        super(Keyword,self).__init__()
+        if identChars is None:
+            identChars = Keyword.DEFAULT_KEYWORD_CHARS
+        self.match = matchString
+        self.matchLen = len(matchString)
+        try:
+            self.firstMatchChar = matchString[0]
+        except IndexError:
+            warnings.warn("null string passed to Keyword; use Empty() instead",
+                            SyntaxWarning, stacklevel=2)
+        self.name = '"%s"' % self.match
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = False
+        self.mayIndexError = False
+        self.caseless = caseless
+        if caseless:
+            self.caselessmatch = matchString.upper()
+            identChars = identChars.upper()
+        self.identChars = set(identChars)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.caseless:
+            if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
+                 (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and
+                 (loc == 0 or instring[loc-1].upper() not in self.identChars) ):
+                return loc+self.matchLen, self.match
+        else:
+            if (instring[loc] == self.firstMatchChar and
+                (self.matchLen==1 or instring.startswith(self.match,loc)) and
+                (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and
+                (loc == 0 or instring[loc-1] not in self.identChars) ):
+                return loc+self.matchLen, self.match
+        raise ParseException(instring, loc, self.errmsg, self)
+
+    def copy(self):
+        c = super(Keyword,self).copy()
+        c.identChars = Keyword.DEFAULT_KEYWORD_CHARS
+        return c
+
+    @staticmethod
+    def setDefaultKeywordChars( chars ):
+        """Overrides the default Keyword chars
+        """
+        Keyword.DEFAULT_KEYWORD_CHARS = chars
+
+class CaselessLiteral(Literal):
+    """
+    Token to match a specified string, ignoring case of letters.
+    Note: the matched results will always be in the case of the given
+    match string, NOT the case of the input text.
+
+    Example::
+        OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD']
+        
+    (Contrast with example for L{CaselessKeyword}.)
+    """
+    def __init__( self, matchString ):
+        super(CaselessLiteral,self).__init__( matchString.upper() )
+        # Preserve the defining literal.
+        self.returnString = matchString
+        self.name = "'%s'" % self.returnString
+        self.errmsg = "Expected " + self.name
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if instring[ loc:loc+self.matchLen ].upper() == self.match:
+            return loc+self.matchLen, self.returnString
+        raise ParseException(instring, loc, self.errmsg, self)
+
+class CaselessKeyword(Keyword):
+    """
+    Caseless version of L{Keyword}.
+
+    Example::
+        OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD']
+        
+    (Contrast with example for L{CaselessLiteral}.)
+    """
+    def __init__( self, matchString, identChars=None ):
+        super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True )
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
+             (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ):
+            return loc+self.matchLen, self.match
+        raise ParseException(instring, loc, self.errmsg, self)
+
+class CloseMatch(Token):
+    """
+    A variation on L{Literal} which matches "close" matches, that is, 
+    strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters:
+     - C{match_string} - string to be matched
+     - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match
+    
+    The results from a successful parse will contain the matched text from the input string and the following named results:
+     - C{mismatches} - a list of the positions within the match_string where mismatches were found
+     - C{original} - the original match_string used to compare against the input string
+    
+    If C{mismatches} is an empty list, then the match was an exact match.
+    
+    Example::
+        patt = CloseMatch("ATCATCGAATGGA")
+        patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']})
+        patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1)
+
+        # exact match
+        patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']})
+
+        # close match allowing up to 2 mismatches
+        patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2)
+        patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']})
+    """
+    def __init__(self, match_string, maxMismatches=1):
+        super(CloseMatch,self).__init__()
+        self.name = match_string
+        self.match_string = match_string
+        self.maxMismatches = maxMismatches
+        self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches)
+        self.mayIndexError = False
+        self.mayReturnEmpty = False
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        start = loc
+        instrlen = len(instring)
+        maxloc = start + len(self.match_string)
+
+        if maxloc <= instrlen:
+            match_string = self.match_string
+            match_stringloc = 0
+            mismatches = []
+            maxMismatches = self.maxMismatches
+
+            for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)):
+                src,mat = s_m
+                if src != mat:
+                    mismatches.append(match_stringloc)
+                    if len(mismatches) > maxMismatches:
+                        break
+            else:
+                loc = match_stringloc + 1
+                results = ParseResults([instring[start:loc]])
+                results['original'] = self.match_string
+                results['mismatches'] = mismatches
+                return loc, results
+
+        raise ParseException(instring, loc, self.errmsg, self)
+
+
+class Word(Token):
+    """
+    Token for matching words composed of allowed character sets.
+    Defined with string containing all allowed initial characters,
+    an optional string containing allowed body characters (if omitted,
+    defaults to the initial character set), and an optional minimum,
+    maximum, and/or exact length.  The default value for C{min} is 1 (a
+    minimum value < 1 is not valid); the default values for C{max} and C{exact}
+    are 0, meaning no maximum or exact length restriction. An optional
+    C{excludeChars} parameter can list characters that might be found in 
+    the input C{bodyChars} string; useful to define a word of all printables
+    except for one or two characters, for instance.
+    
+    L{srange} is useful for defining custom character set strings for defining 
+    C{Word} expressions, using range notation from regular expression character sets.
+    
+    A common mistake is to use C{Word} to match a specific literal string, as in 
+    C{Word("Address")}. Remember that C{Word} uses the string argument to define
+    I{sets} of matchable characters. This expression would match "Add", "AAA",
+    "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'.
+    To match an exact literal string, use L{Literal} or L{Keyword}.
+
+    pyparsing includes helper strings for building Words:
+     - L{alphas}
+     - L{nums}
+     - L{alphanums}
+     - L{hexnums}
+     - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.)
+     - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.)
+     - L{printables} (any non-whitespace character)
+
+    Example::
+        # a word composed of digits
+        integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9"))
+        
+        # a word with a leading capital, and zero or more lowercase
+        capital_word = Word(alphas.upper(), alphas.lower())
+
+        # hostnames are alphanumeric, with leading alpha, and '-'
+        hostname = Word(alphas, alphanums+'-')
+        
+        # roman numeral (not a strict parser, accepts invalid mix of characters)
+        roman = Word("IVXLCDM")
+        
+        # any string of non-whitespace characters, except for ','
+        csv_value = Word(printables, excludeChars=",")
+    """
+    def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ):
+        super(Word,self).__init__()
+        if excludeChars:
+            initChars = ''.join(c for c in initChars if c not in excludeChars)
+            if bodyChars:
+                bodyChars = ''.join(c for c in bodyChars if c not in excludeChars)
+        self.initCharsOrig = initChars
+        self.initChars = set(initChars)
+        if bodyChars :
+            self.bodyCharsOrig = bodyChars
+            self.bodyChars = set(bodyChars)
+        else:
+            self.bodyCharsOrig = initChars
+            self.bodyChars = set(initChars)
+
+        self.maxSpecified = max > 0
+
+        if min < 1:
+            raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted")
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayIndexError = False
+        self.asKeyword = asKeyword
+
+        if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0):
+            if self.bodyCharsOrig == self.initCharsOrig:
+                self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig)
+            elif len(self.initCharsOrig) == 1:
+                self.reString = "%s[%s]*" % \
+                                      (re.escape(self.initCharsOrig),
+                                      _escapeRegexRangeChars(self.bodyCharsOrig),)
+            else:
+                self.reString = "[%s][%s]*" % \
+                                      (_escapeRegexRangeChars(self.initCharsOrig),
+                                      _escapeRegexRangeChars(self.bodyCharsOrig),)
+            if self.asKeyword:
+                self.reString = r"\b"+self.reString+r"\b"
+            try:
+                self.re = re.compile( self.reString )
+            except Exception:
+                self.re = None
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.re:
+            result = self.re.match(instring,loc)
+            if not result:
+                raise ParseException(instring, loc, self.errmsg, self)
+
+            loc = result.end()
+            return loc, result.group()
+
+        if not(instring[ loc ] in self.initChars):
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        start = loc
+        loc += 1
+        instrlen = len(instring)
+        bodychars = self.bodyChars
+        maxloc = start + self.maxLen
+        maxloc = min( maxloc, instrlen )
+        while loc < maxloc and instring[loc] in bodychars:
+            loc += 1
+
+        throwException = False
+        if loc - start < self.minLen:
+            throwException = True
+        if self.maxSpecified and loc < instrlen and instring[loc] in bodychars:
+            throwException = True
+        if self.asKeyword:
+            if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars):
+                throwException = True
+
+        if throwException:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        return loc, instring[start:loc]
+
+    def __str__( self ):
+        try:
+            return super(Word,self).__str__()
+        except Exception:
+            pass
+
+
+        if self.strRepr is None:
+
+            def charsAsStr(s):
+                if len(s)>4:
+                    return s[:4]+"..."
+                else:
+                    return s
+
+            if ( self.initCharsOrig != self.bodyCharsOrig ):
+                self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) )
+            else:
+                self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig)
+
+        return self.strRepr
+
+
+class Regex(Token):
+    """
+    Token for matching strings that match a given regular expression.
+    Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module.
+    If the given regex contains named groups (defined using C{(?P<name>...)}), these will be preserved as 
+    named parse results.
+
+    Example::
+        realnum = Regex(r"[+-]?\d+\.\d*")
+        date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)')
+        # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression
+        roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})")
+    """
+    compiledREtype = type(re.compile("[A-Z]"))
+    def __init__( self, pattern, flags=0):
+        """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags."""
+        super(Regex,self).__init__()
+
+        if isinstance(pattern, basestring):
+            if not pattern:
+                warnings.warn("null string passed to Regex; use Empty() instead",
+                        SyntaxWarning, stacklevel=2)
+
+            self.pattern = pattern
+            self.flags = flags
+
+            try:
+                self.re = re.compile(self.pattern, self.flags)
+                self.reString = self.pattern
+            except sre_constants.error:
+                warnings.warn("invalid pattern (%s) passed to Regex" % pattern,
+                    SyntaxWarning, stacklevel=2)
+                raise
+
+        elif isinstance(pattern, Regex.compiledREtype):
+            self.re = pattern
+            self.pattern = \
+            self.reString = str(pattern)
+            self.flags = flags
+            
+        else:
+            raise ValueError("Regex may only be constructed with a string or a compiled RE object")
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayIndexError = False
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        result = self.re.match(instring,loc)
+        if not result:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        loc = result.end()
+        d = result.groupdict()
+        ret = ParseResults(result.group())
+        if d:
+            for k in d:
+                ret[k] = d[k]
+        return loc,ret
+
+    def __str__( self ):
+        try:
+            return super(Regex,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "Re:(%s)" % repr(self.pattern)
+
+        return self.strRepr
+
+
+class QuotedString(Token):
+    r"""
+    Token for matching strings that are delimited by quoting characters.
+    
+    Defined with the following parameters:
+        - quoteChar - string of one or more characters defining the quote delimiting string
+        - escChar - character to escape quotes, typically backslash (default=C{None})
+        - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None})
+        - multiline - boolean indicating whether quotes can span multiple lines (default=C{False})
+        - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True})
+        - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar)
+        - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True})
+
+    Example::
+        qs = QuotedString('"')
+        print(qs.searchString('lsjdf "This is the quote" sldjf'))
+        complex_qs = QuotedString('{{', endQuoteChar='}}')
+        print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf'))
+        sql_qs = QuotedString('"', escQuote='""')
+        print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf'))
+    prints::
+        [['This is the quote']]
+        [['This is the "quote"']]
+        [['This is the quote with "embedded" quotes']]
+    """
+    def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True):
+        super(QuotedString,self).__init__()
+
+        # remove white space from quote chars - wont work anyway
+        quoteChar = quoteChar.strip()
+        if not quoteChar:
+            warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
+            raise SyntaxError()
+
+        if endQuoteChar is None:
+            endQuoteChar = quoteChar
+        else:
+            endQuoteChar = endQuoteChar.strip()
+            if not endQuoteChar:
+                warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
+                raise SyntaxError()
+
+        self.quoteChar = quoteChar
+        self.quoteCharLen = len(quoteChar)
+        self.firstQuoteChar = quoteChar[0]
+        self.endQuoteChar = endQuoteChar
+        self.endQuoteCharLen = len(endQuoteChar)
+        self.escChar = escChar
+        self.escQuote = escQuote
+        self.unquoteResults = unquoteResults
+        self.convertWhitespaceEscapes = convertWhitespaceEscapes
+
+        if multiline:
+            self.flags = re.MULTILINE | re.DOTALL
+            self.pattern = r'%s(?:[^%s%s]' % \
+                ( re.escape(self.quoteChar),
+                  _escapeRegexRangeChars(self.endQuoteChar[0]),
+                  (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
+        else:
+            self.flags = 0
+            self.pattern = r'%s(?:[^%s\n\r%s]' % \
+                ( re.escape(self.quoteChar),
+                  _escapeRegexRangeChars(self.endQuoteChar[0]),
+                  (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
+        if len(self.endQuoteChar) > 1:
+            self.pattern += (
+                '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]),
+                                               _escapeRegexRangeChars(self.endQuoteChar[i]))
+                                    for i in range(len(self.endQuoteChar)-1,0,-1)) + ')'
+                )
+        if escQuote:
+            self.pattern += (r'|(?:%s)' % re.escape(escQuote))
+        if escChar:
+            self.pattern += (r'|(?:%s.)' % re.escape(escChar))
+            self.escCharReplacePattern = re.escape(self.escChar)+"(.)"
+        self.pattern += (r')*%s' % re.escape(self.endQuoteChar))
+
+        try:
+            self.re = re.compile(self.pattern, self.flags)
+            self.reString = self.pattern
+        except sre_constants.error:
+            warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern,
+                SyntaxWarning, stacklevel=2)
+            raise
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayIndexError = False
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None
+        if not result:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        loc = result.end()
+        ret = result.group()
+
+        if self.unquoteResults:
+
+            # strip off quotes
+            ret = ret[self.quoteCharLen:-self.endQuoteCharLen]
+
+            if isinstance(ret,basestring):
+                # replace escaped whitespace
+                if '\\' in ret and self.convertWhitespaceEscapes:
+                    ws_map = {
+                        r'\t' : '\t',
+                        r'\n' : '\n',
+                        r'\f' : '\f',
+                        r'\r' : '\r',
+                    }
+                    for wslit,wschar in ws_map.items():
+                        ret = ret.replace(wslit, wschar)
+
+                # replace escaped characters
+                if self.escChar:
+                    ret = re.sub(self.escCharReplacePattern,"\g<1>",ret)
+
+                # replace escaped quotes
+                if self.escQuote:
+                    ret = ret.replace(self.escQuote, self.endQuoteChar)
+
+        return loc, ret
+
+    def __str__( self ):
+        try:
+            return super(QuotedString,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar)
+
+        return self.strRepr
+
+
+class CharsNotIn(Token):
+    """
+    Token for matching words composed of characters I{not} in a given set (will
+    include whitespace in matched characters if not listed in the provided exclusion set - see example).
+    Defined with string containing all disallowed characters, and an optional
+    minimum, maximum, and/or exact length.  The default value for C{min} is 1 (a
+    minimum value < 1 is not valid); the default values for C{max} and C{exact}
+    are 0, meaning no maximum or exact length restriction.
+
+    Example::
+        # define a comma-separated-value as anything that is not a ','
+        csv_value = CharsNotIn(',')
+        print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213"))
+    prints::
+        ['dkls', 'lsdkjf', 's12 34', '@!#', '213']
+    """
+    def __init__( self, notChars, min=1, max=0, exact=0 ):
+        super(CharsNotIn,self).__init__()
+        self.skipWhitespace = False
+        self.notChars = notChars
+
+        if min < 1:
+            raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted")
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = ( self.minLen == 0 )
+        self.mayIndexError = False
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if instring[loc] in self.notChars:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        start = loc
+        loc += 1
+        notchars = self.notChars
+        maxlen = min( start+self.maxLen, len(instring) )
+        while loc < maxlen and \
+              (instring[loc] not in notchars):
+            loc += 1
+
+        if loc - start < self.minLen:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        return loc, instring[start:loc]
+
+    def __str__( self ):
+        try:
+            return super(CharsNotIn, self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            if len(self.notChars) > 4:
+                self.strRepr = "!W:(%s...)" % self.notChars[:4]
+            else:
+                self.strRepr = "!W:(%s)" % self.notChars
+
+        return self.strRepr
+
+class White(Token):
+    """
+    Special matching class for matching whitespace.  Normally, whitespace is ignored
+    by pyparsing grammars.  This class is included when some whitespace structures
+    are significant.  Define with a string containing the whitespace characters to be
+    matched; default is C{" \\t\\r\\n"}.  Also takes optional C{min}, C{max}, and C{exact} arguments,
+    as defined for the C{L{Word}} class.
+    """
+    whiteStrs = {
+        " " : "<SPC>",
+        "\t": "<TAB>",
+        "\n": "<LF>",
+        "\r": "<CR>",
+        "\f": "<FF>",
+        }
+    def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0):
+        super(White,self).__init__()
+        self.matchWhite = ws
+        self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) )
+        #~ self.leaveWhitespace()
+        self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite))
+        self.mayReturnEmpty = True
+        self.errmsg = "Expected " + self.name
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if not(instring[ loc ] in self.matchWhite):
+            raise ParseException(instring, loc, self.errmsg, self)
+        start = loc
+        loc += 1
+        maxloc = start + self.maxLen
+        maxloc = min( maxloc, len(instring) )
+        while loc < maxloc and instring[loc] in self.matchWhite:
+            loc += 1
+
+        if loc - start < self.minLen:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        return loc, instring[start:loc]
+
+
+class _PositionToken(Token):
+    def __init__( self ):
+        super(_PositionToken,self).__init__()
+        self.name=self.__class__.__name__
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+
+class GoToColumn(_PositionToken):
+    """
+    Token to advance to a specific column of input text; useful for tabular report scraping.
+    """
+    def __init__( self, colno ):
+        super(GoToColumn,self).__init__()
+        self.col = colno
+
+    def preParse( self, instring, loc ):
+        if col(loc,instring) != self.col:
+            instrlen = len(instring)
+            if self.ignoreExprs:
+                loc = self._skipIgnorables( instring, loc )
+            while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col :
+                loc += 1
+        return loc
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        thiscol = col( loc, instring )
+        if thiscol > self.col:
+            raise ParseException( instring, loc, "Text not in expected column", self )
+        newloc = loc + self.col - thiscol
+        ret = instring[ loc: newloc ]
+        return newloc, ret
+
+
+class LineStart(_PositionToken):
+    """
+    Matches if current position is at the beginning of a line within the parse string
+    
+    Example::
+    
+        test = '''\
+        AAA this line
+        AAA and this line
+          AAA but not this one
+        B AAA and definitely not this one
+        '''
+
+        for t in (LineStart() + 'AAA' + restOfLine).searchString(test):
+            print(t)
+    
+    Prints::
+        ['AAA', ' this line']
+        ['AAA', ' and this line']    
+
+    """
+    def __init__( self ):
+        super(LineStart,self).__init__()
+        self.errmsg = "Expected start of line"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if col(loc, instring) == 1:
+            return loc, []
+        raise ParseException(instring, loc, self.errmsg, self)
+
+class LineEnd(_PositionToken):
+    """
+    Matches if current position is at the end of a line within the parse string
+    """
+    def __init__( self ):
+        super(LineEnd,self).__init__()
+        self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") )
+        self.errmsg = "Expected end of line"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc<len(instring):
+            if instring[loc] == "\n":
+                return loc+1, "\n"
+            else:
+                raise ParseException(instring, loc, self.errmsg, self)
+        elif loc == len(instring):
+            return loc+1, []
+        else:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+class StringStart(_PositionToken):
+    """
+    Matches if current position is at the beginning of the parse string
+    """
+    def __init__( self ):
+        super(StringStart,self).__init__()
+        self.errmsg = "Expected start of text"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc != 0:
+            # see if entire string up to here is just whitespace and ignoreables
+            if loc != self.preParse( instring, 0 ):
+                raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+class StringEnd(_PositionToken):
+    """
+    Matches if current position is at the end of the parse string
+    """
+    def __init__( self ):
+        super(StringEnd,self).__init__()
+        self.errmsg = "Expected end of text"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc < len(instring):
+            raise ParseException(instring, loc, self.errmsg, self)
+        elif loc == len(instring):
+            return loc+1, []
+        elif loc > len(instring):
+            return loc, []
+        else:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+class WordStart(_PositionToken):
+    """
+    Matches if the current position is at the beginning of a Word, and
+    is not preceded by any character in a given set of C{wordChars}
+    (default=C{printables}). To emulate the C{\b} behavior of regular expressions,
+    use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of
+    the string being parsed, or at the beginning of a line.
+    """
+    def __init__(self, wordChars = printables):
+        super(WordStart,self).__init__()
+        self.wordChars = set(wordChars)
+        self.errmsg = "Not at the start of a word"
+
+    def parseImpl(self, instring, loc, doActions=True ):
+        if loc != 0:
+            if (instring[loc-1] in self.wordChars or
+                instring[loc] not in self.wordChars):
+                raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+class WordEnd(_PositionToken):
+    """
+    Matches if the current position is at the end of a Word, and
+    is not followed by any character in a given set of C{wordChars}
+    (default=C{printables}). To emulate the C{\b} behavior of regular expressions,
+    use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of
+    the string being parsed, or at the end of a line.
+    """
+    def __init__(self, wordChars = printables):
+        super(WordEnd,self).__init__()
+        self.wordChars = set(wordChars)
+        self.skipWhitespace = False
+        self.errmsg = "Not at the end of a word"
+
+    def parseImpl(self, instring, loc, doActions=True ):
+        instrlen = len(instring)
+        if instrlen>0 and loc<instrlen:
+            if (instring[loc] in self.wordChars or
+                instring[loc-1] not in self.wordChars):
+                raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+
+class ParseExpression(ParserElement):
+    """
+    Abstract subclass of ParserElement, for combining and post-processing parsed tokens.
+    """
+    def __init__( self, exprs, savelist = False ):
+        super(ParseExpression,self).__init__(savelist)
+        if isinstance( exprs, _generatorType ):
+            exprs = list(exprs)
+
+        if isinstance( exprs, basestring ):
+            self.exprs = [ ParserElement._literalStringClass( exprs ) ]
+        elif isinstance( exprs, collections.Iterable ):
+            exprs = list(exprs)
+            # if sequence of strings provided, wrap with Literal
+            if all(isinstance(expr, basestring) for expr in exprs):
+                exprs = map(ParserElement._literalStringClass, exprs)
+            self.exprs = list(exprs)
+        else:
+            try:
+                self.exprs = list( exprs )
+            except TypeError:
+                self.exprs = [ exprs ]
+        self.callPreparse = False
+
+    def __getitem__( self, i ):
+        return self.exprs[i]
+
+    def append( self, other ):
+        self.exprs.append( other )
+        self.strRepr = None
+        return self
+
+    def leaveWhitespace( self ):
+        """Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on
+           all contained expressions."""
+        self.skipWhitespace = False
+        self.exprs = [ e.copy() for e in self.exprs ]
+        for e in self.exprs:
+            e.leaveWhitespace()
+        return self
+
+    def ignore( self, other ):
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                super( ParseExpression, self).ignore( other )
+                for e in self.exprs:
+                    e.ignore( self.ignoreExprs[-1] )
+        else:
+            super( ParseExpression, self).ignore( other )
+            for e in self.exprs:
+                e.ignore( self.ignoreExprs[-1] )
+        return self
+
+    def __str__( self ):
+        try:
+            return super(ParseExpression,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) )
+        return self.strRepr
+
+    def streamline( self ):
+        super(ParseExpression,self).streamline()
+
+        for e in self.exprs:
+            e.streamline()
+
+        # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d )
+        # but only if there are no parse actions or resultsNames on the nested And's
+        # (likewise for Or's and MatchFirst's)
+        if ( len(self.exprs) == 2 ):
+            other = self.exprs[0]
+            if ( isinstance( other, self.__class__ ) and
+                  not(other.parseAction) and
+                  other.resultsName is None and
+                  not other.debug ):
+                self.exprs = other.exprs[:] + [ self.exprs[1] ]
+                self.strRepr = None
+                self.mayReturnEmpty |= other.mayReturnEmpty
+                self.mayIndexError  |= other.mayIndexError
+
+            other = self.exprs[-1]
+            if ( isinstance( other, self.__class__ ) and
+                  not(other.parseAction) and
+                  other.resultsName is None and
+                  not other.debug ):
+                self.exprs = self.exprs[:-1] + other.exprs[:]
+                self.strRepr = None
+                self.mayReturnEmpty |= other.mayReturnEmpty
+                self.mayIndexError  |= other.mayIndexError
+
+        self.errmsg = "Expected " + _ustr(self)
+        
+        return self
+
+    def setResultsName( self, name, listAllMatches=False ):
+        ret = super(ParseExpression,self).setResultsName(name,listAllMatches)
+        return ret
+
+    def validate( self, validateTrace=[] ):
+        tmp = validateTrace[:]+[self]
+        for e in self.exprs:
+            e.validate(tmp)
+        self.checkRecursion( [] )
+        
+    def copy(self):
+        ret = super(ParseExpression,self).copy()
+        ret.exprs = [e.copy() for e in self.exprs]
+        return ret
+
+class And(ParseExpression):
+    """
+    Requires all given C{ParseExpression}s to be found in the given order.
+    Expressions may be separated by whitespace.
+    May be constructed using the C{'+'} operator.
+    May also be constructed using the C{'-'} operator, which will suppress backtracking.
+
+    Example::
+        integer = Word(nums)
+        name_expr = OneOrMore(Word(alphas))
+
+        expr = And([integer("id"),name_expr("name"),integer("age")])
+        # more easily written as:
+        expr = integer("id") + name_expr("name") + integer("age")
+    """
+
+    class _ErrorStop(Empty):
+        def __init__(self, *args, **kwargs):
+            super(And._ErrorStop,self).__init__(*args, **kwargs)
+            self.name = '-'
+            self.leaveWhitespace()
+
+    def __init__( self, exprs, savelist = True ):
+        super(And,self).__init__(exprs, savelist)
+        self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
+        self.setWhitespaceChars( self.exprs[0].whiteChars )
+        self.skipWhitespace = self.exprs[0].skipWhitespace
+        self.callPreparse = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        # pass False as last arg to _parse for first element, since we already
+        # pre-parsed the string as part of our And pre-parsing
+        loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False )
+        errorStop = False
+        for e in self.exprs[1:]:
+            if isinstance(e, And._ErrorStop):
+                errorStop = True
+                continue
+            if errorStop:
+                try:
+                    loc, exprtokens = e._parse( instring, loc, doActions )
+                except ParseSyntaxException:
+                    raise
+                except ParseBaseException as pe:
+                    pe.__traceback__ = None
+                    raise ParseSyntaxException._from_exception(pe)
+                except IndexError:
+                    raise ParseSyntaxException(instring, len(instring), self.errmsg, self)
+            else:
+                loc, exprtokens = e._parse( instring, loc, doActions )
+            if exprtokens or exprtokens.haskeys():
+                resultlist += exprtokens
+        return loc, resultlist
+
+    def __iadd__(self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        return self.append( other ) #And( [ self, other ] )
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+            if not e.mayReturnEmpty:
+                break
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+
+class Or(ParseExpression):
+    """
+    Requires that at least one C{ParseExpression} is found.
+    If two expressions match, the expression that matches the longest string will be used.
+    May be constructed using the C{'^'} operator.
+
+    Example::
+        # construct Or using '^' operator
+        
+        number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums))
+        print(number.searchString("123 3.1416 789"))
+    prints::
+        [['123'], ['3.1416'], ['789']]
+    """
+    def __init__( self, exprs, savelist = False ):
+        super(Or,self).__init__(exprs, savelist)
+        if self.exprs:
+            self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs)
+        else:
+            self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        maxExcLoc = -1
+        maxException = None
+        matches = []
+        for e in self.exprs:
+            try:
+                loc2 = e.tryParse( instring, loc )
+            except ParseException as err:
+                err.__traceback__ = None
+                if err.loc > maxExcLoc:
+                    maxException = err
+                    maxExcLoc = err.loc
+            except IndexError:
+                if len(instring) > maxExcLoc:
+                    maxException = ParseException(instring,len(instring),e.errmsg,self)
+                    maxExcLoc = len(instring)
+            else:
+                # save match among all matches, to retry longest to shortest
+                matches.append((loc2, e))
+
+        if matches:
+            matches.sort(key=lambda x: -x[0])
+            for _,e in matches:
+                try:
+                    return e._parse( instring, loc, doActions )
+                except ParseException as err:
+                    err.__traceback__ = None
+                    if err.loc > maxExcLoc:
+                        maxException = err
+                        maxExcLoc = err.loc
+
+        if maxException is not None:
+            maxException.msg = self.errmsg
+            raise maxException
+        else:
+            raise ParseException(instring, loc, "no defined alternatives to match", self)
+
+
+    def __ixor__(self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        return self.append( other ) #Or( [ self, other ] )
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class MatchFirst(ParseExpression):
+    """
+    Requires that at least one C{ParseExpression} is found.
+    If two expressions match, the first one listed is the one that will match.
+    May be constructed using the C{'|'} operator.
+
+    Example::
+        # construct MatchFirst using '|' operator
+        
+        # watch the order of expressions to match
+        number = Word(nums) | Combine(Word(nums) + '.' + Word(nums))
+        print(number.searchString("123 3.1416 789")) #  Fail! -> [['123'], ['3'], ['1416'], ['789']]
+
+        # put more selective expression first
+        number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums)
+        print(number.searchString("123 3.1416 789")) #  Better -> [['123'], ['3.1416'], ['789']]
+    """
+    def __init__( self, exprs, savelist = False ):
+        super(MatchFirst,self).__init__(exprs, savelist)
+        if self.exprs:
+            self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs)
+        else:
+            self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        maxExcLoc = -1
+        maxException = None
+        for e in self.exprs:
+            try:
+                ret = e._parse( instring, loc, doActions )
+                return ret
+            except ParseException as err:
+                if err.loc > maxExcLoc:
+                    maxException = err
+                    maxExcLoc = err.loc
+            except IndexError:
+                if len(instring) > maxExcLoc:
+                    maxException = ParseException(instring,len(instring),e.errmsg,self)
+                    maxExcLoc = len(instring)
+
+        # only got here if no expression matched, raise exception for match that made it the furthest
+        else:
+            if maxException is not None:
+                maxException.msg = self.errmsg
+                raise maxException
+            else:
+                raise ParseException(instring, loc, "no defined alternatives to match", self)
+
+    def __ior__(self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        return self.append( other ) #MatchFirst( [ self, other ] )
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class Each(ParseExpression):
+    """
+    Requires all given C{ParseExpression}s to be found, but in any order.
+    Expressions may be separated by whitespace.
+    May be constructed using the C{'&'} operator.
+
+    Example::
+        color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN")
+        shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON")
+        integer = Word(nums)
+        shape_attr = "shape:" + shape_type("shape")
+        posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn")
+        color_attr = "color:" + color("color")
+        size_attr = "size:" + integer("size")
+
+        # use Each (using operator '&') to accept attributes in any order 
+        # (shape and posn are required, color and size are optional)
+        shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr)
+
+        shape_spec.runTests('''
+            shape: SQUARE color: BLACK posn: 100, 120
+            shape: CIRCLE size: 50 color: BLUE posn: 50,80
+            color:GREEN size:20 shape:TRIANGLE posn:20,40
+            '''
+            )
+    prints::
+        shape: SQUARE color: BLACK posn: 100, 120
+        ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']]
+        - color: BLACK
+        - posn: ['100', ',', '120']
+          - x: 100
+          - y: 120
+        - shape: SQUARE
+
+
+        shape: CIRCLE size: 50 color: BLUE posn: 50,80
+        ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']]
+        - color: BLUE
+        - posn: ['50', ',', '80']
+          - x: 50
+          - y: 80
+        - shape: CIRCLE
+        - size: 50
+
+
+        color: GREEN size: 20 shape: TRIANGLE posn: 20,40
+        ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']]
+        - color: GREEN
+        - posn: ['20', ',', '40']
+          - x: 20
+          - y: 40
+        - shape: TRIANGLE
+        - size: 20
+    """
+    def __init__( self, exprs, savelist = True ):
+        super(Each,self).__init__(exprs, savelist)
+        self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
+        self.skipWhitespace = True
+        self.initExprGroups = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.initExprGroups:
+            self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional))
+            opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ]
+            opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)]
+            self.optionals = opt1 + opt2
+            self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ]
+            self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ]
+            self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ]
+            self.required += self.multirequired
+            self.initExprGroups = False
+        tmpLoc = loc
+        tmpReqd = self.required[:]
+        tmpOpt  = self.optionals[:]
+        matchOrder = []
+
+        keepMatching = True
+        while keepMatching:
+            tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired
+            failed = []
+            for e in tmpExprs:
+                try:
+                    tmpLoc = e.tryParse( instring, tmpLoc )
+                except ParseException:
+                    failed.append(e)
+                else:
+                    matchOrder.append(self.opt1map.get(id(e),e))
+                    if e in tmpReqd:
+                        tmpReqd.remove(e)
+                    elif e in tmpOpt:
+                        tmpOpt.remove(e)
+            if len(failed) == len(tmpExprs):
+                keepMatching = False
+
+        if tmpReqd:
+            missing = ", ".join(_ustr(e) for e in tmpReqd)
+            raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing )
+
+        # add any unmatched Optionals, in case they have default values defined
+        matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt]
+
+        resultlist = []
+        for e in matchOrder:
+            loc,results = e._parse(instring,loc,doActions)
+            resultlist.append(results)
+
+        finalResults = sum(resultlist, ParseResults([]))
+        return loc, finalResults
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class ParseElementEnhance(ParserElement):
+    """
+    Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens.
+    """
+    def __init__( self, expr, savelist=False ):
+        super(ParseElementEnhance,self).__init__(savelist)
+        if isinstance( expr, basestring ):
+            if issubclass(ParserElement._literalStringClass, Token):
+                expr = ParserElement._literalStringClass(expr)
+            else:
+                expr = ParserElement._literalStringClass(Literal(expr))
+        self.expr = expr
+        self.strRepr = None
+        if expr is not None:
+            self.mayIndexError = expr.mayIndexError
+            self.mayReturnEmpty = expr.mayReturnEmpty
+            self.setWhitespaceChars( expr.whiteChars )
+            self.skipWhitespace = expr.skipWhitespace
+            self.saveAsList = expr.saveAsList
+            self.callPreparse = expr.callPreparse
+            self.ignoreExprs.extend(expr.ignoreExprs)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.expr is not None:
+            return self.expr._parse( instring, loc, doActions, callPreParse=False )
+        else:
+            raise ParseException("",loc,self.errmsg,self)
+
+    def leaveWhitespace( self ):
+        self.skipWhitespace = False
+        self.expr = self.expr.copy()
+        if self.expr is not None:
+            self.expr.leaveWhitespace()
+        return self
+
+    def ignore( self, other ):
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                super( ParseElementEnhance, self).ignore( other )
+                if self.expr is not None:
+                    self.expr.ignore( self.ignoreExprs[-1] )
+        else:
+            super( ParseElementEnhance, self).ignore( other )
+            if self.expr is not None:
+                self.expr.ignore( self.ignoreExprs[-1] )
+        return self
+
+    def streamline( self ):
+        super(ParseElementEnhance,self).streamline()
+        if self.expr is not None:
+            self.expr.streamline()
+        return self
+
+    def checkRecursion( self, parseElementList ):
+        if self in parseElementList:
+            raise RecursiveGrammarException( parseElementList+[self] )
+        subRecCheckList = parseElementList[:] + [ self ]
+        if self.expr is not None:
+            self.expr.checkRecursion( subRecCheckList )
+
+    def validate( self, validateTrace=[] ):
+        tmp = validateTrace[:]+[self]
+        if self.expr is not None:
+            self.expr.validate(tmp)
+        self.checkRecursion( [] )
+
+    def __str__( self ):
+        try:
+            return super(ParseElementEnhance,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None and self.expr is not None:
+            self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) )
+        return self.strRepr
+
+
+class FollowedBy(ParseElementEnhance):
+    """
+    Lookahead matching of the given parse expression.  C{FollowedBy}
+    does I{not} advance the parsing position within the input string, it only
+    verifies that the specified parse expression matches at the current
+    position.  C{FollowedBy} always returns a null token list.
+
+    Example::
+        # use FollowedBy to match a label only if it is followed by a ':'
+        data_word = Word(alphas)
+        label = data_word + FollowedBy(':')
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        
+        OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint()
+    prints::
+        [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']]
+    """
+    def __init__( self, expr ):
+        super(FollowedBy,self).__init__(expr)
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        self.expr.tryParse( instring, loc )
+        return loc, []
+
+
+class NotAny(ParseElementEnhance):
+    """
+    Lookahead to disallow matching with the given parse expression.  C{NotAny}
+    does I{not} advance the parsing position within the input string, it only
+    verifies that the specified parse expression does I{not} match at the current
+    position.  Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny}
+    always returns a null token list.  May be constructed using the '~' operator.
+
+    Example::
+        
+    """
+    def __init__( self, expr ):
+        super(NotAny,self).__init__(expr)
+        #~ self.leaveWhitespace()
+        self.skipWhitespace = False  # do NOT use self.leaveWhitespace(), don't want to propagate to exprs
+        self.mayReturnEmpty = True
+        self.errmsg = "Found unwanted token, "+_ustr(self.expr)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.expr.canParseNext(instring, loc):
+            raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "~{" + _ustr(self.expr) + "}"
+
+        return self.strRepr
+
+class _MultipleMatch(ParseElementEnhance):
+    def __init__( self, expr, stopOn=None):
+        super(_MultipleMatch, self).__init__(expr)
+        self.saveAsList = True
+        ender = stopOn
+        if isinstance(ender, basestring):
+            ender = ParserElement._literalStringClass(ender)
+        self.not_ender = ~ender if ender is not None else None
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        self_expr_parse = self.expr._parse
+        self_skip_ignorables = self._skipIgnorables
+        check_ender = self.not_ender is not None
+        if check_ender:
+            try_not_ender = self.not_ender.tryParse
+        
+        # must be at least one (but first see if we are the stopOn sentinel;
+        # if so, fail)
+        if check_ender:
+            try_not_ender(instring, loc)
+        loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False )
+        try:
+            hasIgnoreExprs = (not not self.ignoreExprs)
+            while 1:
+                if check_ender:
+                    try_not_ender(instring, loc)
+                if hasIgnoreExprs:
+                    preloc = self_skip_ignorables( instring, loc )
+                else:
+                    preloc = loc
+                loc, tmptokens = self_expr_parse( instring, preloc, doActions )
+                if tmptokens or tmptokens.haskeys():
+                    tokens += tmptokens
+        except (ParseException,IndexError):
+            pass
+
+        return loc, tokens
+        
+class OneOrMore(_MultipleMatch):
+    """
+    Repetition of one or more of the given expression.
+    
+    Parameters:
+     - expr - expression that must match one or more times
+     - stopOn - (default=C{None}) - expression for a terminating sentinel
+          (only required if the sentinel would ordinarily match the repetition 
+          expression)          
+
+    Example::
+        data_word = Word(alphas)
+        label = data_word + FollowedBy(':')
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join))
+
+        text = "shape: SQUARE posn: upper left color: BLACK"
+        OneOrMore(attr_expr).parseString(text).pprint()  # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']]
+
+        # use stopOn attribute for OneOrMore to avoid reading label string as part of the data
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']]
+        
+        # could also be written as
+        (attr_expr * (1,)).parseString(text).pprint()
+    """
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + _ustr(self.expr) + "}..."
+
+        return self.strRepr
+
+class ZeroOrMore(_MultipleMatch):
+    """
+    Optional repetition of zero or more of the given expression.
+    
+    Parameters:
+     - expr - expression that must match zero or more times
+     - stopOn - (default=C{None}) - expression for a terminating sentinel
+          (only required if the sentinel would ordinarily match the repetition 
+          expression)          
+
+    Example: similar to L{OneOrMore}
+    """
+    def __init__( self, expr, stopOn=None):
+        super(ZeroOrMore,self).__init__(expr, stopOn=stopOn)
+        self.mayReturnEmpty = True
+        
+    def parseImpl( self, instring, loc, doActions=True ):
+        try:
+            return super(ZeroOrMore, self).parseImpl(instring, loc, doActions)
+        except (ParseException,IndexError):
+            return loc, []
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "[" + _ustr(self.expr) + "]..."
+
+        return self.strRepr
+
+class _NullToken(object):
+    def __bool__(self):
+        return False
+    __nonzero__ = __bool__
+    def __str__(self):
+        return ""
+
+_optionalNotMatched = _NullToken()
+class Optional(ParseElementEnhance):
+    """
+    Optional matching of the given expression.
+
+    Parameters:
+     - expr - expression that must match zero or more times
+     - default (optional) - value to be returned if the optional expression is not found.
+
+    Example::
+        # US postal code can be a 5-digit zip, plus optional 4-digit qualifier
+        zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4)))
+        zip.runTests('''
+            # traditional ZIP code
+            12345
+            
+            # ZIP+4 form
+            12101-0001
+            
+            # invalid ZIP
+            98765-
+            ''')
+    prints::
+        # traditional ZIP code
+        12345
+        ['12345']
+
+        # ZIP+4 form
+        12101-0001
+        ['12101-0001']
+
+        # invalid ZIP
+        98765-
+             ^
+        FAIL: Expected end of text (at char 5), (line:1, col:6)
+    """
+    def __init__( self, expr, default=_optionalNotMatched ):
+        super(Optional,self).__init__( expr, savelist=False )
+        self.saveAsList = self.expr.saveAsList
+        self.defaultValue = default
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        try:
+            loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False )
+        except (ParseException,IndexError):
+            if self.defaultValue is not _optionalNotMatched:
+                if self.expr.resultsName:
+                    tokens = ParseResults([ self.defaultValue ])
+                    tokens[self.expr.resultsName] = self.defaultValue
+                else:
+                    tokens = [ self.defaultValue ]
+            else:
+                tokens = []
+        return loc, tokens
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "[" + _ustr(self.expr) + "]"
+
+        return self.strRepr
+
+class SkipTo(ParseElementEnhance):
+    """
+    Token for skipping over all undefined text until the matched expression is found.
+
+    Parameters:
+     - expr - target expression marking the end of the data to be skipped
+     - include - (default=C{False}) if True, the target expression is also parsed 
+          (the skipped text and target expression are returned as a 2-element list).
+     - ignore - (default=C{None}) used to define grammars (typically quoted strings and 
+          comments) that might contain false matches to the target expression
+     - failOn - (default=C{None}) define expressions that are not allowed to be 
+          included in the skipped test; if found before the target expression is found, 
+          the SkipTo is not a match
+
+    Example::
+        report = '''
+            Outstanding Issues Report - 1 Jan 2000
+
+               # | Severity | Description                               |  Days Open
+            -----+----------+-------------------------------------------+-----------
+             101 | Critical | Intermittent system crash                 |          6
+              94 | Cosmetic | Spelling error on Login ('log|n')         |         14
+              79 | Minor    | System slow when running too many reports |         47
+            '''
+        integer = Word(nums)
+        SEP = Suppress('|')
+        # use SkipTo to simply match everything up until the next SEP
+        # - ignore quoted strings, so that a '|' character inside a quoted string does not match
+        # - parse action will call token.strip() for each matched token, i.e., the description body
+        string_data = SkipTo(SEP, ignore=quotedString)
+        string_data.setParseAction(tokenMap(str.strip))
+        ticket_expr = (integer("issue_num") + SEP 
+                      + string_data("sev") + SEP 
+                      + string_data("desc") + SEP 
+                      + integer("days_open"))
+        
+        for tkt in ticket_expr.searchString(report):
+            print tkt.dump()
+    prints::
+        ['101', 'Critical', 'Intermittent system crash', '6']
+        - days_open: 6
+        - desc: Intermittent system crash
+        - issue_num: 101
+        - sev: Critical
+        ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14']
+        - days_open: 14
+        - desc: Spelling error on Login ('log|n')
+        - issue_num: 94
+        - sev: Cosmetic
+        ['79', 'Minor', 'System slow when running too many reports', '47']
+        - days_open: 47
+        - desc: System slow when running too many reports
+        - issue_num: 79
+        - sev: Minor
+    """
+    def __init__( self, other, include=False, ignore=None, failOn=None ):
+        super( SkipTo, self ).__init__( other )
+        self.ignoreExpr = ignore
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+        self.includeMatch = include
+        self.asList = False
+        if isinstance(failOn, basestring):
+            self.failOn = ParserElement._literalStringClass(failOn)
+        else:
+            self.failOn = failOn
+        self.errmsg = "No match found for "+_ustr(self.expr)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        startloc = loc
+        instrlen = len(instring)
+        expr = self.expr
+        expr_parse = self.expr._parse
+        self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None
+        self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None
+        
+        tmploc = loc
+        while tmploc <= instrlen:
+            if self_failOn_canParseNext is not None:
+                # break if failOn expression matches
+                if self_failOn_canParseNext(instring, tmploc):
+                    break
+                    
+            if self_ignoreExpr_tryParse is not None:
+                # advance past ignore expressions
+                while 1:
+                    try:
+                        tmploc = self_ignoreExpr_tryParse(instring, tmploc)
+                    except ParseBaseException:
+                        break
+            
+            try:
+                expr_parse(instring, tmploc, doActions=False, callPreParse=False)
+            except (ParseException, IndexError):
+                # no match, advance loc in string
+                tmploc += 1
+            else:
+                # matched skipto expr, done
+                break
+
+        else:
+            # ran off the end of the input string without matching skipto expr, fail
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        # build up return values
+        loc = tmploc
+        skiptext = instring[startloc:loc]
+        skipresult = ParseResults(skiptext)
+        
+        if self.includeMatch:
+            loc, mat = expr_parse(instring,loc,doActions,callPreParse=False)
+            skipresult += mat
+
+        return loc, skipresult
+
+class Forward(ParseElementEnhance):
+    """
+    Forward declaration of an expression to be defined later -
+    used for recursive grammars, such as algebraic infix notation.
+    When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator.
+
+    Note: take care when assigning to C{Forward} not to overlook precedence of operators.
+    Specifically, '|' has a lower precedence than '<<', so that::
+        fwdExpr << a | b | c
+    will actually be evaluated as::
+        (fwdExpr << a) | b | c
+    thereby leaving b and c out as parseable alternatives.  It is recommended that you
+    explicitly group the values inserted into the C{Forward}::
+        fwdExpr << (a | b | c)
+    Converting to use the '<<=' operator instead will avoid this problem.
+
+    See L{ParseResults.pprint} for an example of a recursive parser created using
+    C{Forward}.
+    """
+    def __init__( self, other=None ):
+        super(Forward,self).__init__( other, savelist=False )
+
+    def __lshift__( self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass(other)
+        self.expr = other
+        self.strRepr = None
+        self.mayIndexError = self.expr.mayIndexError
+        self.mayReturnEmpty = self.expr.mayReturnEmpty
+        self.setWhitespaceChars( self.expr.whiteChars )
+        self.skipWhitespace = self.expr.skipWhitespace
+        self.saveAsList = self.expr.saveAsList
+        self.ignoreExprs.extend(self.expr.ignoreExprs)
+        return self
+        
+    def __ilshift__(self, other):
+        return self << other
+    
+    def leaveWhitespace( self ):
+        self.skipWhitespace = False
+        return self
+
+    def streamline( self ):
+        if not self.streamlined:
+            self.streamlined = True
+            if self.expr is not None:
+                self.expr.streamline()
+        return self
+
+    def validate( self, validateTrace=[] ):
+        if self not in validateTrace:
+            tmp = validateTrace[:]+[self]
+            if self.expr is not None:
+                self.expr.validate(tmp)
+        self.checkRecursion([])
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+        return self.__class__.__name__ + ": ..."
+
+        # stubbed out for now - creates awful memory and perf issues
+        self._revertClass = self.__class__
+        self.__class__ = _ForwardNoRecurse
+        try:
+            if self.expr is not None:
+                retString = _ustr(self.expr)
+            else:
+                retString = "None"
+        finally:
+            self.__class__ = self._revertClass
+        return self.__class__.__name__ + ": " + retString
+
+    def copy(self):
+        if self.expr is not None:
+            return super(Forward,self).copy()
+        else:
+            ret = Forward()
+            ret <<= self
+            return ret
+
+class _ForwardNoRecurse(Forward):
+    def __str__( self ):
+        return "..."
+
+class TokenConverter(ParseElementEnhance):
+    """
+    Abstract subclass of C{ParseExpression}, for converting parsed results.
+    """
+    def __init__( self, expr, savelist=False ):
+        super(TokenConverter,self).__init__( expr )#, savelist )
+        self.saveAsList = False
+
+class Combine(TokenConverter):
+    """
+    Converter to concatenate all matching tokens to a single string.
+    By default, the matching patterns must also be contiguous in the input string;
+    this can be disabled by specifying C{'adjacent=False'} in the constructor.
+
+    Example::
+        real = Word(nums) + '.' + Word(nums)
+        print(real.parseString('3.1416')) # -> ['3', '.', '1416']
+        # will also erroneously match the following
+        print(real.parseString('3. 1416')) # -> ['3', '.', '1416']
+
+        real = Combine(Word(nums) + '.' + Word(nums))
+        print(real.parseString('3.1416')) # -> ['3.1416']
+        # no match when there are internal spaces
+        print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...)
+    """
+    def __init__( self, expr, joinString="", adjacent=True ):
+        super(Combine,self).__init__( expr )
+        # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself
+        if adjacent:
+            self.leaveWhitespace()
+        self.adjacent = adjacent
+        self.skipWhitespace = True
+        self.joinString = joinString
+        self.callPreparse = True
+
+    def ignore( self, other ):
+        if self.adjacent:
+            ParserElement.ignore(self, other)
+        else:
+            super( Combine, self).ignore( other )
+        return self
+
+    def postParse( self, instring, loc, tokenlist ):
+        retToks = tokenlist.copy()
+        del retToks[:]
+        retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults)
+
+        if self.resultsName and retToks.haskeys():
+            return [ retToks ]
+        else:
+            return retToks
+
+class Group(TokenConverter):
+    """
+    Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions.
+
+    Example::
+        ident = Word(alphas)
+        num = Word(nums)
+        term = ident | num
+        func = ident + Optional(delimitedList(term))
+        print(func.parseString("fn a,b,100"))  # -> ['fn', 'a', 'b', '100']
+
+        func = ident + Group(Optional(delimitedList(term)))
+        print(func.parseString("fn a,b,100"))  # -> ['fn', ['a', 'b', '100']]
+    """
+    def __init__( self, expr ):
+        super(Group,self).__init__( expr )
+        self.saveAsList = True
+
+    def postParse( self, instring, loc, tokenlist ):
+        return [ tokenlist ]
+
+class Dict(TokenConverter):
+    """
+    Converter to return a repetitive expression as a list, but also as a dictionary.
+    Each element can also be referenced using the first token in the expression as its key.
+    Useful for tabular report scraping when the first column can be used as a item key.
+
+    Example::
+        data_word = Word(alphas)
+        label = data_word + FollowedBy(':')
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join))
+
+        text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
+        attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        
+        # print attributes as plain groups
+        print(OneOrMore(attr_expr).parseString(text).dump())
+        
+        # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names
+        result = Dict(OneOrMore(Group(attr_expr))).parseString(text)
+        print(result.dump())
+        
+        # access named fields as dict entries, or output as dict
+        print(result['shape'])        
+        print(result.asDict())
+    prints::
+        ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap']
+
+        [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
+        - color: light blue
+        - posn: upper left
+        - shape: SQUARE
+        - texture: burlap
+        SQUARE
+        {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'}
+    See more examples at L{ParseResults} of accessing fields by results name.
+    """
+    def __init__( self, expr ):
+        super(Dict,self).__init__( expr )
+        self.saveAsList = True
+
+    def postParse( self, instring, loc, tokenlist ):
+        for i,tok in enumerate(tokenlist):
+            if len(tok) == 0:
+                continue
+            ikey = tok[0]
+            if isinstance(ikey,int):
+                ikey = _ustr(tok[0]).strip()
+            if len(tok)==1:
+                tokenlist[ikey] = _ParseResultsWithOffset("",i)
+            elif len(tok)==2 and not isinstance(tok[1],ParseResults):
+                tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i)
+            else:
+                dictvalue = tok.copy() #ParseResults(i)
+                del dictvalue[0]
+                if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()):
+                    tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i)
+                else:
+                    tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i)
+
+        if self.resultsName:
+            return [ tokenlist ]
+        else:
+            return tokenlist
+
+
+class Suppress(TokenConverter):
+    """
+    Converter for ignoring the results of a parsed expression.
+
+    Example::
+        source = "a, b, c,d"
+        wd = Word(alphas)
+        wd_list1 = wd + ZeroOrMore(',' + wd)
+        print(wd_list1.parseString(source))
+
+        # often, delimiters that are useful during parsing are just in the
+        # way afterward - use Suppress to keep them out of the parsed output
+        wd_list2 = wd + ZeroOrMore(Suppress(',') + wd)
+        print(wd_list2.parseString(source))
+    prints::
+        ['a', ',', 'b', ',', 'c', ',', 'd']
+        ['a', 'b', 'c', 'd']
+    (See also L{delimitedList}.)
+    """
+    def postParse( self, instring, loc, tokenlist ):
+        return []
+
+    def suppress( self ):
+        return self
+
+
+class OnlyOnce(object):
+    """
+    Wrapper for parse actions, to ensure they are only called once.
+    """
+    def __init__(self, methodCall):
+        self.callable = _trim_arity(methodCall)
+        self.called = False
+    def __call__(self,s,l,t):
+        if not self.called:
+            results = self.callable(s,l,t)
+            self.called = True
+            return results
+        raise ParseException(s,l,"")
+    def reset(self):
+        self.called = False
+
+def traceParseAction(f):
+    """
+    Decorator for debugging parse actions. 
+    
+    When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".}
+    When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised.
+
+    Example::
+        wd = Word(alphas)
+
+        @traceParseAction
+        def remove_duplicate_chars(tokens):
+            return ''.join(sorted(set(''.join(tokens)))
+
+        wds = OneOrMore(wd).setParseAction(remove_duplicate_chars)
+        print(wds.parseString("slkdjs sld sldd sdlf sdljf"))
+    prints::
+        >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {}))
+        <<leaving remove_duplicate_chars (ret: 'dfjkls')
+        ['dfjkls']
+    """
+    f = _trim_arity(f)
+    def z(*paArgs):
+        thisFunc = f.__name__
+        s,l,t = paArgs[-3:]
+        if len(paArgs)>3:
+            thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc
+        sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) )
+        try:
+            ret = f(*paArgs)
+        except Exception as exc:
+            sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) )
+            raise
+        sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) )
+        return ret
+    try:
+        z.__name__ = f.__name__
+    except AttributeError:
+        pass
+    return z
+
+#
+# global helpers
+#
+def delimitedList( expr, delim=",", combine=False ):
+    """
+    Helper to define a delimited list of expressions - the delimiter defaults to ','.
+    By default, the list elements and delimiters can have intervening whitespace, and
+    comments, but this can be overridden by passing C{combine=True} in the constructor.
+    If C{combine} is set to C{True}, the matching tokens are returned as a single token
+    string, with the delimiters included; otherwise, the matching tokens are returned
+    as a list of tokens, with the delimiters suppressed.
+
+    Example::
+        delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc']
+        delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE']
+    """
+    dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..."
+    if combine:
+        return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName)
+    else:
+        return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName)
+
+def countedArray( expr, intExpr=None ):
+    """
+    Helper to define a counted list of expressions.
+    This helper defines a pattern of the form::
+        integer expr expr expr...
+    where the leading integer tells how many expr expressions follow.
+    The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed.
+    
+    If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value.
+
+    Example::
+        countedArray(Word(alphas)).parseString('2 ab cd ef')  # -> ['ab', 'cd']
+
+        # in this parser, the leading integer value is given in binary,
+        # '10' indicating that 2 values are in the array
+        binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2))
+        countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef')  # -> ['ab', 'cd']
+    """
+    arrayExpr = Forward()
+    def countFieldParseAction(s,l,t):
+        n = t[0]
+        arrayExpr << (n and Group(And([expr]*n)) or Group(empty))
+        return []
+    if intExpr is None:
+        intExpr = Word(nums).setParseAction(lambda t:int(t[0]))
+    else:
+        intExpr = intExpr.copy()
+    intExpr.setName("arrayLen")
+    intExpr.addParseAction(countFieldParseAction, callDuringTry=True)
+    return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...')
+
+def _flatten(L):
+    ret = []
+    for i in L:
+        if isinstance(i,list):
+            ret.extend(_flatten(i))
+        else:
+            ret.append(i)
+    return ret
+
+def matchPreviousLiteral(expr):
+    """
+    Helper to define an expression that is indirectly defined from
+    the tokens matched in a previous expression, that is, it looks
+    for a 'repeat' of a previous expression.  For example::
+        first = Word(nums)
+        second = matchPreviousLiteral(first)
+        matchExpr = first + ":" + second
+    will match C{"1:1"}, but not C{"1:2"}.  Because this matches a
+    previous literal, will also match the leading C{"1:1"} in C{"1:10"}.
+    If this is not desired, use C{matchPreviousExpr}.
+    Do I{not} use with packrat parsing enabled.
+    """
+    rep = Forward()
+    def copyTokenToRepeater(s,l,t):
+        if t:
+            if len(t) == 1:
+                rep << t[0]
+            else:
+                # flatten t tokens
+                tflat = _flatten(t.asList())
+                rep << And(Literal(tt) for tt in tflat)
+        else:
+            rep << Empty()
+    expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
+    rep.setName('(prev) ' + _ustr(expr))
+    return rep
+
+def matchPreviousExpr(expr):
+    """
+    Helper to define an expression that is indirectly defined from
+    the tokens matched in a previous expression, that is, it looks
+    for a 'repeat' of a previous expression.  For example::
+        first = Word(nums)
+        second = matchPreviousExpr(first)
+        matchExpr = first + ":" + second
+    will match C{"1:1"}, but not C{"1:2"}.  Because this matches by
+    expressions, will I{not} match the leading C{"1:1"} in C{"1:10"};
+    the expressions are evaluated first, and then compared, so
+    C{"1"} is compared with C{"10"}.
+    Do I{not} use with packrat parsing enabled.
+    """
+    rep = Forward()
+    e2 = expr.copy()
+    rep <<= e2
+    def copyTokenToRepeater(s,l,t):
+        matchTokens = _flatten(t.asList())
+        def mustMatchTheseTokens(s,l,t):
+            theseTokens = _flatten(t.asList())
+            if  theseTokens != matchTokens:
+                raise ParseException("",0,"")
+        rep.setParseAction( mustMatchTheseTokens, callDuringTry=True )
+    expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
+    rep.setName('(prev) ' + _ustr(expr))
+    return rep
+
+def _escapeRegexRangeChars(s):
+    #~  escape these chars: ^-]
+    for c in r"\^-]":
+        s = s.replace(c,_bslash+c)
+    s = s.replace("\n",r"\n")
+    s = s.replace("\t",r"\t")
+    return _ustr(s)
+
+def oneOf( strs, caseless=False, useRegex=True ):
+    """
+    Helper to quickly define a set of alternative Literals, and makes sure to do
+    longest-first testing when there is a conflict, regardless of the input order,
+    but returns a C{L{MatchFirst}} for best performance.
+
+    Parameters:
+     - strs - a string of space-delimited literals, or a collection of string literals
+     - caseless - (default=C{False}) - treat all literals as caseless
+     - useRegex - (default=C{True}) - as an optimization, will generate a Regex
+          object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or
+          if creating a C{Regex} raises an exception)
+
+    Example::
+        comp_oper = oneOf("< = > <= >= !=")
+        var = Word(alphas)
+        number = Word(nums)
+        term = var | number
+        comparison_expr = term + comp_oper + term
+        print(comparison_expr.searchString("B = 12  AA=23 B<=AA AA>12"))
+    prints::
+        [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']]
+    """
+    if caseless:
+        isequal = ( lambda a,b: a.upper() == b.upper() )
+        masks = ( lambda a,b: b.upper().startswith(a.upper()) )
+        parseElementClass = CaselessLiteral
+    else:
+        isequal = ( lambda a,b: a == b )
+        masks = ( lambda a,b: b.startswith(a) )
+        parseElementClass = Literal
+
+    symbols = []
+    if isinstance(strs,basestring):
+        symbols = strs.split()
+    elif isinstance(strs, collections.Iterable):
+        symbols = list(strs)
+    else:
+        warnings.warn("Invalid argument to oneOf, expected string or iterable",
+                SyntaxWarning, stacklevel=2)
+    if not symbols:
+        return NoMatch()
+
+    i = 0
+    while i < len(symbols)-1:
+        cur = symbols[i]
+        for j,other in enumerate(symbols[i+1:]):
+            if ( isequal(other, cur) ):
+                del symbols[i+j+1]
+                break
+            elif ( masks(cur, other) ):
+                del symbols[i+j+1]
+                symbols.insert(i,other)
+                cur = other
+                break
+        else:
+            i += 1
+
+    if not caseless and useRegex:
+        #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] ))
+        try:
+            if len(symbols)==len("".join(symbols)):
+                return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols))
+            else:
+                return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols))
+        except Exception:
+            warnings.warn("Exception creating Regex for oneOf, building MatchFirst",
+                    SyntaxWarning, stacklevel=2)
+
+
+    # last resort, just use MatchFirst
+    return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols))
+
+def dictOf( key, value ):
+    """
+    Helper to easily and clearly define a dictionary by specifying the respective patterns
+    for the key and value.  Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens
+    in the proper order.  The key pattern can include delimiting markers or punctuation,
+    as long as they are suppressed, thereby leaving the significant key text.  The value
+    pattern can include named results, so that the C{Dict} results can include named token
+    fields.
+
+    Example::
+        text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
+        attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        print(OneOrMore(attr_expr).parseString(text).dump())
+        
+        attr_label = label
+        attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)
+
+        # similar to Dict, but simpler call format
+        result = dictOf(attr_label, attr_value).parseString(text)
+        print(result.dump())
+        print(result['shape'])
+        print(result.shape)  # object attribute access works too
+        print(result.asDict())
+    prints::
+        [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
+        - color: light blue
+        - posn: upper left
+        - shape: SQUARE
+        - texture: burlap
+        SQUARE
+        SQUARE
+        {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'}
+    """
+    return Dict( ZeroOrMore( Group ( key + value ) ) )
+
+def originalTextFor(expr, asString=True):
+    """
+    Helper to return the original, untokenized text for a given expression.  Useful to
+    restore the parsed fields of an HTML start tag into the raw tag text itself, or to
+    revert separate tokens with intervening whitespace back to the original matching
+    input text. By default, returns astring containing the original parsed text.  
+       
+    If the optional C{asString} argument is passed as C{False}, then the return value is a 
+    C{L{ParseResults}} containing any results names that were originally matched, and a 
+    single token containing the original matched text from the input string.  So if 
+    the expression passed to C{L{originalTextFor}} contains expressions with defined
+    results names, you must set C{asString} to C{False} if you want to preserve those
+    results name values.
+
+    Example::
+        src = "this is test <b> bold <i>text</i> </b> normal text "
+        for tag in ("b","i"):
+            opener,closer = makeHTMLTags(tag)
+            patt = originalTextFor(opener + SkipTo(closer) + closer)
+            print(patt.searchString(src)[0])
+    prints::
+        ['<b> bold <i>text</i> </b>']
+        ['<i>text</i>']
+    """
+    locMarker = Empty().setParseAction(lambda s,loc,t: loc)
+    endlocMarker = locMarker.copy()
+    endlocMarker.callPreparse = False
+    matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end")
+    if asString:
+        extractText = lambda s,l,t: s[t._original_start:t._original_end]
+    else:
+        def extractText(s,l,t):
+            t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]]
+    matchExpr.setParseAction(extractText)
+    matchExpr.ignoreExprs = expr.ignoreExprs
+    return matchExpr
+
+def ungroup(expr): 
+    """
+    Helper to undo pyparsing's default grouping of And expressions, even
+    if all but one are non-empty.
+    """
+    return TokenConverter(expr).setParseAction(lambda t:t[0])
+
+def locatedExpr(expr):
+    """
+    Helper to decorate a returned token with its starting and ending locations in the input string.
+    This helper adds the following results names:
+     - locn_start = location where matched expression begins
+     - locn_end = location where matched expression ends
+     - value = the actual parsed results
+
+    Be careful if the input text contains C{<TAB>} characters, you may want to call
+    C{L{ParserElement.parseWithTabs}}
+
+    Example::
+        wd = Word(alphas)
+        for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"):
+            print(match)
+    prints::
+        [[0, 'ljsdf', 5]]
+        [[8, 'lksdjjf', 15]]
+        [[18, 'lkkjj', 23]]
+    """
+    locator = Empty().setParseAction(lambda s,l,t: l)
+    return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end"))
+
+
+# convenience constants for positional expressions
+empty       = Empty().setName("empty")
+lineStart   = LineStart().setName("lineStart")
+lineEnd     = LineEnd().setName("lineEnd")
+stringStart = StringStart().setName("stringStart")
+stringEnd   = StringEnd().setName("stringEnd")
+
+_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1])
+_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16)))
+_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8)))
+_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(printables, excludeChars=r'\]', exact=1) | Regex(r"\w", re.UNICODE)
+_charRange = Group(_singleChar + Suppress("-") + _singleChar)
+_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]"
+
+def srange(s):
+    r"""
+    Helper to easily define string ranges for use in Word construction.  Borrows
+    syntax from regexp '[]' string range definitions::
+        srange("[0-9]")   -> "0123456789"
+        srange("[a-z]")   -> "abcdefghijklmnopqrstuvwxyz"
+        srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_"
+    The input string must be enclosed in []'s, and the returned string is the expanded
+    character set joined into a single string.
+    The values enclosed in the []'s may be:
+     - a single character
+     - an escaped character with a leading backslash (such as C{\-} or C{\]})
+     - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) 
+         (C{\0x##} is also supported for backwards compatibility) 
+     - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character)
+     - a range of any of the above, separated by a dash (C{'a-z'}, etc.)
+     - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.)
+    """
+    _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1))
+    try:
+        return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body)
+    except Exception:
+        return ""
+
+def matchOnlyAtCol(n):
+    """
+    Helper method for defining parse actions that require matching at a specific
+    column in the input text.
+    """
+    def verifyCol(strg,locn,toks):
+        if col(locn,strg) != n:
+            raise ParseException(strg,locn,"matched token not at column %d" % n)
+    return verifyCol
+
+def replaceWith(replStr):
+    """
+    Helper method for common parse actions that simply return a literal value.  Especially
+    useful when used with C{L{transformString<ParserElement.transformString>}()}.
+
+    Example::
+        num = Word(nums).setParseAction(lambda toks: int(toks[0]))
+        na = oneOf("N/A NA").setParseAction(replaceWith(math.nan))
+        term = na | num
+        
+        OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234]
+    """
+    return lambda s,l,t: [replStr]
+
+def removeQuotes(s,l,t):
+    """
+    Helper parse action for removing quotation marks from parsed quoted strings.
+
+    Example::
+        # by default, quotation marks are included in parsed results
+        quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"]
+
+        # use removeQuotes to strip quotation marks from parsed results
+        quotedString.setParseAction(removeQuotes)
+        quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"]
+    """
+    return t[0][1:-1]
+
+def tokenMap(func, *args):
+    """
+    Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional 
+    args are passed, they are forwarded to the given function as additional arguments after
+    the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the
+    parsed data to an integer using base 16.
+
+    Example (compare the last to example in L{ParserElement.transformString}::
+        hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16))
+        hex_ints.runTests('''
+            00 11 22 aa FF 0a 0d 1a
+            ''')
+        
+        upperword = Word(alphas).setParseAction(tokenMap(str.upper))
+        OneOrMore(upperword).runTests('''
+            my kingdom for a horse
+            ''')
+
+        wd = Word(alphas).setParseAction(tokenMap(str.title))
+        OneOrMore(wd).setParseAction(' '.join).runTests('''
+            now is the winter of our discontent made glorious summer by this sun of york
+            ''')
+    prints::
+        00 11 22 aa FF 0a 0d 1a
+        [0, 17, 34, 170, 255, 10, 13, 26]
+
+        my kingdom for a horse
+        ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE']
+
+        now is the winter of our discontent made glorious summer by this sun of york
+        ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York']
+    """
+    def pa(s,l,t):
+        return [func(tokn, *args) for tokn in t]
+
+    try:
+        func_name = getattr(func, '__name__', 
+                            getattr(func, '__class__').__name__)
+    except Exception:
+        func_name = str(func)
+    pa.__name__ = func_name
+
+    return pa
+
+upcaseTokens = tokenMap(lambda t: _ustr(t).upper())
+"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}"""
+
+downcaseTokens = tokenMap(lambda t: _ustr(t).lower())
+"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}"""
+    
+def _makeTags(tagStr, xml):
+    """Internal helper to construct opening and closing tag expressions, given a tag name"""
+    if isinstance(tagStr,basestring):
+        resname = tagStr
+        tagStr = Keyword(tagStr, caseless=not xml)
+    else:
+        resname = tagStr.name
+
+    tagAttrName = Word(alphas,alphanums+"_-:")
+    if (xml):
+        tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes )
+        openTag = Suppress("<") + tagStr("tag") + \
+                Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \
+                Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
+    else:
+        printablesLessRAbrack = "".join(c for c in printables if c not in ">")
+        tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack)
+        openTag = Suppress("<") + tagStr("tag") + \
+                Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \
+                Optional( Suppress("=") + tagAttrValue ) ))) + \
+                Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
+    closeTag = Combine(_L("</") + tagStr + ">")
+
+    openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname)
+    closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname)
+    openTag.tag = resname
+    closeTag.tag = resname
+    return openTag, closeTag
+
+def makeHTMLTags(tagStr):
+    """
+    Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches
+    tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values.
+
+    Example::
+        text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>'
+        # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple
+        a,a_end = makeHTMLTags("A")
+        link_expr = a + SkipTo(a_end)("link_text") + a_end
+        
+        for link in link_expr.searchString(text):
+            # attributes in the <A> tag (like "href" shown here) are also accessible as named results
+            print(link.link_text, '->', link.href)
+    prints::
+        pyparsing -> http://pyparsing.wikispaces.com
+    """
+    return _makeTags( tagStr, False )
+
+def makeXMLTags(tagStr):
+    """
+    Helper to construct opening and closing tag expressions for XML, given a tag name. Matches
+    tags only in the given upper/lower case.
+
+    Example: similar to L{makeHTMLTags}
+    """
+    return _makeTags( tagStr, True )
+
+def withAttribute(*args,**attrDict):
+    """
+    Helper to create a validating parse action to be used with start tags created
+    with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag
+    with a required attribute value, to avoid false matches on common tags such as
+    C{<TD>} or C{<DIV>}.
+
+    Call C{withAttribute} with a series of attribute names and values. Specify the list
+    of filter attributes names and values as:
+     - keyword arguments, as in C{(align="right")}, or
+     - as an explicit dict with C{**} operator, when an attribute name is also a Python
+          reserved word, as in C{**{"class":"Customer", "align":"right"}}
+     - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") )
+    For attribute names with a namespace prefix, you must use the second form.  Attribute
+    names are matched insensitive to upper/lower case.
+       
+    If just testing for C{class} (with or without a namespace), use C{L{withClass}}.
+
+    To verify that the attribute exists, but without specifying a value, pass
+    C{withAttribute.ANY_VALUE} as the value.
+
+    Example::
+        html = '''
+            <div>
+            Some text
+            <div type="grid">1 4 0 1 0</div>
+            <div type="graph">1,3 2,3 1,1</div>
+            <div>this has no type</div>
+            </div>
+                
+        '''
+        div,div_end = makeHTMLTags("div")
+
+        # only match div tag having a type attribute with value "grid"
+        div_grid = div().setParseAction(withAttribute(type="grid"))
+        grid_expr = div_grid + SkipTo(div | div_end)("body")
+        for grid_header in grid_expr.searchString(html):
+            print(grid_header.body)
+        
+        # construct a match with any div tag having a type attribute, regardless of the value
+        div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE))
+        div_expr = div_any_type + SkipTo(div | div_end)("body")
+        for div_header in div_expr.searchString(html):
+            print(div_header.body)
+    prints::
+        1 4 0 1 0
+
+        1 4 0 1 0
+        1,3 2,3 1,1
+    """
+    if args:
+        attrs = args[:]
+    else:
+        attrs = attrDict.items()
+    attrs = [(k,v) for k,v in attrs]
+    def pa(s,l,tokens):
+        for attrName,attrValue in attrs:
+            if attrName not in tokens:
+                raise ParseException(s,l,"no matching attribute " + attrName)
+            if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue:
+                raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" %
+                                            (attrName, tokens[attrName], attrValue))
+    return pa
+withAttribute.ANY_VALUE = object()
+
+def withClass(classname, namespace=''):
+    """
+    Simplified version of C{L{withAttribute}} when matching on a div class - made
+    difficult because C{class} is a reserved word in Python.
+
+    Example::
+        html = '''
+            <div>
+            Some text
+            <div class="grid">1 4 0 1 0</div>
+            <div class="graph">1,3 2,3 1,1</div>
+            <div>this &lt;div&gt; has no class</div>
+            </div>
+                
+        '''
+        div,div_end = makeHTMLTags("div")
+        div_grid = div().setParseAction(withClass("grid"))
+        
+        grid_expr = div_grid + SkipTo(div | div_end)("body")
+        for grid_header in grid_expr.searchString(html):
+            print(grid_header.body)
+        
+        div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE))
+        div_expr = div_any_type + SkipTo(div | div_end)("body")
+        for div_header in div_expr.searchString(html):
+            print(div_header.body)
+    prints::
+        1 4 0 1 0
+
+        1 4 0 1 0
+        1,3 2,3 1,1
+    """
+    classattr = "%s:class" % namespace if namespace else "class"
+    return withAttribute(**{classattr : classname})        
+
+opAssoc = _Constants()
+opAssoc.LEFT = object()
+opAssoc.RIGHT = object()
+
+def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ):
+    """
+    Helper method for constructing grammars of expressions made up of
+    operators working in a precedence hierarchy.  Operators may be unary or
+    binary, left- or right-associative.  Parse actions can also be attached
+    to operator expressions. The generated parser will also recognize the use 
+    of parentheses to override operator precedences (see example below).
+    
+    Note: if you define a deep operator list, you may see performance issues
+    when using infixNotation. See L{ParserElement.enablePackrat} for a
+    mechanism to potentially improve your parser performance.
+
+    Parameters:
+     - baseExpr - expression representing the most basic element for the nested
+     - opList - list of tuples, one for each operator precedence level in the
+      expression grammar; each tuple is of the form
+      (opExpr, numTerms, rightLeftAssoc, parseAction), where:
+       - opExpr is the pyparsing expression for the operator;
+          may also be a string, which will be converted to a Literal;
+          if numTerms is 3, opExpr is a tuple of two expressions, for the
+          two operators separating the 3 terms
+       - numTerms is the number of terms for this operator (must
+          be 1, 2, or 3)
+       - rightLeftAssoc is the indicator whether the operator is
+          right or left associative, using the pyparsing-defined
+          constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}.
+       - parseAction is the parse action to be associated with
+          expressions matching this operator expression (the
+          parse action tuple member may be omitted)
+     - lpar - expression for matching left-parentheses (default=C{Suppress('(')})
+     - rpar - expression for matching right-parentheses (default=C{Suppress(')')})
+
+    Example::
+        # simple example of four-function arithmetic with ints and variable names
+        integer = pyparsing_common.signed_integer
+        varname = pyparsing_common.identifier 
+        
+        arith_expr = infixNotation(integer | varname,
+            [
+            ('-', 1, opAssoc.RIGHT),
+            (oneOf('* /'), 2, opAssoc.LEFT),
+            (oneOf('+ -'), 2, opAssoc.LEFT),
+            ])
+        
+        arith_expr.runTests('''
+            5+3*6
+            (5+3)*6
+            -2--11
+            ''', fullDump=False)
+    prints::
+        5+3*6
+        [[5, '+', [3, '*', 6]]]
+
+        (5+3)*6
+        [[[5, '+', 3], '*', 6]]
+
+        -2--11
+        [[['-', 2], '-', ['-', 11]]]
+    """
+    ret = Forward()
+    lastExpr = baseExpr | ( lpar + ret + rpar )
+    for i,operDef in enumerate(opList):
+        opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4]
+        termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr
+        if arity == 3:
+            if opExpr is None or len(opExpr) != 2:
+                raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions")
+            opExpr1, opExpr2 = opExpr
+        thisExpr = Forward().setName(termName)
+        if rightLeftAssoc == opAssoc.LEFT:
+            if arity == 1:
+                matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) )
+            elif arity == 2:
+                if opExpr is not None:
+                    matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) )
+                else:
+                    matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) )
+            elif arity == 3:
+                matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \
+                            Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr )
+            else:
+                raise ValueError("operator must be unary (1), binary (2), or ternary (3)")
+        elif rightLeftAssoc == opAssoc.RIGHT:
+            if arity == 1:
+                # try to avoid LR with this extra test
+                if not isinstance(opExpr, Optional):
+                    opExpr = Optional(opExpr)
+                matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr )
+            elif arity == 2:
+                if opExpr is not None:
+                    matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) )
+                else:
+                    matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) )
+            elif arity == 3:
+                matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \
+                            Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr )
+            else:
+                raise ValueError("operator must be unary (1), binary (2), or ternary (3)")
+        else:
+            raise ValueError("operator must indicate right or left associativity")
+        if pa:
+            matchExpr.setParseAction( pa )
+        thisExpr <<= ( matchExpr.setName(termName) | lastExpr )
+        lastExpr = thisExpr
+    ret <<= lastExpr
+    return ret
+
+operatorPrecedence = infixNotation
+"""(Deprecated) Former name of C{L{infixNotation}}, will be dropped in a future release."""
+
+dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes")
+sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes")
+quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'|
+                       Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes")
+unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal")
+
+def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()):
+    """
+    Helper method for defining nested lists enclosed in opening and closing
+    delimiters ("(" and ")" are the default).
+
+    Parameters:
+     - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression
+     - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression
+     - content - expression for items within the nested lists (default=C{None})
+     - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString})
+
+    If an expression is not provided for the content argument, the nested
+    expression will capture all whitespace-delimited content between delimiters
+    as a list of separate values.
+
+    Use the C{ignoreExpr} argument to define expressions that may contain
+    opening or closing characters that should not be treated as opening
+    or closing characters for nesting, such as quotedString or a comment
+    expression.  Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}.
+    The default is L{quotedString}, but if no expressions are to be ignored,
+    then pass C{None} for this argument.
+
+    Example::
+        data_type = oneOf("void int short long char float double")
+        decl_data_type = Combine(data_type + Optional(Word('*')))
+        ident = Word(alphas+'_', alphanums+'_')
+        number = pyparsing_common.number
+        arg = Group(decl_data_type + ident)
+        LPAR,RPAR = map(Suppress, "()")
+
+        code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment))
+
+        c_function = (decl_data_type("type") 
+                      + ident("name")
+                      + LPAR + Optional(delimitedList(arg), [])("args") + RPAR 
+                      + code_body("body"))
+        c_function.ignore(cStyleComment)
+        
+        source_code = '''
+            int is_odd(int x) { 
+                return (x%2); 
+            }
+                
+            int dec_to_hex(char hchar) { 
+                if (hchar >= '0' && hchar <= '9') { 
+                    return (ord(hchar)-ord('0')); 
+                } else { 
+                    return (10+ord(hchar)-ord('A'));
+                } 
+            }
+        '''
+        for func in c_function.searchString(source_code):
+            print("%(name)s (%(type)s) args: %(args)s" % func)
+
+    prints::
+        is_odd (int) args: [['int', 'x']]
+        dec_to_hex (int) args: [['char', 'hchar']]
+    """
+    if opener == closer:
+        raise ValueError("opening and closing strings cannot be the same")
+    if content is None:
+        if isinstance(opener,basestring) and isinstance(closer,basestring):
+            if len(opener) == 1 and len(closer)==1:
+                if ignoreExpr is not None:
+                    content = (Combine(OneOrMore(~ignoreExpr +
+                                    CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1))
+                                ).setParseAction(lambda t:t[0].strip()))
+                else:
+                    content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS
+                                ).setParseAction(lambda t:t[0].strip()))
+            else:
+                if ignoreExpr is not None:
+                    content = (Combine(OneOrMore(~ignoreExpr + 
+                                    ~Literal(opener) + ~Literal(closer) +
+                                    CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1))
+                                ).setParseAction(lambda t:t[0].strip()))
+                else:
+                    content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) +
+                                    CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1))
+                                ).setParseAction(lambda t:t[0].strip()))
+        else:
+            raise ValueError("opening and closing arguments must be strings if no content expression is given")
+    ret = Forward()
+    if ignoreExpr is not None:
+        ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) )
+    else:
+        ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content )  + Suppress(closer) )
+    ret.setName('nested %s%s expression' % (opener,closer))
+    return ret
+
+def indentedBlock(blockStatementExpr, indentStack, indent=True):
+    """
+    Helper method for defining space-delimited indentation blocks, such as
+    those used to define block statements in Python source code.
+
+    Parameters:
+     - blockStatementExpr - expression defining syntax of statement that
+            is repeated within the indented block
+     - indentStack - list created by caller to manage indentation stack
+            (multiple statementWithIndentedBlock expressions within a single grammar
+            should share a common indentStack)
+     - indent - boolean indicating whether block must be indented beyond the
+            the current level; set to False for block of left-most statements
+            (default=C{True})
+
+    A valid block must contain at least one C{blockStatement}.
+
+    Example::
+        data = '''
+        def A(z):
+          A1
+          B = 100
+          G = A2
+          A2
+          A3
+        B
+        def BB(a,b,c):
+          BB1
+          def BBA():
+            bba1
+            bba2
+            bba3
+        C
+        D
+        def spam(x,y):
+             def eggs(z):
+                 pass
+        '''
+
+
+        indentStack = [1]
+        stmt = Forward()
+
+        identifier = Word(alphas, alphanums)
+        funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":")
+        func_body = indentedBlock(stmt, indentStack)
+        funcDef = Group( funcDecl + func_body )
+
+        rvalue = Forward()
+        funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")")
+        rvalue << (funcCall | identifier | Word(nums))
+        assignment = Group(identifier + "=" + rvalue)
+        stmt << ( funcDef | assignment | identifier )
+
+        module_body = OneOrMore(stmt)
+
+        parseTree = module_body.parseString(data)
+        parseTree.pprint()
+    prints::
+        [['def',
+          'A',
+          ['(', 'z', ')'],
+          ':',
+          [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]],
+         'B',
+         ['def',
+          'BB',
+          ['(', 'a', 'b', 'c', ')'],
+          ':',
+          [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]],
+         'C',
+         'D',
+         ['def',
+          'spam',
+          ['(', 'x', 'y', ')'],
+          ':',
+          [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] 
+    """
+    def checkPeerIndent(s,l,t):
+        if l >= len(s): return
+        curCol = col(l,s)
+        if curCol != indentStack[-1]:
+            if curCol > indentStack[-1]:
+                raise ParseFatalException(s,l,"illegal nesting")
+            raise ParseException(s,l,"not a peer entry")
+
+    def checkSubIndent(s,l,t):
+        curCol = col(l,s)
+        if curCol > indentStack[-1]:
+            indentStack.append( curCol )
+        else:
+            raise ParseException(s,l,"not a subentry")
+
+    def checkUnindent(s,l,t):
+        if l >= len(s): return
+        curCol = col(l,s)
+        if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]):
+            raise ParseException(s,l,"not an unindent")
+        indentStack.pop()
+
+    NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress())
+    INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT')
+    PEER   = Empty().setParseAction(checkPeerIndent).setName('')
+    UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT')
+    if indent:
+        smExpr = Group( Optional(NL) +
+            #~ FollowedBy(blockStatementExpr) +
+            INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT)
+    else:
+        smExpr = Group( Optional(NL) +
+            (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) )
+    blockStatementExpr.ignore(_bslash + LineEnd())
+    return smExpr.setName('indented block')
+
+alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]")
+punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]")
+
+anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag'))
+_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\''))
+commonHTMLEntity = Regex('&(?P<entity>' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity")
+def replaceHTMLEntity(t):
+    """Helper parser action to replace common HTML entities with their special characters"""
+    return _htmlEntityMap.get(t.entity)
+
+# it's easy to get these comment structures wrong - they're very common, so may as well make them available
+cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment")
+"Comment of the form C{/* ... */}"
+
+htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment")
+"Comment of the form C{<!-- ... -->}"
+
+restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line")
+dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment")
+"Comment of the form C{// ... (to end of line)}"
+
+cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment")
+"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}"
+
+javaStyleComment = cppStyleComment
+"Same as C{L{cppStyleComment}}"
+
+pythonStyleComment = Regex(r"#.*").setName("Python style comment")
+"Comment of the form C{# ... (to end of line)}"
+
+_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') +
+                                  Optional( Word(" \t") +
+                                            ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem")
+commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList")
+"""(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas.
+   This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}."""
+
+# some other useful expressions - using lower-case class name since we are really using this as a namespace
+class pyparsing_common:
+    """
+    Here are some common low-level expressions that may be useful in jump-starting parser development:
+     - numeric forms (L{integers<integer>}, L{reals<real>}, L{scientific notation<sci_real>})
+     - common L{programming identifiers<identifier>}
+     - network addresses (L{MAC<mac_address>}, L{IPv4<ipv4_address>}, L{IPv6<ipv6_address>})
+     - ISO8601 L{dates<iso8601_date>} and L{datetime<iso8601_datetime>}
+     - L{UUID<uuid>}
+     - L{comma-separated list<comma_separated_list>}
+    Parse actions:
+     - C{L{convertToInteger}}
+     - C{L{convertToFloat}}
+     - C{L{convertToDate}}
+     - C{L{convertToDatetime}}
+     - C{L{stripHTMLTags}}
+     - C{L{upcaseTokens}}
+     - C{L{downcaseTokens}}
+
+    Example::
+        pyparsing_common.number.runTests('''
+            # any int or real number, returned as the appropriate type
+            100
+            -100
+            +100
+            3.14159
+            6.02e23
+            1e-12
+            ''')
+
+        pyparsing_common.fnumber.runTests('''
+            # any int or real number, returned as float
+            100
+            -100
+            +100
+            3.14159
+            6.02e23
+            1e-12
+            ''')
+
+        pyparsing_common.hex_integer.runTests('''
+            # hex numbers
+            100
+            FF
+            ''')
+
+        pyparsing_common.fraction.runTests('''
+            # fractions
+            1/2
+            -3/4
+            ''')
+
+        pyparsing_common.mixed_integer.runTests('''
+            # mixed fractions
+            1
+            1/2
+            -3/4
+            1-3/4
+            ''')
+
+        import uuid
+        pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID))
+        pyparsing_common.uuid.runTests('''
+            # uuid
+            12345678-1234-5678-1234-567812345678
+            ''')
+    prints::
+        # any int or real number, returned as the appropriate type
+        100
+        [100]
+
+        -100
+        [-100]
+
+        +100
+        [100]
+
+        3.14159
+        [3.14159]
+
+        6.02e23
+        [6.02e+23]
+
+        1e-12
+        [1e-12]
+
+        # any int or real number, returned as float
+        100
+        [100.0]
+
+        -100
+        [-100.0]
+
+        +100
+        [100.0]
+
+        3.14159
+        [3.14159]
+
+        6.02e23
+        [6.02e+23]
+
+        1e-12
+        [1e-12]
+
+        # hex numbers
+        100
+        [256]
+
+        FF
+        [255]
+
+        # fractions
+        1/2
+        [0.5]
+
+        -3/4
+        [-0.75]
+
+        # mixed fractions
+        1
+        [1]
+
+        1/2
+        [0.5]
+
+        -3/4
+        [-0.75]
+
+        1-3/4
+        [1.75]
+
+        # uuid
+        12345678-1234-5678-1234-567812345678
+        [UUID('12345678-1234-5678-1234-567812345678')]
+    """
+
+    convertToInteger = tokenMap(int)
+    """
+    Parse action for converting parsed integers to Python int
+    """
+
+    convertToFloat = tokenMap(float)
+    """
+    Parse action for converting parsed numbers to Python float
+    """
+
+    integer = Word(nums).setName("integer").setParseAction(convertToInteger)
+    """expression that parses an unsigned integer, returns an int"""
+
+    hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16))
+    """expression that parses a hexadecimal integer, returns an int"""
+
+    signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger)
+    """expression that parses an integer with optional leading sign, returns an int"""
+
+    fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction")
+    """fractional expression of an integer divided by an integer, returns a float"""
+    fraction.addParseAction(lambda t: t[0]/t[-1])
+
+    mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction")
+    """mixed integer of the form 'integer - fraction', with optional leading integer, returns float"""
+    mixed_integer.addParseAction(sum)
+
+    real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat)
+    """expression that parses a floating point number and returns a float"""
+
+    sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat)
+    """expression that parses a floating point number with optional scientific notation and returns a float"""
+
+    # streamlining this expression makes the docs nicer-looking
+    number = (sci_real | real | signed_integer).streamline()
+    """any numeric expression, returns the corresponding Python type"""
+
+    fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat)
+    """any int or real number, returned as float"""
+    
+    identifier = Word(alphas+'_', alphanums+'_').setName("identifier")
+    """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')"""
+    
+    ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address")
+    "IPv4 address (C{0.0.0.0 - 255.255.255.255})"
+
+    _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer")
+    _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address")
+    _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address")
+    _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8)
+    _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address")
+    ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address")
+    "IPv6 address (long, short, or mixed form)"
+    
+    mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address")
+    "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)"
+
+    @staticmethod
+    def convertToDate(fmt="%Y-%m-%d"):
+        """
+        Helper to create a parse action for converting parsed date string to Python datetime.date
+
+        Params -
+         - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"})
+
+        Example::
+            date_expr = pyparsing_common.iso8601_date.copy()
+            date_expr.setParseAction(pyparsing_common.convertToDate())
+            print(date_expr.parseString("1999-12-31"))
+        prints::
+            [datetime.date(1999, 12, 31)]
+        """
+        def cvt_fn(s,l,t):
+            try:
+                return datetime.strptime(t[0], fmt).date()
+            except ValueError as ve:
+                raise ParseException(s, l, str(ve))
+        return cvt_fn
+
+    @staticmethod
+    def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"):
+        """
+        Helper to create a parse action for converting parsed datetime string to Python datetime.datetime
+
+        Params -
+         - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"})
+
+        Example::
+            dt_expr = pyparsing_common.iso8601_datetime.copy()
+            dt_expr.setParseAction(pyparsing_common.convertToDatetime())
+            print(dt_expr.parseString("1999-12-31T23:59:59.999"))
+        prints::
+            [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)]
+        """
+        def cvt_fn(s,l,t):
+            try:
+                return datetime.strptime(t[0], fmt)
+            except ValueError as ve:
+                raise ParseException(s, l, str(ve))
+        return cvt_fn
+
+    iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date")
+    "ISO8601 date (C{yyyy-mm-dd})"
+
+    iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime")
+    "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}"
+
+    uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID")
+    "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})"
+
+    _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress()
+    @staticmethod
+    def stripHTMLTags(s, l, tokens):
+        """
+        Parse action to remove HTML tags from web page HTML source
+
+        Example::
+            # strip HTML links from normal text 
+            text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>'
+            td,td_end = makeHTMLTags("TD")
+            table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end
+            
+            print(table_text.parseString(text).body) # -> 'More info at the pyparsing wiki page'
+        """
+        return pyparsing_common._html_stripper.transformString(tokens[0])
+
+    _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') 
+                                        + Optional( White(" \t") ) ) ).streamline().setName("commaItem")
+    comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list")
+    """Predefined expression of 1 or more printable words or quoted strings, separated by commas."""
+
+    upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper()))
+    """Parse action to convert tokens to upper case."""
+
+    downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower()))
+    """Parse action to convert tokens to lower case."""
+
+
+if __name__ == "__main__":
+
+    selectToken    = CaselessLiteral("select")
+    fromToken      = CaselessLiteral("from")
+
+    ident          = Word(alphas, alphanums + "_$")
+
+    columnName     = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens)
+    columnNameList = Group(delimitedList(columnName)).setName("columns")
+    columnSpec     = ('*' | columnNameList)
+
+    tableName      = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens)
+    tableNameList  = Group(delimitedList(tableName)).setName("tables")
+    
+    simpleSQL      = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables")
+
+    # demo runTests method, including embedded comments in test string
+    simpleSQL.runTests("""
+        # '*' as column list and dotted table name
+        select * from SYS.XYZZY
+
+        # caseless match on "SELECT", and casts back to "select"
+        SELECT * from XYZZY, ABC
+
+        # list of column names, and mixed case SELECT keyword
+        Select AA,BB,CC from Sys.dual
+
+        # multiple tables
+        Select A, B, C from Sys.dual, Table2
+
+        # invalid SELECT keyword - should fail
+        Xelect A, B, C from Sys.dual
+
+        # incomplete command - should fail
+        Select
+
+        # invalid column name - should fail
+        Select ^^^ frox Sys.dual
+
+        """)
+
+    pyparsing_common.number.runTests("""
+        100
+        -100
+        +100
+        3.14159
+        6.02e23
+        1e-12
+        """)
+
+    # any int or real number, returned as float
+    pyparsing_common.fnumber.runTests("""
+        100
+        -100
+        +100
+        3.14159
+        6.02e23
+        1e-12
+        """)
+
+    pyparsing_common.hex_integer.runTests("""
+        100
+        FF
+        """)
+
+    import uuid
+    pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID))
+    pyparsing_common.uuid.runTests("""
+        12345678-1234-5678-1234-567812345678
+        """)
diff --git a/vendor/setuptools-39.0.1/pkg_resources/_vendor/six.py b/vendor/setuptools-39.0.1/pkg_resources/_vendor/six.py
new file mode 100644
index 00000000..190c0239
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/_vendor/six.py
@@ -0,0 +1,868 @@
+"""Utilities for writing code that runs on Python 2 and 3"""
+
+# Copyright (c) 2010-2015 Benjamin Peterson
+#
+# 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 __future__ import absolute_import
+
+import functools
+import itertools
+import operator
+import sys
+import types
+
+__author__ = "Benjamin Peterson <benjamin@python.org>"
+__version__ = "1.10.0"
+
+
+# Useful for very coarse version differentiation.
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
+PY34 = sys.version_info[0:2] >= (3, 4)
+
+if PY3:
+    string_types = str,
+    integer_types = int,
+    class_types = type,
+    text_type = str
+    binary_type = bytes
+
+    MAXSIZE = sys.maxsize
+else:
+    string_types = basestring,
+    integer_types = (int, long)
+    class_types = (type, types.ClassType)
+    text_type = unicode
+    binary_type = str
+
+    if sys.platform.startswith("java"):
+        # Jython always uses 32 bits.
+        MAXSIZE = int((1 << 31) - 1)
+    else:
+        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
+        class X(object):
+
+            def __len__(self):
+                return 1 << 31
+        try:
+            len(X())
+        except OverflowError:
+            # 32-bit
+            MAXSIZE = int((1 << 31) - 1)
+        else:
+            # 64-bit
+            MAXSIZE = int((1 << 63) - 1)
+        del X
+
+
+def _add_doc(func, doc):
+    """Add documentation to a function."""
+    func.__doc__ = doc
+
+
+def _import_module(name):
+    """Import module, returning the module after the last dot."""
+    __import__(name)
+    return sys.modules[name]
+
+
+class _LazyDescr(object):
+
+    def __init__(self, name):
+        self.name = name
+
+    def __get__(self, obj, tp):
+        result = self._resolve()
+        setattr(obj, self.name, result)  # Invokes __set__.
+        try:
+            # This is a bit ugly, but it avoids running this again by
+            # removing this descriptor.
+            delattr(obj.__class__, self.name)
+        except AttributeError:
+            pass
+        return result
+
+
+class MovedModule(_LazyDescr):
+
+    def __init__(self, name, old, new=None):
+        super(MovedModule, self).__init__(name)
+        if PY3:
+            if new is None:
+                new = name
+            self.mod = new
+        else:
+            self.mod = old
+
+    def _resolve(self):
+        return _import_module(self.mod)
+
+    def __getattr__(self, attr):
+        _module = self._resolve()
+        value = getattr(_module, attr)
+        setattr(self, attr, value)
+        return value
+
+
+class _LazyModule(types.ModuleType):
+
+    def __init__(self, name):
+        super(_LazyModule, self).__init__(name)
+        self.__doc__ = self.__class__.__doc__
+
+    def __dir__(self):
+        attrs = ["__doc__", "__name__"]
+        attrs += [attr.name for attr in self._moved_attributes]
+        return attrs
+
+    # Subclasses should override this
+    _moved_attributes = []
+
+
+class MovedAttribute(_LazyDescr):
+
+    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
+        super(MovedAttribute, self).__init__(name)
+        if PY3:
+            if new_mod is None:
+                new_mod = name
+            self.mod = new_mod
+            if new_attr is None:
+                if old_attr is None:
+                    new_attr = name
+                else:
+                    new_attr = old_attr
+            self.attr = new_attr
+        else:
+            self.mod = old_mod
+            if old_attr is None:
+                old_attr = name
+            self.attr = old_attr
+
+    def _resolve(self):
+        module = _import_module(self.mod)
+        return getattr(module, self.attr)
+
+
+class _SixMetaPathImporter(object):
+
+    """
+    A meta path importer to import six.moves and its submodules.
+
+    This class implements a PEP302 finder and loader. It should be compatible
+    with Python 2.5 and all existing versions of Python3
+    """
+
+    def __init__(self, six_module_name):
+        self.name = six_module_name
+        self.known_modules = {}
+
+    def _add_module(self, mod, *fullnames):
+        for fullname in fullnames:
+            self.known_modules[self.name + "." + fullname] = mod
+
+    def _get_module(self, fullname):
+        return self.known_modules[self.name + "." + fullname]
+
+    def find_module(self, fullname, path=None):
+        if fullname in self.known_modules:
+            return self
+        return None
+
+    def __get_module(self, fullname):
+        try:
+            return self.known_modules[fullname]
+        except KeyError:
+            raise ImportError("This loader does not know module " + fullname)
+
+    def load_module(self, fullname):
+        try:
+            # in case of a reload
+            return sys.modules[fullname]
+        except KeyError:
+            pass
+        mod = self.__get_module(fullname)
+        if isinstance(mod, MovedModule):
+            mod = mod._resolve()
+        else:
+            mod.__loader__ = self
+        sys.modules[fullname] = mod
+        return mod
+
+    def is_package(self, fullname):
+        """
+        Return true, if the named module is a package.
+
+        We need this method to get correct spec objects with
+        Python 3.4 (see PEP451)
+        """
+        return hasattr(self.__get_module(fullname), "__path__")
+
+    def get_code(self, fullname):
+        """Return None
+
+        Required, if is_package is implemented"""
+        self.__get_module(fullname)  # eventually raises ImportError
+        return None
+    get_source = get_code  # same as get_code
+
+_importer = _SixMetaPathImporter(__name__)
+
+
+class _MovedItems(_LazyModule):
+
+    """Lazy loading of moved objects"""
+    __path__ = []  # mark as package
+
+
+_moved_attributes = [
+    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
+    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
+    MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
+    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
+    MovedAttribute("intern", "__builtin__", "sys"),
+    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
+    MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
+    MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
+    MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
+    MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
+    MovedAttribute("reduce", "__builtin__", "functools"),
+    MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
+    MovedAttribute("StringIO", "StringIO", "io"),
+    MovedAttribute("UserDict", "UserDict", "collections"),
+    MovedAttribute("UserList", "UserList", "collections"),
+    MovedAttribute("UserString", "UserString", "collections"),
+    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
+    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
+    MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
+    MovedModule("builtins", "__builtin__"),
+    MovedModule("configparser", "ConfigParser"),
+    MovedModule("copyreg", "copy_reg"),
+    MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
+    MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
+    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
+    MovedModule("http_cookies", "Cookie", "http.cookies"),
+    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
+    MovedModule("html_parser", "HTMLParser", "html.parser"),
+    MovedModule("http_client", "httplib", "http.client"),
+    MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
+    MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
+    MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
+    MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
+    MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
+    MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
+    MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
+    MovedModule("cPickle", "cPickle", "pickle"),
+    MovedModule("queue", "Queue"),
+    MovedModule("reprlib", "repr"),
+    MovedModule("socketserver", "SocketServer"),
+    MovedModule("_thread", "thread", "_thread"),
+    MovedModule("tkinter", "Tkinter"),
+    MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
+    MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
+    MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
+    MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
+    MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
+    MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
+    MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
+    MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
+    MovedModule("tkinter_colorchooser", "tkColorChooser",
+                "tkinter.colorchooser"),
+    MovedModule("tkinter_commondialog", "tkCommonDialog",
+                "tkinter.commondialog"),
+    MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
+    MovedModule("tkinter_font", "tkFont", "tkinter.font"),
+    MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
+    MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
+                "tkinter.simpledialog"),
+    MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
+    MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
+    MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
+    MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
+    MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
+    MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
+]
+# Add windows specific modules.
+if sys.platform == "win32":
+    _moved_attributes += [
+        MovedModule("winreg", "_winreg"),
+    ]
+
+for attr in _moved_attributes:
+    setattr(_MovedItems, attr.name, attr)
+    if isinstance(attr, MovedModule):
+        _importer._add_module(attr, "moves." + attr.name)
+del attr
+
+_MovedItems._moved_attributes = _moved_attributes
+
+moves = _MovedItems(__name__ + ".moves")
+_importer._add_module(moves, "moves")
+
+
+class Module_six_moves_urllib_parse(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_parse"""
+
+
+_urllib_parse_moved_attributes = [
+    MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
+    MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
+    MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
+    MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
+    MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
+    MovedAttribute("urljoin", "urlparse", "urllib.parse"),
+    MovedAttribute("urlparse", "urlparse", "urllib.parse"),
+    MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
+    MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
+    MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
+    MovedAttribute("quote", "urllib", "urllib.parse"),
+    MovedAttribute("quote_plus", "urllib", "urllib.parse"),
+    MovedAttribute("unquote", "urllib", "urllib.parse"),
+    MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
+    MovedAttribute("urlencode", "urllib", "urllib.parse"),
+    MovedAttribute("splitquery", "urllib", "urllib.parse"),
+    MovedAttribute("splittag", "urllib", "urllib.parse"),
+    MovedAttribute("splituser", "urllib", "urllib.parse"),
+    MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_params", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_query", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
+]
+for attr in _urllib_parse_moved_attributes:
+    setattr(Module_six_moves_urllib_parse, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
+                      "moves.urllib_parse", "moves.urllib.parse")
+
+
+class Module_six_moves_urllib_error(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_error"""
+
+
+_urllib_error_moved_attributes = [
+    MovedAttribute("URLError", "urllib2", "urllib.error"),
+    MovedAttribute("HTTPError", "urllib2", "urllib.error"),
+    MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
+]
+for attr in _urllib_error_moved_attributes:
+    setattr(Module_six_moves_urllib_error, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
+                      "moves.urllib_error", "moves.urllib.error")
+
+
+class Module_six_moves_urllib_request(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_request"""
+
+
+_urllib_request_moved_attributes = [
+    MovedAttribute("urlopen", "urllib2", "urllib.request"),
+    MovedAttribute("install_opener", "urllib2", "urllib.request"),
+    MovedAttribute("build_opener", "urllib2", "urllib.request"),
+    MovedAttribute("pathname2url", "urllib", "urllib.request"),
+    MovedAttribute("url2pathname", "urllib", "urllib.request"),
+    MovedAttribute("getproxies", "urllib", "urllib.request"),
+    MovedAttribute("Request", "urllib2", "urllib.request"),
+    MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
+    MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
+    MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
+    MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
+    MovedAttribute("FileHandler", "urllib2", "urllib.request"),
+    MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
+    MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
+    MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
+    MovedAttribute("urlretrieve", "urllib", "urllib.request"),
+    MovedAttribute("urlcleanup", "urllib", "urllib.request"),
+    MovedAttribute("URLopener", "urllib", "urllib.request"),
+    MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
+    MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
+]
+for attr in _urllib_request_moved_attributes:
+    setattr(Module_six_moves_urllib_request, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
+                      "moves.urllib_request", "moves.urllib.request")
+
+
+class Module_six_moves_urllib_response(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_response"""
+
+
+_urllib_response_moved_attributes = [
+    MovedAttribute("addbase", "urllib", "urllib.response"),
+    MovedAttribute("addclosehook", "urllib", "urllib.response"),
+    MovedAttribute("addinfo", "urllib", "urllib.response"),
+    MovedAttribute("addinfourl", "urllib", "urllib.response"),
+]
+for attr in _urllib_response_moved_attributes:
+    setattr(Module_six_moves_urllib_response, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
+                      "moves.urllib_response", "moves.urllib.response")
+
+
+class Module_six_moves_urllib_robotparser(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_robotparser"""
+
+
+_urllib_robotparser_moved_attributes = [
+    MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
+]
+for attr in _urllib_robotparser_moved_attributes:
+    setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
+                      "moves.urllib_robotparser", "moves.urllib.robotparser")
+
+
+class Module_six_moves_urllib(types.ModuleType):
+
+    """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
+    __path__ = []  # mark as package
+    parse = _importer._get_module("moves.urllib_parse")
+    error = _importer._get_module("moves.urllib_error")
+    request = _importer._get_module("moves.urllib_request")
+    response = _importer._get_module("moves.urllib_response")
+    robotparser = _importer._get_module("moves.urllib_robotparser")
+
+    def __dir__(self):
+        return ['parse', 'error', 'request', 'response', 'robotparser']
+
+_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
+                      "moves.urllib")
+
+
+def add_move(move):
+    """Add an item to six.moves."""
+    setattr(_MovedItems, move.name, move)
+
+
+def remove_move(name):
+    """Remove item from six.moves."""
+    try:
+        delattr(_MovedItems, name)
+    except AttributeError:
+        try:
+            del moves.__dict__[name]
+        except KeyError:
+            raise AttributeError("no such move, %r" % (name,))
+
+
+if PY3:
+    _meth_func = "__func__"
+    _meth_self = "__self__"
+
+    _func_closure = "__closure__"
+    _func_code = "__code__"
+    _func_defaults = "__defaults__"
+    _func_globals = "__globals__"
+else:
+    _meth_func = "im_func"
+    _meth_self = "im_self"
+
+    _func_closure = "func_closure"
+    _func_code = "func_code"
+    _func_defaults = "func_defaults"
+    _func_globals = "func_globals"
+
+
+try:
+    advance_iterator = next
+except NameError:
+    def advance_iterator(it):
+        return it.next()
+next = advance_iterator
+
+
+try:
+    callable = callable
+except NameError:
+    def callable(obj):
+        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
+
+
+if PY3:
+    def get_unbound_function(unbound):
+        return unbound
+
+    create_bound_method = types.MethodType
+
+    def create_unbound_method(func, cls):
+        return func
+
+    Iterator = object
+else:
+    def get_unbound_function(unbound):
+        return unbound.im_func
+
+    def create_bound_method(func, obj):
+        return types.MethodType(func, obj, obj.__class__)
+
+    def create_unbound_method(func, cls):
+        return types.MethodType(func, None, cls)
+
+    class Iterator(object):
+
+        def next(self):
+            return type(self).__next__(self)
+
+    callable = callable
+_add_doc(get_unbound_function,
+         """Get the function out of a possibly unbound function""")
+
+
+get_method_function = operator.attrgetter(_meth_func)
+get_method_self = operator.attrgetter(_meth_self)
+get_function_closure = operator.attrgetter(_func_closure)
+get_function_code = operator.attrgetter(_func_code)
+get_function_defaults = operator.attrgetter(_func_defaults)
+get_function_globals = operator.attrgetter(_func_globals)
+
+
+if PY3:
+    def iterkeys(d, **kw):
+        return iter(d.keys(**kw))
+
+    def itervalues(d, **kw):
+        return iter(d.values(**kw))
+
+    def iteritems(d, **kw):
+        return iter(d.items(**kw))
+
+    def iterlists(d, **kw):
+        return iter(d.lists(**kw))
+
+    viewkeys = operator.methodcaller("keys")
+
+    viewvalues = operator.methodcaller("values")
+
+    viewitems = operator.methodcaller("items")
+else:
+    def iterkeys(d, **kw):
+        return d.iterkeys(**kw)
+
+    def itervalues(d, **kw):
+        return d.itervalues(**kw)
+
+    def iteritems(d, **kw):
+        return d.iteritems(**kw)
+
+    def iterlists(d, **kw):
+        return d.iterlists(**kw)
+
+    viewkeys = operator.methodcaller("viewkeys")
+
+    viewvalues = operator.methodcaller("viewvalues")
+
+    viewitems = operator.methodcaller("viewitems")
+
+_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
+_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
+_add_doc(iteritems,
+         "Return an iterator over the (key, value) pairs of a dictionary.")
+_add_doc(iterlists,
+         "Return an iterator over the (key, [values]) pairs of a dictionary.")
+
+
+if PY3:
+    def b(s):
+        return s.encode("latin-1")
+
+    def u(s):
+        return s
+    unichr = chr
+    import struct
+    int2byte = struct.Struct(">B").pack
+    del struct
+    byte2int = operator.itemgetter(0)
+    indexbytes = operator.getitem
+    iterbytes = iter
+    import io
+    StringIO = io.StringIO
+    BytesIO = io.BytesIO
+    _assertCountEqual = "assertCountEqual"
+    if sys.version_info[1] <= 1:
+        _assertRaisesRegex = "assertRaisesRegexp"
+        _assertRegex = "assertRegexpMatches"
+    else:
+        _assertRaisesRegex = "assertRaisesRegex"
+        _assertRegex = "assertRegex"
+else:
+    def b(s):
+        return s
+    # Workaround for standalone backslash
+
+    def u(s):
+        return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
+    unichr = unichr
+    int2byte = chr
+
+    def byte2int(bs):
+        return ord(bs[0])
+
+    def indexbytes(buf, i):
+        return ord(buf[i])
+    iterbytes = functools.partial(itertools.imap, ord)
+    import StringIO
+    StringIO = BytesIO = StringIO.StringIO
+    _assertCountEqual = "assertItemsEqual"
+    _assertRaisesRegex = "assertRaisesRegexp"
+    _assertRegex = "assertRegexpMatches"
+_add_doc(b, """Byte literal""")
+_add_doc(u, """Text literal""")
+
+
+def assertCountEqual(self, *args, **kwargs):
+    return getattr(self, _assertCountEqual)(*args, **kwargs)
+
+
+def assertRaisesRegex(self, *args, **kwargs):
+    return getattr(self, _assertRaisesRegex)(*args, **kwargs)
+
+
+def assertRegex(self, *args, **kwargs):
+    return getattr(self, _assertRegex)(*args, **kwargs)
+
+
+if PY3:
+    exec_ = getattr(moves.builtins, "exec")
+
+    def reraise(tp, value, tb=None):
+        if value is None:
+            value = tp()
+        if value.__traceback__ is not tb:
+            raise value.with_traceback(tb)
+        raise value
+
+else:
+    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 reraise(tp, value, tb=None):
+    raise tp, value, tb
+""")
+
+
+if sys.version_info[:2] == (3, 2):
+    exec_("""def raise_from(value, from_value):
+    if from_value is None:
+        raise value
+    raise value from from_value
+""")
+elif sys.version_info[:2] > (3, 2):
+    exec_("""def raise_from(value, from_value):
+    raise value from from_value
+""")
+else:
+    def raise_from(value, from_value):
+        raise value
+
+
+print_ = getattr(moves.builtins, "print", None)
+if print_ is None:
+    def print_(*args, **kwargs):
+        """The new-style print function for Python 2.4 and 2.5."""
+        fp = kwargs.pop("file", sys.stdout)
+        if fp is None:
+            return
+
+        def write(data):
+            if not isinstance(data, basestring):
+                data = str(data)
+            # If the file has an encoding, encode unicode with it.
+            if (isinstance(fp, file) and
+                    isinstance(data, unicode) and
+                    fp.encoding is not None):
+                errors = getattr(fp, "errors", None)
+                if errors is None:
+                    errors = "strict"
+                data = data.encode(fp.encoding, errors)
+            fp.write(data)
+        want_unicode = False
+        sep = kwargs.pop("sep", None)
+        if sep is not None:
+            if isinstance(sep, unicode):
+                want_unicode = True
+            elif not isinstance(sep, str):
+                raise TypeError("sep must be None or a string")
+        end = kwargs.pop("end", None)
+        if end is not None:
+            if isinstance(end, unicode):
+                want_unicode = True
+            elif not isinstance(end, str):
+                raise TypeError("end must be None or a string")
+        if kwargs:
+            raise TypeError("invalid keyword arguments to print()")
+        if not want_unicode:
+            for arg in args:
+                if isinstance(arg, unicode):
+                    want_unicode = True
+                    break
+        if want_unicode:
+            newline = unicode("\n")
+            space = unicode(" ")
+        else:
+            newline = "\n"
+            space = " "
+        if sep is None:
+            sep = space
+        if end is None:
+            end = newline
+        for i, arg in enumerate(args):
+            if i:
+                write(sep)
+            write(arg)
+        write(end)
+if sys.version_info[:2] < (3, 3):
+    _print = print_
+
+    def print_(*args, **kwargs):
+        fp = kwargs.get("file", sys.stdout)
+        flush = kwargs.pop("flush", False)
+        _print(*args, **kwargs)
+        if flush and fp is not None:
+            fp.flush()
+
+_add_doc(reraise, """Reraise an exception.""")
+
+if sys.version_info[0:2] < (3, 4):
+    def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
+              updated=functools.WRAPPER_UPDATES):
+        def wrapper(f):
+            f = functools.wraps(wrapped, assigned, updated)(f)
+            f.__wrapped__ = wrapped
+            return f
+        return wrapper
+else:
+    wraps = functools.wraps
+
+
+def with_metaclass(meta, *bases):
+    """Create a base class with a metaclass."""
+    # This requires a bit of explanation: the basic idea is to make a dummy
+    # metaclass for one level of class instantiation that replaces itself with
+    # the actual metaclass.
+    class metaclass(meta):
+
+        def __new__(cls, name, this_bases, d):
+            return meta(name, bases, d)
+    return type.__new__(metaclass, 'temporary_class', (), {})
+
+
+def add_metaclass(metaclass):
+    """Class decorator for creating a class with a metaclass."""
+    def wrapper(cls):
+        orig_vars = cls.__dict__.copy()
+        slots = orig_vars.get('__slots__')
+        if slots is not None:
+            if isinstance(slots, str):
+                slots = [slots]
+            for slots_var in slots:
+                orig_vars.pop(slots_var)
+        orig_vars.pop('__dict__', None)
+        orig_vars.pop('__weakref__', None)
+        return metaclass(cls.__name__, cls.__bases__, orig_vars)
+    return wrapper
+
+
+def python_2_unicode_compatible(klass):
+    """
+    A decorator that defines __unicode__ and __str__ methods under Python 2.
+    Under Python 3 it does nothing.
+
+    To support Python 2 and 3 with a single code base, define a __str__ method
+    returning text and apply this decorator to the class.
+    """
+    if PY2:
+        if '__str__' not in klass.__dict__:
+            raise ValueError("@python_2_unicode_compatible cannot be applied "
+                             "to %s because it doesn't define __str__()." %
+                             klass.__name__)
+        klass.__unicode__ = klass.__str__
+        klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
+    return klass
+
+
+# Complete the moves implementation.
+# This code is at the end of this module to speed up module loading.
+# Turn this module into a package.
+__path__ = []  # required for PEP 302 and PEP 451
+__package__ = __name__  # see PEP 366 @ReservedAssignment
+if globals().get("__spec__") is not None:
+    __spec__.submodule_search_locations = []  # PEP 451 @UndefinedVariable
+# Remove other six meta path importers, since they cause problems. This can
+# happen if six is removed from sys.modules and then reloaded. (Setuptools does
+# this for some reason.)
+if sys.meta_path:
+    for i, importer in enumerate(sys.meta_path):
+        # Here's some real nastiness: Another "instance" of the six module might
+        # be floating around. Therefore, we can't use isinstance() to check for
+        # the six meta path importer, since the other six instance will have
+        # inserted an importer with different class.
+        if (type(importer).__name__ == "_SixMetaPathImporter" and
+                importer.name == __name__):
+            del sys.meta_path[i]
+            break
+    del i, importer
+# Finally, add the importer to the meta path import hook.
+sys.meta_path.append(_importer)
diff --git a/vendor/setuptools-39.0.1/pkg_resources/_vendor/vendored.txt b/vendor/setuptools-39.0.1/pkg_resources/_vendor/vendored.txt
new file mode 100644
index 00000000..9a94c5bc
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/_vendor/vendored.txt
@@ -0,0 +1,4 @@
+packaging==16.8
+pyparsing==2.1.10
+six==1.10.0
+appdirs==1.4.0
diff --git a/vendor/setuptools-39.0.1/pkg_resources/api_tests.txt b/vendor/setuptools-39.0.1/pkg_resources/api_tests.txt
new file mode 100644
index 00000000..0a75170e
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/api_tests.txt
@@ -0,0 +1,401 @@
+Pluggable Distributions of Python Software
+==========================================
+
+Distributions
+-------------
+
+A "Distribution" is a collection of files that represent a "Release" of a
+"Project" as of a particular point in time, denoted by a
+"Version"::
+
+    >>> import sys, pkg_resources
+    >>> from pkg_resources import Distribution
+    >>> Distribution(project_name="Foo", version="1.2")
+    Foo 1.2
+
+Distributions have a location, which can be a filename, URL, or really anything
+else you care to use::
+
+    >>> dist = Distribution(
+    ...     location="http://example.com/something",
+    ...     project_name="Bar", version="0.9"
+    ... )
+
+    >>> dist
+    Bar 0.9 (http://example.com/something)
+
+
+Distributions have various introspectable attributes::
+
+    >>> dist.location
+    'http://example.com/something'
+
+    >>> dist.project_name
+    'Bar'
+
+    >>> dist.version
+    '0.9'
+
+    >>> dist.py_version == sys.version[:3]
+    True
+
+    >>> print(dist.platform)
+    None
+
+Including various computed attributes::
+
+    >>> from pkg_resources import parse_version
+    >>> dist.parsed_version == parse_version(dist.version)
+    True
+
+    >>> dist.key    # case-insensitive form of the project name
+    'bar'
+
+Distributions are compared (and hashed) by version first::
+
+    >>> Distribution(version='1.0') == Distribution(version='1.0')
+    True
+    >>> Distribution(version='1.0') == Distribution(version='1.1')
+    False
+    >>> Distribution(version='1.0') <  Distribution(version='1.1')
+    True
+
+but also by project name (case-insensitive), platform, Python version,
+location, etc.::
+
+    >>> Distribution(project_name="Foo",version="1.0") == \
+    ... Distribution(project_name="Foo",version="1.0")
+    True
+
+    >>> Distribution(project_name="Foo",version="1.0") == \
+    ... Distribution(project_name="foo",version="1.0")
+    True
+
+    >>> Distribution(project_name="Foo",version="1.0") == \
+    ... Distribution(project_name="Foo",version="1.1")
+    False
+
+    >>> Distribution(project_name="Foo",py_version="2.3",version="1.0") == \
+    ... Distribution(project_name="Foo",py_version="2.4",version="1.0")
+    False
+
+    >>> Distribution(location="spam",version="1.0") == \
+    ... Distribution(location="spam",version="1.0")
+    True
+
+    >>> Distribution(location="spam",version="1.0") == \
+    ... Distribution(location="baz",version="1.0")
+    False
+
+
+
+Hash and compare distribution by prio/plat
+
+Get version from metadata
+provider capabilities
+egg_name()
+as_requirement()
+from_location, from_filename (w/path normalization)
+
+Releases may have zero or more "Requirements", which indicate
+what releases of another project the release requires in order to
+function.  A Requirement names the other project, expresses some criteria
+as to what releases of that project are acceptable, and lists any "Extras"
+that the requiring release may need from that project.  (An Extra is an
+optional feature of a Release, that can only be used if its additional
+Requirements are satisfied.)
+
+
+
+The Working Set
+---------------
+
+A collection of active distributions is called a Working Set.  Note that a
+Working Set can contain any importable distribution, not just pluggable ones.
+For example, the Python standard library is an importable distribution that
+will usually be part of the Working Set, even though it is not pluggable.
+Similarly, when you are doing development work on a project, the files you are
+editing are also a Distribution.  (And, with a little attention to the
+directory names used,  and including some additional metadata, such a
+"development distribution" can be made pluggable as well.)
+
+    >>> from pkg_resources import WorkingSet
+
+A working set's entries are the sys.path entries that correspond to the active
+distributions.  By default, the working set's entries are the items on
+``sys.path``::
+
+    >>> ws = WorkingSet()
+    >>> ws.entries == sys.path
+    True
+
+But you can also create an empty working set explicitly, and add distributions
+to it::
+
+    >>> ws = WorkingSet([])
+    >>> ws.add(dist)
+    >>> ws.entries
+    ['http://example.com/something']
+    >>> dist in ws
+    True
+    >>> Distribution('foo',version="") in ws
+    False
+
+And you can iterate over its distributions::
+
+    >>> list(ws)
+    [Bar 0.9 (http://example.com/something)]
+
+Adding the same distribution more than once is a no-op::
+
+    >>> ws.add(dist)
+    >>> list(ws)
+    [Bar 0.9 (http://example.com/something)]
+
+For that matter, adding multiple distributions for the same project also does
+nothing, because a working set can only hold one active distribution per
+project -- the first one added to it::
+
+    >>> ws.add(
+    ...     Distribution(
+    ...         'http://example.com/something', project_name="Bar",
+    ...         version="7.2"
+    ...     )
+    ... )
+    >>> list(ws)
+    [Bar 0.9 (http://example.com/something)]
+
+You can append a path entry to a working set using ``add_entry()``::
+
+    >>> ws.entries
+    ['http://example.com/something']
+    >>> ws.add_entry(pkg_resources.__file__)
+    >>> ws.entries
+    ['http://example.com/something', '...pkg_resources...']
+
+Multiple additions result in multiple entries, even if the entry is already in
+the working set (because ``sys.path`` can contain the same entry more than
+once)::
+
+    >>> ws.add_entry(pkg_resources.__file__)
+    >>> ws.entries
+    ['...example.com...', '...pkg_resources...', '...pkg_resources...']
+
+And you can specify the path entry a distribution was found under, using the
+optional second parameter to ``add()``::
+
+    >>> ws = WorkingSet([])
+    >>> ws.add(dist,"foo")
+    >>> ws.entries
+    ['foo']
+
+But even if a distribution is found under multiple path entries, it still only
+shows up once when iterating the working set:
+
+    >>> ws.add_entry(ws.entries[0])
+    >>> list(ws)
+    [Bar 0.9 (http://example.com/something)]
+
+You can ask a WorkingSet to ``find()`` a distribution matching a requirement::
+
+    >>> from pkg_resources import Requirement
+    >>> print(ws.find(Requirement.parse("Foo==1.0")))   # no match, return None
+    None
+
+    >>> ws.find(Requirement.parse("Bar==0.9"))  # match, return distribution
+    Bar 0.9 (http://example.com/something)
+
+Note that asking for a conflicting version of a distribution already in a
+working set triggers a ``pkg_resources.VersionConflict`` error:
+
+    >>> try:
+    ...     ws.find(Requirement.parse("Bar==1.0"))
+    ... except pkg_resources.VersionConflict as exc:
+    ...     print(str(exc))
+    ... else:
+    ...     raise AssertionError("VersionConflict was not raised")
+    (Bar 0.9 (http://example.com/something), Requirement.parse('Bar==1.0'))
+
+You can subscribe a callback function to receive notifications whenever a new
+distribution is added to a working set.  The callback is immediately invoked
+once for each existing distribution in the working set, and then is called
+again for new distributions added thereafter::
+
+    >>> def added(dist): print("Added %s" % dist)
+    >>> ws.subscribe(added)
+    Added Bar 0.9
+    >>> foo12 = Distribution(project_name="Foo", version="1.2", location="f12")
+    >>> ws.add(foo12)
+    Added Foo 1.2
+
+Note, however, that only the first distribution added for a given project name
+will trigger a callback, even during the initial ``subscribe()`` callback::
+
+    >>> foo14 = Distribution(project_name="Foo", version="1.4", location="f14")
+    >>> ws.add(foo14)   # no callback, because Foo 1.2 is already active
+
+    >>> ws = WorkingSet([])
+    >>> ws.add(foo12)
+    >>> ws.add(foo14)
+    >>> ws.subscribe(added)
+    Added Foo 1.2
+
+And adding a callback more than once has no effect, either::
+
+    >>> ws.subscribe(added)     # no callbacks
+
+    # and no double-callbacks on subsequent additions, either
+    >>> just_a_test = Distribution(project_name="JustATest", version="0.99")
+    >>> ws.add(just_a_test)
+    Added JustATest 0.99
+
+
+Finding Plugins
+---------------
+
+``WorkingSet`` objects can be used to figure out what plugins in an
+``Environment`` can be loaded without any resolution errors::
+
+    >>> from pkg_resources import Environment
+
+    >>> plugins = Environment([])   # normally, a list of plugin directories
+    >>> plugins.add(foo12)
+    >>> plugins.add(foo14)
+    >>> plugins.add(just_a_test)
+
+In the simplest case, we just get the newest version of each distribution in
+the plugin environment::
+
+    >>> ws = WorkingSet([])
+    >>> ws.find_plugins(plugins)
+    ([JustATest 0.99, Foo 1.4 (f14)], {})
+
+But if there's a problem with a version conflict or missing requirements, the
+method falls back to older versions, and the error info dict will contain an
+exception instance for each unloadable plugin::
+
+    >>> ws.add(foo12)   # this will conflict with Foo 1.4
+    >>> ws.find_plugins(plugins)
+    ([JustATest 0.99, Foo 1.2 (f12)], {Foo 1.4 (f14): VersionConflict(...)})
+
+But if you disallow fallbacks, the failed plugin will be skipped instead of
+trying older versions::
+
+    >>> ws.find_plugins(plugins, fallback=False)
+    ([JustATest 0.99], {Foo 1.4 (f14): VersionConflict(...)})
+
+
+
+Platform Compatibility Rules
+----------------------------
+
+On the Mac, there are potential compatibility issues for modules compiled
+on newer versions of Mac OS X than what the user is running. Additionally,
+Mac OS X will soon have two platforms to contend with: Intel and PowerPC.
+
+Basic equality works as on other platforms::
+
+    >>> from pkg_resources import compatible_platforms as cp
+    >>> reqd = 'macosx-10.4-ppc'
+    >>> cp(reqd, reqd)
+    True
+    >>> cp("win32", reqd)
+    False
+
+Distributions made on other machine types are not compatible::
+
+    >>> cp("macosx-10.4-i386", reqd)
+    False
+
+Distributions made on earlier versions of the OS are compatible, as
+long as they are from the same top-level version. The patchlevel version
+number does not matter::
+
+    >>> cp("macosx-10.4-ppc", reqd)
+    True
+    >>> cp("macosx-10.3-ppc", reqd)
+    True
+    >>> cp("macosx-10.5-ppc", reqd)
+    False
+    >>> cp("macosx-9.5-ppc", reqd)
+    False
+
+Backwards compatibility for packages made via earlier versions of
+setuptools is provided as well::
+
+    >>> cp("darwin-8.2.0-Power_Macintosh", reqd)
+    True
+    >>> cp("darwin-7.2.0-Power_Macintosh", reqd)
+    True
+    >>> cp("darwin-8.2.0-Power_Macintosh", "macosx-10.3-ppc")
+    False
+
+
+Environment Markers
+-------------------
+
+    >>> from pkg_resources import invalid_marker as im, evaluate_marker as em
+    >>> import os
+
+    >>> print(im("sys_platform"))
+    Invalid marker: 'sys_platform', parse error at ''
+
+    >>> print(im("sys_platform=="))
+    Invalid marker: 'sys_platform==', parse error at ''
+
+    >>> print(im("sys_platform=='win32'"))
+    False
+
+    >>> print(im("sys=='x'"))
+    Invalid marker: "sys=='x'", parse error at "sys=='x'"
+
+    >>> print(im("(extra)"))
+    Invalid marker: '(extra)', parse error at ')'
+
+    >>> print(im("(extra"))
+    Invalid marker: '(extra', parse error at ''
+
+    >>> print(im("os.open('foo')=='y'"))
+    Invalid marker: "os.open('foo')=='y'", parse error at 'os.open('
+
+    >>> print(im("'x'=='y' and os.open('foo')=='y'"))   # no short-circuit!
+    Invalid marker: "'x'=='y' and os.open('foo')=='y'", parse error at 'and os.o'
+
+    >>> print(im("'x'=='x' or os.open('foo')=='y'"))   # no short-circuit!
+    Invalid marker: "'x'=='x' or os.open('foo')=='y'", parse error at 'or os.op'
+
+    >>> print(im("'x' < 'y' < 'z'"))
+    Invalid marker: "'x' < 'y' < 'z'", parse error at "< 'z'"
+
+    >>> print(im("r'x'=='x'"))
+    Invalid marker: "r'x'=='x'", parse error at "r'x'=='x"
+
+    >>> print(im("'''x'''=='x'"))
+    Invalid marker: "'''x'''=='x'", parse error at "'x'''=='"
+
+    >>> print(im('"""x"""=="x"'))
+    Invalid marker: '"""x"""=="x"', parse error at '"x"""=="'
+
+    >>> print(im(r"x\n=='x'"))
+    Invalid marker: "x\\n=='x'", parse error at "x\\n=='x'"
+
+    >>> print(im("os.open=='y'"))
+    Invalid marker: "os.open=='y'", parse error at 'os.open='
+
+    >>> em("sys_platform=='win32'") == (sys.platform=='win32')
+    True
+
+    >>> em("python_version >= '2.7'")
+    True
+
+    >>> em("python_version > '2.6'")
+    True
+
+    >>> im("implementation_name=='cpython'")
+    False
+
+    >>> im("platform_python_implementation=='CPython'")
+    False
+
+    >>> im("implementation_version=='3.5.1'")
+    False
diff --git a/vendor/setuptools-39.0.1/pkg_resources/extern/__init__.py b/vendor/setuptools-39.0.1/pkg_resources/extern/__init__.py
new file mode 100644
index 00000000..b4156fec
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/extern/__init__.py
@@ -0,0 +1,73 @@
+import sys
+
+
+class VendorImporter:
+    """
+    A PEP 302 meta path importer for finding optionally-vendored
+    or otherwise naturally-installed packages from root_name.
+    """
+
+    def __init__(self, root_name, vendored_names=(), vendor_pkg=None):
+        self.root_name = root_name
+        self.vendored_names = set(vendored_names)
+        self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor')
+
+    @property
+    def search_path(self):
+        """
+        Search first the vendor package then as a natural package.
+        """
+        yield self.vendor_pkg + '.'
+        yield ''
+
+    def find_module(self, fullname, path=None):
+        """
+        Return self when fullname starts with root_name and the
+        target module is one vendored through this importer.
+        """
+        root, base, target = fullname.partition(self.root_name + '.')
+        if root:
+            return
+        if not any(map(target.startswith, self.vendored_names)):
+            return
+        return self
+
+    def load_module(self, fullname):
+        """
+        Iterate over the search path to locate and load fullname.
+        """
+        root, base, target = fullname.partition(self.root_name + '.')
+        for prefix in self.search_path:
+            try:
+                extant = prefix + target
+                __import__(extant)
+                mod = sys.modules[extant]
+                sys.modules[fullname] = mod
+                # mysterious hack:
+                # Remove the reference to the extant package/module
+                # on later Python versions to cause relative imports
+                # in the vendor package to resolve the same modules
+                # as those going through this importer.
+                if sys.version_info > (3, 3):
+                    del sys.modules[extant]
+                return mod
+            except ImportError:
+                pass
+        else:
+            raise ImportError(
+                "The '{target}' package is required; "
+                "normally this is bundled with this package so if you get "
+                "this warning, consult the packager of your "
+                "distribution.".format(**locals())
+            )
+
+    def install(self):
+        """
+        Install this importer into sys.meta_path if not already present.
+        """
+        if self not in sys.meta_path:
+            sys.meta_path.append(self)
+
+
+names = 'packaging', 'pyparsing', 'six', 'appdirs'
+VendorImporter(__name__, names).install()
diff --git a/vendor/setuptools-39.0.1/pkg_resources/py31compat.py b/vendor/setuptools-39.0.1/pkg_resources/py31compat.py
new file mode 100644
index 00000000..331a51bb
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/py31compat.py
@@ -0,0 +1,22 @@
+import os
+import errno
+import sys
+
+
+def _makedirs_31(path, exist_ok=False):
+    try:
+        os.makedirs(path)
+    except OSError as exc:
+        if not exist_ok or exc.errno != errno.EEXIST:
+            raise
+
+
+# rely on compatibility behavior until mode considerations
+#  and exists_ok considerations are disentangled.
+# See https://github.com/pypa/setuptools/pull/1083#issuecomment-315168663
+needs_makedirs = (
+    sys.version_info < (3, 2, 5) or
+    (3, 3) <= sys.version_info < (3, 3, 6) or
+    (3, 4) <= sys.version_info < (3, 4, 1)
+)
+makedirs = _makedirs_31 if needs_makedirs else os.makedirs
diff --git a/vendor/setuptools-39.0.1/pkg_resources/tests/__init__.py b/vendor/setuptools-39.0.1/pkg_resources/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/vendor/setuptools-39.0.1/pkg_resources/tests/test_find_distributions.py b/vendor/setuptools-39.0.1/pkg_resources/tests/test_find_distributions.py
new file mode 100644
index 00000000..d735c590
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/tests/test_find_distributions.py
@@ -0,0 +1,66 @@
+import subprocess
+import sys
+
+import pytest
+import pkg_resources
+
+SETUP_TEMPLATE = """
+import setuptools
+setuptools.setup(
+    name="my-test-package",
+    version="1.0",
+    zip_safe=True,
+)
+""".lstrip()
+
+
+class TestFindDistributions:
+
+    @pytest.fixture
+    def target_dir(self, tmpdir):
+        target_dir = tmpdir.mkdir('target')
+        # place a .egg named directory in the target that is not an egg:
+        target_dir.mkdir('not.an.egg')
+        return str(target_dir)
+
+    @pytest.fixture
+    def project_dir(self, tmpdir):
+        project_dir = tmpdir.mkdir('my-test-package')
+        (project_dir / "setup.py").write(SETUP_TEMPLATE)
+        return str(project_dir)
+
+    def test_non_egg_dir_named_egg(self, target_dir):
+        dists = pkg_resources.find_distributions(target_dir)
+        assert not list(dists)
+
+    def test_standalone_egg_directory(self, project_dir, target_dir):
+        # install this distro as an unpacked egg:
+        args = [
+            sys.executable,
+            '-c', 'from setuptools.command.easy_install import main; main()',
+            '-mNx',
+            '-d', target_dir,
+            '--always-unzip',
+            project_dir,
+        ]
+        subprocess.check_call(args)
+        dists = pkg_resources.find_distributions(target_dir)
+        assert [dist.project_name for dist in dists] == ['my-test-package']
+        dists = pkg_resources.find_distributions(target_dir, only=True)
+        assert not list(dists)
+
+    def test_zipped_egg(self, project_dir, target_dir):
+        # install this distro as an unpacked egg:
+        args = [
+            sys.executable,
+            '-c', 'from setuptools.command.easy_install import main; main()',
+            '-mNx',
+            '-d', target_dir,
+            '--zip-ok',
+            project_dir,
+        ]
+        subprocess.check_call(args)
+        dists = pkg_resources.find_distributions(target_dir)
+        assert [dist.project_name for dist in dists] == ['my-test-package']
+        dists = pkg_resources.find_distributions(target_dir, only=True)
+        assert not list(dists)
diff --git a/vendor/setuptools-39.0.1/pkg_resources/tests/test_markers.py b/vendor/setuptools-39.0.1/pkg_resources/tests/test_markers.py
new file mode 100644
index 00000000..15a3b499
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/tests/test_markers.py
@@ -0,0 +1,8 @@
+import mock
+
+from pkg_resources import evaluate_marker
+
+
+@mock.patch('platform.python_version', return_value='2.7.10')
+def test_ordering(python_version_mock):
+    assert evaluate_marker("python_full_version > '2.7.3'") is True
diff --git a/vendor/setuptools-39.0.1/pkg_resources/tests/test_pkg_resources.py b/vendor/setuptools-39.0.1/pkg_resources/tests/test_pkg_resources.py
new file mode 100644
index 00000000..7442b79f
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/tests/test_pkg_resources.py
@@ -0,0 +1,209 @@
+# coding: utf-8
+from __future__ import unicode_literals
+
+import sys
+import tempfile
+import os
+import zipfile
+import datetime
+import time
+import subprocess
+import stat
+import distutils.dist
+import distutils.command.install_egg_info
+
+from pkg_resources.extern.six.moves import map
+
+import pytest
+
+import pkg_resources
+
+try:
+    unicode
+except NameError:
+    unicode = str
+
+
+def timestamp(dt):
+    """
+    Return a timestamp for a local, naive datetime instance.
+    """
+    try:
+        return dt.timestamp()
+    except AttributeError:
+        # Python 3.2 and earlier
+        return time.mktime(dt.timetuple())
+
+
+class EggRemover(unicode):
+    def __call__(self):
+        if self in sys.path:
+            sys.path.remove(self)
+        if os.path.exists(self):
+            os.remove(self)
+
+
+class TestZipProvider(object):
+    finalizers = []
+
+    ref_time = datetime.datetime(2013, 5, 12, 13, 25, 0)
+    "A reference time for a file modification"
+
+    @classmethod
+    def setup_class(cls):
+        "create a zip egg and add it to sys.path"
+        egg = tempfile.NamedTemporaryFile(suffix='.egg', delete=False)
+        zip_egg = zipfile.ZipFile(egg, 'w')
+        zip_info = zipfile.ZipInfo()
+        zip_info.filename = 'mod.py'
+        zip_info.date_time = cls.ref_time.timetuple()
+        zip_egg.writestr(zip_info, 'x = 3\n')
+        zip_info = zipfile.ZipInfo()
+        zip_info.filename = 'data.dat'
+        zip_info.date_time = cls.ref_time.timetuple()
+        zip_egg.writestr(zip_info, 'hello, world!')
+        zip_info = zipfile.ZipInfo()
+        zip_info.filename = 'subdir/mod2.py'
+        zip_info.date_time = cls.ref_time.timetuple()
+        zip_egg.writestr(zip_info, 'x = 6\n')
+        zip_info = zipfile.ZipInfo()
+        zip_info.filename = 'subdir/data2.dat'
+        zip_info.date_time = cls.ref_time.timetuple()
+        zip_egg.writestr(zip_info, 'goodbye, world!')
+        zip_egg.close()
+        egg.close()
+
+        sys.path.append(egg.name)
+        subdir = os.path.join(egg.name, 'subdir')
+        sys.path.append(subdir)
+        cls.finalizers.append(EggRemover(subdir))
+        cls.finalizers.append(EggRemover(egg.name))
+
+    @classmethod
+    def teardown_class(cls):
+        for finalizer in cls.finalizers:
+            finalizer()
+
+    def test_resource_listdir(self):
+        import mod
+        zp = pkg_resources.ZipProvider(mod)
+
+        expected_root = ['data.dat', 'mod.py', 'subdir']
+        assert sorted(zp.resource_listdir('')) == expected_root
+        assert sorted(zp.resource_listdir('/')) == expected_root
+
+        expected_subdir = ['data2.dat', 'mod2.py']
+        assert sorted(zp.resource_listdir('subdir')) == expected_subdir
+        assert sorted(zp.resource_listdir('subdir/')) == expected_subdir
+
+        assert zp.resource_listdir('nonexistent') == []
+        assert zp.resource_listdir('nonexistent/') == []
+
+        import mod2
+        zp2 = pkg_resources.ZipProvider(mod2)
+
+        assert sorted(zp2.resource_listdir('')) == expected_subdir
+        assert sorted(zp2.resource_listdir('/')) == expected_subdir
+
+        assert zp2.resource_listdir('subdir') == []
+        assert zp2.resource_listdir('subdir/') == []
+
+    def test_resource_filename_rewrites_on_change(self):
+        """
+        If a previous call to get_resource_filename has saved the file, but
+        the file has been subsequently mutated with different file of the
+        same size and modification time, it should not be overwritten on a
+        subsequent call to get_resource_filename.
+        """
+        import mod
+        manager = pkg_resources.ResourceManager()
+        zp = pkg_resources.ZipProvider(mod)
+        filename = zp.get_resource_filename(manager, 'data.dat')
+        actual = datetime.datetime.fromtimestamp(os.stat(filename).st_mtime)
+        assert actual == self.ref_time
+        f = open(filename, 'w')
+        f.write('hello, world?')
+        f.close()
+        ts = timestamp(self.ref_time)
+        os.utime(filename, (ts, ts))
+        filename = zp.get_resource_filename(manager, 'data.dat')
+        with open(filename) as f:
+            assert f.read() == 'hello, world!'
+        manager.cleanup_resources()
+
+
+class TestResourceManager(object):
+    def test_get_cache_path(self):
+        mgr = pkg_resources.ResourceManager()
+        path = mgr.get_cache_path('foo')
+        type_ = str(type(path))
+        message = "Unexpected type from get_cache_path: " + type_
+        assert isinstance(path, (unicode, str)), message
+
+
+class TestIndependence:
+    """
+    Tests to ensure that pkg_resources runs independently from setuptools.
+    """
+
+    def test_setuptools_not_imported(self):
+        """
+        In a separate Python environment, import pkg_resources and assert
+        that action doesn't cause setuptools to be imported.
+        """
+        lines = (
+            'import pkg_resources',
+            'import sys',
+            (
+                'assert "setuptools" not in sys.modules, '
+                '"setuptools was imported"'
+            ),
+        )
+        cmd = [sys.executable, '-c', '; '.join(lines)]
+        subprocess.check_call(cmd)
+
+
+class TestDeepVersionLookupDistutils(object):
+    @pytest.fixture
+    def env(self, tmpdir):
+        """
+        Create a package environment, similar to a virtualenv,
+        in which packages are installed.
+        """
+
+        class Environment(str):
+            pass
+
+        env = Environment(tmpdir)
+        tmpdir.chmod(stat.S_IRWXU)
+        subs = 'home', 'lib', 'scripts', 'data', 'egg-base'
+        env.paths = dict(
+            (dirname, str(tmpdir / dirname))
+            for dirname in subs
+        )
+        list(map(os.mkdir, env.paths.values()))
+        return env
+
+    def create_foo_pkg(self, env, version):
+        """
+        Create a foo package installed (distutils-style) to env.paths['lib']
+        as version.
+        """
+        ld = "This package has unicode metadata! ❄"
+        attrs = dict(name='foo', version=version, long_description=ld)
+        dist = distutils.dist.Distribution(attrs)
+        iei_cmd = distutils.command.install_egg_info.install_egg_info(dist)
+        iei_cmd.initialize_options()
+        iei_cmd.install_dir = env.paths['lib']
+        iei_cmd.finalize_options()
+        iei_cmd.run()
+
+    def test_version_resolved_from_egg_info(self, env):
+        version = '1.11.0.dev0+2329eae'
+        self.create_foo_pkg(env, version)
+
+        # this requirement parsing will raise a VersionConflict unless the
+        # .egg-info file is parsed (see #419 on BitBucket)
+        req = pkg_resources.Requirement.parse('foo>=1.9')
+        dist = pkg_resources.WorkingSet([env.paths['lib']]).find(req)
+        assert dist.version == version
diff --git a/vendor/setuptools-39.0.1/pkg_resources/tests/test_resources.py b/vendor/setuptools-39.0.1/pkg_resources/tests/test_resources.py
new file mode 100644
index 00000000..05f35ade
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/tests/test_resources.py
@@ -0,0 +1,834 @@
+from __future__ import unicode_literals
+
+import os
+import sys
+import string
+import platform
+import itertools
+
+from pkg_resources.extern.six.moves import map
+
+import pytest
+from pkg_resources.extern import packaging
+
+import pkg_resources
+from pkg_resources import (
+    parse_requirements, VersionConflict, parse_version,
+    Distribution, EntryPoint, Requirement, safe_version, safe_name,
+    WorkingSet)
+
+
+# from Python 3.6 docs.
+def pairwise(iterable):
+    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
+    a, b = itertools.tee(iterable)
+    next(b, None)
+    return zip(a, b)
+
+
+class Metadata(pkg_resources.EmptyProvider):
+    """Mock object to return metadata as if from an on-disk distribution"""
+
+    def __init__(self, *pairs):
+        self.metadata = dict(pairs)
+
+    def has_metadata(self, name):
+        return name in self.metadata
+
+    def get_metadata(self, name):
+        return self.metadata[name]
+
+    def get_metadata_lines(self, name):
+        return pkg_resources.yield_lines(self.get_metadata(name))
+
+
+dist_from_fn = pkg_resources.Distribution.from_filename
+
+
+class TestDistro:
+    def testCollection(self):
+        # empty path should produce no distributions
+        ad = pkg_resources.Environment([], platform=None, python=None)
+        assert list(ad) == []
+        assert ad['FooPkg'] == []
+        ad.add(dist_from_fn("FooPkg-1.3_1.egg"))
+        ad.add(dist_from_fn("FooPkg-1.4-py2.4-win32.egg"))
+        ad.add(dist_from_fn("FooPkg-1.2-py2.4.egg"))
+
+        # Name is in there now
+        assert ad['FooPkg']
+        # But only 1 package
+        assert list(ad) == ['foopkg']
+
+        # Distributions sort by version
+        expected = ['1.4', '1.3-1', '1.2']
+        assert [dist.version for dist in ad['FooPkg']] == expected
+
+        # Removing a distribution leaves sequence alone
+        ad.remove(ad['FooPkg'][1])
+        assert [dist.version for dist in ad['FooPkg']] == ['1.4', '1.2']
+
+        # And inserting adds them in order
+        ad.add(dist_from_fn("FooPkg-1.9.egg"))
+        assert [dist.version for dist in ad['FooPkg']] == ['1.9', '1.4', '1.2']
+
+        ws = WorkingSet([])
+        foo12 = dist_from_fn("FooPkg-1.2-py2.4.egg")
+        foo14 = dist_from_fn("FooPkg-1.4-py2.4-win32.egg")
+        req, = parse_requirements("FooPkg>=1.3")
+
+        # Nominal case: no distros on path, should yield all applicable
+        assert ad.best_match(req, ws).version == '1.9'
+        # If a matching distro is already installed, should return only that
+        ws.add(foo14)
+        assert ad.best_match(req, ws).version == '1.4'
+
+        # If the first matching distro is unsuitable, it's a version conflict
+        ws = WorkingSet([])
+        ws.add(foo12)
+        ws.add(foo14)
+        with pytest.raises(VersionConflict):
+            ad.best_match(req, ws)
+
+        # If more than one match on the path, the first one takes precedence
+        ws = WorkingSet([])
+        ws.add(foo14)
+        ws.add(foo12)
+        ws.add(foo14)
+        assert ad.best_match(req, ws).version == '1.4'
+
+    def checkFooPkg(self, d):
+        assert d.project_name == "FooPkg"
+        assert d.key == "foopkg"
+        assert d.version == "1.3.post1"
+        assert d.py_version == "2.4"
+        assert d.platform == "win32"
+        assert d.parsed_version == parse_version("1.3-1")
+
+    def testDistroBasics(self):
+        d = Distribution(
+            "/some/path",
+            project_name="FooPkg",
+            version="1.3-1",
+            py_version="2.4",
+            platform="win32",
+        )
+        self.checkFooPkg(d)
+
+        d = Distribution("/some/path")
+        assert d.py_version == sys.version[:3]
+        assert d.platform is None
+
+    def testDistroParse(self):
+        d = dist_from_fn("FooPkg-1.3.post1-py2.4-win32.egg")
+        self.checkFooPkg(d)
+        d = dist_from_fn("FooPkg-1.3.post1-py2.4-win32.egg-info")
+        self.checkFooPkg(d)
+
+    def testDistroMetadata(self):
+        d = Distribution(
+            "/some/path", project_name="FooPkg",
+            py_version="2.4", platform="win32",
+            metadata=Metadata(
+                ('PKG-INFO', "Metadata-Version: 1.0\nVersion: 1.3-1\n")
+            ),
+        )
+        self.checkFooPkg(d)
+
+    def distRequires(self, txt):
+        return Distribution("/foo", metadata=Metadata(('depends.txt', txt)))
+
+    def checkRequires(self, dist, txt, extras=()):
+        assert list(dist.requires(extras)) == list(parse_requirements(txt))
+
+    def testDistroDependsSimple(self):
+        for v in "Twisted>=1.5", "Twisted>=1.5\nZConfig>=2.0":
+            self.checkRequires(self.distRequires(v), v)
+
+    def testResolve(self):
+        ad = pkg_resources.Environment([])
+        ws = WorkingSet([])
+        # Resolving no requirements -> nothing to install
+        assert list(ws.resolve([], ad)) == []
+        # Request something not in the collection -> DistributionNotFound
+        with pytest.raises(pkg_resources.DistributionNotFound):
+            ws.resolve(parse_requirements("Foo"), ad)
+
+        Foo = Distribution.from_filename(
+            "/foo_dir/Foo-1.2.egg",
+            metadata=Metadata(('depends.txt', "[bar]\nBaz>=2.0"))
+        )
+        ad.add(Foo)
+        ad.add(Distribution.from_filename("Foo-0.9.egg"))
+
+        # Request thing(s) that are available -> list to activate
+        for i in range(3):
+            targets = list(ws.resolve(parse_requirements("Foo"), ad))
+            assert targets == [Foo]
+            list(map(ws.add, targets))
+        with pytest.raises(VersionConflict):
+            ws.resolve(parse_requirements("Foo==0.9"), ad)
+        ws = WorkingSet([])  # reset
+
+        # Request an extra that causes an unresolved dependency for "Baz"
+        with pytest.raises(pkg_resources.DistributionNotFound):
+            ws.resolve(parse_requirements("Foo[bar]"), ad)
+        Baz = Distribution.from_filename(
+            "/foo_dir/Baz-2.1.egg", metadata=Metadata(('depends.txt', "Foo"))
+        )
+        ad.add(Baz)
+
+        # Activation list now includes resolved dependency
+        assert (
+            list(ws.resolve(parse_requirements("Foo[bar]"), ad))
+            == [Foo, Baz]
+        )
+        # Requests for conflicting versions produce VersionConflict
+        with pytest.raises(VersionConflict) as vc:
+            ws.resolve(parse_requirements("Foo==1.2\nFoo!=1.2"), ad)
+
+        msg = 'Foo 0.9 is installed but Foo==1.2 is required'
+        assert vc.value.report() == msg
+
+    def test_environment_marker_evaluation_negative(self):
+        """Environment markers are evaluated at resolution time."""
+        ad = pkg_resources.Environment([])
+        ws = WorkingSet([])
+        res = ws.resolve(parse_requirements("Foo;python_version<'2'"), ad)
+        assert list(res) == []
+
+    def test_environment_marker_evaluation_positive(self):
+        ad = pkg_resources.Environment([])
+        ws = WorkingSet([])
+        Foo = Distribution.from_filename("/foo_dir/Foo-1.2.dist-info")
+        ad.add(Foo)
+        res = ws.resolve(parse_requirements("Foo;python_version>='2'"), ad)
+        assert list(res) == [Foo]
+
+    def test_environment_marker_evaluation_called(self):
+        """
+        If one package foo requires bar without any extras,
+        markers should pass for bar without extras.
+        """
+        parent_req, = parse_requirements("foo")
+        req, = parse_requirements("bar;python_version>='2'")
+        req_extras = pkg_resources._ReqExtras({req: parent_req.extras})
+        assert req_extras.markers_pass(req)
+
+        parent_req, = parse_requirements("foo[]")
+        req, = parse_requirements("bar;python_version>='2'")
+        req_extras = pkg_resources._ReqExtras({req: parent_req.extras})
+        assert req_extras.markers_pass(req)
+
+    def test_marker_evaluation_with_extras(self):
+        """Extras are also evaluated as markers at resolution time."""
+        ad = pkg_resources.Environment([])
+        ws = WorkingSet([])
+        Foo = Distribution.from_filename(
+            "/foo_dir/Foo-1.2.dist-info",
+            metadata=Metadata(("METADATA", "Provides-Extra: baz\n"
+                               "Requires-Dist: quux; extra=='baz'"))
+        )
+        ad.add(Foo)
+        assert list(ws.resolve(parse_requirements("Foo"), ad)) == [Foo]
+        quux = Distribution.from_filename("/foo_dir/quux-1.0.dist-info")
+        ad.add(quux)
+        res = list(ws.resolve(parse_requirements("Foo[baz]"), ad))
+        assert res == [Foo, quux]
+
+    def test_marker_evaluation_with_extras_normlized(self):
+        """Extras are also evaluated as markers at resolution time."""
+        ad = pkg_resources.Environment([])
+        ws = WorkingSet([])
+        Foo = Distribution.from_filename(
+            "/foo_dir/Foo-1.2.dist-info",
+            metadata=Metadata(("METADATA", "Provides-Extra: baz-lightyear\n"
+                               "Requires-Dist: quux; extra=='baz-lightyear'"))
+        )
+        ad.add(Foo)
+        assert list(ws.resolve(parse_requirements("Foo"), ad)) == [Foo]
+        quux = Distribution.from_filename("/foo_dir/quux-1.0.dist-info")
+        ad.add(quux)
+        res = list(ws.resolve(parse_requirements("Foo[baz-lightyear]"), ad))
+        assert res == [Foo, quux]
+
+    def test_marker_evaluation_with_multiple_extras(self):
+        ad = pkg_resources.Environment([])
+        ws = WorkingSet([])
+        Foo = Distribution.from_filename(
+            "/foo_dir/Foo-1.2.dist-info",
+            metadata=Metadata(("METADATA", "Provides-Extra: baz\n"
+                               "Requires-Dist: quux; extra=='baz'\n"
+                               "Provides-Extra: bar\n"
+                               "Requires-Dist: fred; extra=='bar'\n"))
+        )
+        ad.add(Foo)
+        quux = Distribution.from_filename("/foo_dir/quux-1.0.dist-info")
+        ad.add(quux)
+        fred = Distribution.from_filename("/foo_dir/fred-0.1.dist-info")
+        ad.add(fred)
+        res = list(ws.resolve(parse_requirements("Foo[baz,bar]"), ad))
+        assert sorted(res) == [fred, quux, Foo]
+
+    def test_marker_evaluation_with_extras_loop(self):
+        ad = pkg_resources.Environment([])
+        ws = WorkingSet([])
+        a = Distribution.from_filename(
+            "/foo_dir/a-0.2.dist-info",
+            metadata=Metadata(("METADATA", "Requires-Dist: c[a]"))
+        )
+        b = Distribution.from_filename(
+            "/foo_dir/b-0.3.dist-info",
+            metadata=Metadata(("METADATA", "Requires-Dist: c[b]"))
+        )
+        c = Distribution.from_filename(
+            "/foo_dir/c-1.0.dist-info",
+            metadata=Metadata(("METADATA", "Provides-Extra: a\n"
+                               "Requires-Dist: b;extra=='a'\n"
+                               "Provides-Extra: b\n"
+                               "Requires-Dist: foo;extra=='b'"))
+        )
+        foo = Distribution.from_filename("/foo_dir/foo-0.1.dist-info")
+        for dist in (a, b, c, foo):
+            ad.add(dist)
+        res = list(ws.resolve(parse_requirements("a"), ad))
+        assert res == [a, c, b, foo]
+
+    def testDistroDependsOptions(self):
+        d = self.distRequires("""
+            Twisted>=1.5
+            [docgen]
+            ZConfig>=2.0
+            docutils>=0.3
+            [fastcgi]
+            fcgiapp>=0.1""")
+        self.checkRequires(d, "Twisted>=1.5")
+        self.checkRequires(
+            d, "Twisted>=1.5 ZConfig>=2.0 docutils>=0.3".split(), ["docgen"]
+        )
+        self.checkRequires(
+            d, "Twisted>=1.5 fcgiapp>=0.1".split(), ["fastcgi"]
+        )
+        self.checkRequires(
+            d, "Twisted>=1.5 ZConfig>=2.0 docutils>=0.3 fcgiapp>=0.1".split(),
+            ["docgen", "fastcgi"]
+        )
+        self.checkRequires(
+            d, "Twisted>=1.5 fcgiapp>=0.1 ZConfig>=2.0 docutils>=0.3".split(),
+            ["fastcgi", "docgen"]
+        )
+        with pytest.raises(pkg_resources.UnknownExtra):
+            d.requires(["foo"])
+
+
+class TestWorkingSet:
+    def test_find_conflicting(self):
+        ws = WorkingSet([])
+        Foo = Distribution.from_filename("/foo_dir/Foo-1.2.egg")
+        ws.add(Foo)
+
+        # create a requirement that conflicts with Foo 1.2
+        req = next(parse_requirements("Foo<1.2"))
+
+        with pytest.raises(VersionConflict) as vc:
+            ws.find(req)
+
+        msg = 'Foo 1.2 is installed but Foo<1.2 is required'
+        assert vc.value.report() == msg
+
+    def test_resolve_conflicts_with_prior(self):
+        """
+        A ContextualVersionConflict should be raised when a requirement
+        conflicts with a prior requirement for a different package.
+        """
+        # Create installation where Foo depends on Baz 1.0 and Bar depends on
+        # Baz 2.0.
+        ws = WorkingSet([])
+        md = Metadata(('depends.txt', "Baz==1.0"))
+        Foo = Distribution.from_filename("/foo_dir/Foo-1.0.egg", metadata=md)
+        ws.add(Foo)
+        md = Metadata(('depends.txt', "Baz==2.0"))
+        Bar = Distribution.from_filename("/foo_dir/Bar-1.0.egg", metadata=md)
+        ws.add(Bar)
+        Baz = Distribution.from_filename("/foo_dir/Baz-1.0.egg")
+        ws.add(Baz)
+        Baz = Distribution.from_filename("/foo_dir/Baz-2.0.egg")
+        ws.add(Baz)
+
+        with pytest.raises(VersionConflict) as vc:
+            ws.resolve(parse_requirements("Foo\nBar\n"))
+
+        msg = "Baz 1.0 is installed but Baz==2.0 is required by "
+        msg += repr(set(['Bar']))
+        assert vc.value.report() == msg
+
+
+class TestEntryPoints:
+    def assertfields(self, ep):
+        assert ep.name == "foo"
+        assert ep.module_name == "pkg_resources.tests.test_resources"
+        assert ep.attrs == ("TestEntryPoints",)
+        assert ep.extras == ("x",)
+        assert ep.load() is TestEntryPoints
+        expect = "foo = pkg_resources.tests.test_resources:TestEntryPoints [x]"
+        assert str(ep) == expect
+
+    def setup_method(self, method):
+        self.dist = Distribution.from_filename(
+            "FooPkg-1.2-py2.4.egg", metadata=Metadata(('requires.txt', '[x]')))
+
+    def testBasics(self):
+        ep = EntryPoint(
+            "foo", "pkg_resources.tests.test_resources", ["TestEntryPoints"],
+            ["x"], self.dist
+        )
+        self.assertfields(ep)
+
+    def testParse(self):
+        s = "foo = pkg_resources.tests.test_resources:TestEntryPoints [x]"
+        ep = EntryPoint.parse(s, self.dist)
+        self.assertfields(ep)
+
+        ep = EntryPoint.parse("bar baz=  spammity[PING]")
+        assert ep.name == "bar baz"
+        assert ep.module_name == "spammity"
+        assert ep.attrs == ()
+        assert ep.extras == ("ping",)
+
+        ep = EntryPoint.parse(" fizzly =  wocka:foo")
+        assert ep.name == "fizzly"
+        assert ep.module_name == "wocka"
+        assert ep.attrs == ("foo",)
+        assert ep.extras == ()
+
+        # plus in the name
+        spec = "html+mako = mako.ext.pygmentplugin:MakoHtmlLexer"
+        ep = EntryPoint.parse(spec)
+        assert ep.name == 'html+mako'
+
+    reject_specs = "foo", "x=a:b:c", "q=x/na", "fez=pish:tush-z", "x=f[a]>2"
+
+    @pytest.mark.parametrize("reject_spec", reject_specs)
+    def test_reject_spec(self, reject_spec):
+        with pytest.raises(ValueError):
+            EntryPoint.parse(reject_spec)
+
+    def test_printable_name(self):
+        """
+        Allow any printable character in the name.
+        """
+        # Create a name with all printable characters; strip the whitespace.
+        name = string.printable.strip()
+        spec = "{name} = module:attr".format(**locals())
+        ep = EntryPoint.parse(spec)
+        assert ep.name == name
+
+    def checkSubMap(self, m):
+        assert len(m) == len(self.submap_expect)
+        for key, ep in self.submap_expect.items():
+            assert m.get(key).name == ep.name
+            assert m.get(key).module_name == ep.module_name
+            assert sorted(m.get(key).attrs) == sorted(ep.attrs)
+            assert sorted(m.get(key).extras) == sorted(ep.extras)
+
+    submap_expect = dict(
+        feature1=EntryPoint('feature1', 'somemodule', ['somefunction']),
+        feature2=EntryPoint(
+            'feature2', 'another.module', ['SomeClass'], ['extra1', 'extra2']),
+        feature3=EntryPoint('feature3', 'this.module', extras=['something'])
+    )
+    submap_str = """
+            # define features for blah blah
+            feature1 = somemodule:somefunction
+            feature2 = another.module:SomeClass [extra1,extra2]
+            feature3 = this.module [something]
+    """
+
+    def testParseList(self):
+        self.checkSubMap(EntryPoint.parse_group("xyz", self.submap_str))
+        with pytest.raises(ValueError):
+            EntryPoint.parse_group("x a", "foo=bar")
+        with pytest.raises(ValueError):
+            EntryPoint.parse_group("x", ["foo=baz", "foo=bar"])
+
+    def testParseMap(self):
+        m = EntryPoint.parse_map({'xyz': self.submap_str})
+        self.checkSubMap(m['xyz'])
+        assert list(m.keys()) == ['xyz']
+        m = EntryPoint.parse_map("[xyz]\n" + self.submap_str)
+        self.checkSubMap(m['xyz'])
+        assert list(m.keys()) == ['xyz']
+        with pytest.raises(ValueError):
+            EntryPoint.parse_map(["[xyz]", "[xyz]"])
+        with pytest.raises(ValueError):
+            EntryPoint.parse_map(self.submap_str)
+
+
+class TestRequirements:
+    def testBasics(self):
+        r = Requirement.parse("Twisted>=1.2")
+        assert str(r) == "Twisted>=1.2"
+        assert repr(r) == "Requirement.parse('Twisted>=1.2')"
+        assert r == Requirement("Twisted>=1.2")
+        assert r == Requirement("twisTed>=1.2")
+        assert r != Requirement("Twisted>=2.0")
+        assert r != Requirement("Zope>=1.2")
+        assert r != Requirement("Zope>=3.0")
+        assert r != Requirement("Twisted[extras]>=1.2")
+
+    def testOrdering(self):
+        r1 = Requirement("Twisted==1.2c1,>=1.2")
+        r2 = Requirement("Twisted>=1.2,==1.2c1")
+        assert r1 == r2
+        assert str(r1) == str(r2)
+        assert str(r2) == "Twisted==1.2c1,>=1.2"
+
+    def testBasicContains(self):
+        r = Requirement("Twisted>=1.2")
+        foo_dist = Distribution.from_filename("FooPkg-1.3_1.egg")
+        twist11 = Distribution.from_filename("Twisted-1.1.egg")
+        twist12 = Distribution.from_filename("Twisted-1.2.egg")
+        assert parse_version('1.2') in r
+        assert parse_version('1.1') not in r
+        assert '1.2' in r
+        assert '1.1' not in r
+        assert foo_dist not in r
+        assert twist11 not in r
+        assert twist12 in r
+
+    def testOptionsAndHashing(self):
+        r1 = Requirement.parse("Twisted[foo,bar]>=1.2")
+        r2 = Requirement.parse("Twisted[bar,FOO]>=1.2")
+        assert r1 == r2
+        assert set(r1.extras) == set(("foo", "bar"))
+        assert set(r2.extras) == set(("foo", "bar"))
+        assert hash(r1) == hash(r2)
+        assert (
+            hash(r1)
+            ==
+            hash((
+                "twisted",
+                packaging.specifiers.SpecifierSet(">=1.2"),
+                frozenset(["foo", "bar"]),
+                None
+            ))
+        )
+
+    def testVersionEquality(self):
+        r1 = Requirement.parse("foo==0.3a2")
+        r2 = Requirement.parse("foo!=0.3a4")
+        d = Distribution.from_filename
+
+        assert d("foo-0.3a4.egg") not in r1
+        assert d("foo-0.3a1.egg") not in r1
+        assert d("foo-0.3a4.egg") not in r2
+
+        assert d("foo-0.3a2.egg") in r1
+        assert d("foo-0.3a2.egg") in r2
+        assert d("foo-0.3a3.egg") in r2
+        assert d("foo-0.3a5.egg") in r2
+
+    def testSetuptoolsProjectName(self):
+        """
+        The setuptools project should implement the setuptools package.
+        """
+
+        assert (
+            Requirement.parse('setuptools').project_name == 'setuptools')
+        # setuptools 0.7 and higher means setuptools.
+        assert (
+            Requirement.parse('setuptools == 0.7').project_name
+            == 'setuptools'
+        )
+        assert (
+            Requirement.parse('setuptools == 0.7a1').project_name
+            == 'setuptools'
+        )
+        assert (
+            Requirement.parse('setuptools >= 0.7').project_name
+            == 'setuptools'
+        )
+
+
+class TestParsing:
+    def testEmptyParse(self):
+        assert list(parse_requirements('')) == []
+
+    def testYielding(self):
+        for inp, out in [
+            ([], []), ('x', ['x']), ([[]], []), (' x\n y', ['x', 'y']),
+            (['x\n\n', 'y'], ['x', 'y']),
+        ]:
+            assert list(pkg_resources.yield_lines(inp)) == out
+
+    def testSplitting(self):
+        sample = """
+                    x
+                    [Y]
+                    z
+
+                    a
+                    [b ]
+                    # foo
+                    c
+                    [ d]
+                    [q]
+                    v
+                    """
+        assert (
+            list(pkg_resources.split_sections(sample))
+            ==
+            [
+                (None, ["x"]),
+                ("Y", ["z", "a"]),
+                ("b", ["c"]),
+                ("d", []),
+                ("q", ["v"]),
+            ]
+        )
+        with pytest.raises(ValueError):
+            list(pkg_resources.split_sections("[foo"))
+
+    def testSafeName(self):
+        assert safe_name("adns-python") == "adns-python"
+        assert safe_name("WSGI Utils") == "WSGI-Utils"
+        assert safe_name("WSGI  Utils") == "WSGI-Utils"
+        assert safe_name("Money$$$Maker") == "Money-Maker"
+        assert safe_name("peak.web") != "peak-web"
+
+    def testSafeVersion(self):
+        assert safe_version("1.2-1") == "1.2.post1"
+        assert safe_version("1.2 alpha") == "1.2.alpha"
+        assert safe_version("2.3.4 20050521") == "2.3.4.20050521"
+        assert safe_version("Money$$$Maker") == "Money-Maker"
+        assert safe_version("peak.web") == "peak.web"
+
+    def testSimpleRequirements(self):
+        assert (
+            list(parse_requirements('Twis-Ted>=1.2-1'))
+            ==
+            [Requirement('Twis-Ted>=1.2-1')]
+        )
+        assert (
+            list(parse_requirements('Twisted >=1.2, \\ # more\n<2.0'))
+            ==
+            [Requirement('Twisted>=1.2,<2.0')]
+        )
+        assert (
+            Requirement.parse("FooBar==1.99a3")
+            ==
+            Requirement("FooBar==1.99a3")
+        )
+        with pytest.raises(ValueError):
+            Requirement.parse(">=2.3")
+        with pytest.raises(ValueError):
+            Requirement.parse("x\\")
+        with pytest.raises(ValueError):
+            Requirement.parse("x==2 q")
+        with pytest.raises(ValueError):
+            Requirement.parse("X==1\nY==2")
+        with pytest.raises(ValueError):
+            Requirement.parse("#")
+
+    def test_requirements_with_markers(self):
+        assert (
+            Requirement.parse("foobar;os_name=='a'")
+            ==
+            Requirement.parse("foobar;os_name=='a'")
+        )
+        assert (
+            Requirement.parse("name==1.1;python_version=='2.7'")
+            !=
+            Requirement.parse("name==1.1;python_version=='3.3'")
+        )
+        assert (
+            Requirement.parse("name==1.0;python_version=='2.7'")
+            !=
+            Requirement.parse("name==1.2;python_version=='2.7'")
+        )
+        assert (
+            Requirement.parse("name[foo]==1.0;python_version=='3.3'")
+            !=
+            Requirement.parse("name[foo,bar]==1.0;python_version=='3.3'")
+        )
+
+    def test_local_version(self):
+        req, = parse_requirements('foo==1.0.org1')
+
+    def test_spaces_between_multiple_versions(self):
+        req, = parse_requirements('foo>=1.0, <3')
+        req, = parse_requirements('foo >= 1.0, < 3')
+
+    @pytest.mark.parametrize(
+        ['lower', 'upper'],
+        [
+            ('1.2-rc1', '1.2rc1'),
+            ('0.4', '0.4.0'),
+            ('0.4.0.0', '0.4.0'),
+            ('0.4.0-0', '0.4-0'),
+            ('0post1', '0.0post1'),
+            ('0pre1', '0.0c1'),
+            ('0.0.0preview1', '0c1'),
+            ('0.0c1', '0-rc1'),
+            ('1.2a1', '1.2.a.1'),
+            ('1.2.a', '1.2a'),
+        ],
+    )
+    def testVersionEquality(self, lower, upper):
+        assert parse_version(lower) == parse_version(upper)
+
+    torture = """
+        0.80.1-3 0.80.1-2 0.80.1-1 0.79.9999+0.80.0pre4-1
+        0.79.9999+0.80.0pre2-3 0.79.9999+0.80.0pre2-2
+        0.77.2-1 0.77.1-1 0.77.0-1
+        """
+
+    @pytest.mark.parametrize(
+        ['lower', 'upper'],
+        [
+            ('2.1', '2.1.1'),
+            ('2a1', '2b0'),
+            ('2a1', '2.1'),
+            ('2.3a1', '2.3'),
+            ('2.1-1', '2.1-2'),
+            ('2.1-1', '2.1.1'),
+            ('2.1', '2.1post4'),
+            ('2.1a0-20040501', '2.1'),
+            ('1.1', '02.1'),
+            ('3.2', '3.2.post0'),
+            ('3.2post1', '3.2post2'),
+            ('0.4', '4.0'),
+            ('0.0.4', '0.4.0'),
+            ('0post1', '0.4post1'),
+            ('2.1.0-rc1', '2.1.0'),
+            ('2.1dev', '2.1a0'),
+        ] + list(pairwise(reversed(torture.split()))),
+    )
+    def testVersionOrdering(self, lower, upper):
+        assert parse_version(lower) < parse_version(upper)
+
+    def testVersionHashable(self):
+        """
+        Ensure that our versions stay hashable even though we've subclassed
+        them and added some shim code to them.
+        """
+        assert (
+            hash(parse_version("1.0"))
+            ==
+            hash(parse_version("1.0"))
+        )
+
+
+class TestNamespaces:
+
+    ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n"
+
+    @pytest.yield_fixture
+    def symlinked_tmpdir(self, tmpdir):
+        """
+        Where available, return the tempdir as a symlink,
+        which as revealed in #231 is more fragile than
+        a natural tempdir.
+        """
+        if not hasattr(os, 'symlink'):
+            yield str(tmpdir)
+            return
+
+        link_name = str(tmpdir) + '-linked'
+        os.symlink(str(tmpdir), link_name)
+        try:
+            yield type(tmpdir)(link_name)
+        finally:
+            os.unlink(link_name)
+
+    @pytest.yield_fixture(autouse=True)
+    def patched_path(self, tmpdir):
+        """
+        Patch sys.path to include the 'site-pkgs' dir. Also
+        restore pkg_resources._namespace_packages to its
+        former state.
+        """
+        saved_ns_pkgs = pkg_resources._namespace_packages.copy()
+        saved_sys_path = sys.path[:]
+        site_pkgs = tmpdir.mkdir('site-pkgs')
+        sys.path.append(str(site_pkgs))
+        try:
+            yield
+        finally:
+            pkg_resources._namespace_packages = saved_ns_pkgs
+            sys.path = saved_sys_path
+
+    issue591 = pytest.mark.xfail(platform.system() == 'Windows', reason="#591")
+
+    @issue591
+    def test_two_levels_deep(self, symlinked_tmpdir):
+        """
+        Test nested namespace packages
+        Create namespace packages in the following tree :
+            site-packages-1/pkg1/pkg2
+            site-packages-2/pkg1/pkg2
+        Check both are in the _namespace_packages dict and that their __path__
+        is correct
+        """
+        real_tmpdir = symlinked_tmpdir.realpath()
+        tmpdir = symlinked_tmpdir
+        sys.path.append(str(tmpdir / 'site-pkgs2'))
+        site_dirs = tmpdir / 'site-pkgs', tmpdir / 'site-pkgs2'
+        for site in site_dirs:
+            pkg1 = site / 'pkg1'
+            pkg2 = pkg1 / 'pkg2'
+            pkg2.ensure_dir()
+            (pkg1 / '__init__.py').write_text(self.ns_str, encoding='utf-8')
+            (pkg2 / '__init__.py').write_text(self.ns_str, encoding='utf-8')
+        import pkg1
+        assert "pkg1" in pkg_resources._namespace_packages
+        # attempt to import pkg2 from site-pkgs2
+        import pkg1.pkg2
+        # check the _namespace_packages dict
+        assert "pkg1.pkg2" in pkg_resources._namespace_packages
+        assert pkg_resources._namespace_packages["pkg1"] == ["pkg1.pkg2"]
+        # check the __path__ attribute contains both paths
+        expected = [
+            str(real_tmpdir / "site-pkgs" / "pkg1" / "pkg2"),
+            str(real_tmpdir / "site-pkgs2" / "pkg1" / "pkg2"),
+        ]
+        assert pkg1.pkg2.__path__ == expected
+
+    @issue591
+    def test_path_order(self, symlinked_tmpdir):
+        """
+        Test that if multiple versions of the same namespace package subpackage
+        are on different sys.path entries, that only the one earliest on
+        sys.path is imported, and that the namespace package's __path__ is in
+        the correct order.
+
+        Regression test for https://github.com/pypa/setuptools/issues/207
+        """
+
+        tmpdir = symlinked_tmpdir
+        site_dirs = (
+            tmpdir / "site-pkgs",
+            tmpdir / "site-pkgs2",
+            tmpdir / "site-pkgs3",
+        )
+
+        vers_str = "__version__ = %r"
+
+        for number, site in enumerate(site_dirs, 1):
+            if number > 1:
+                sys.path.append(str(site))
+            nspkg = site / 'nspkg'
+            subpkg = nspkg / 'subpkg'
+            subpkg.ensure_dir()
+            (nspkg / '__init__.py').write_text(self.ns_str, encoding='utf-8')
+            (subpkg / '__init__.py').write_text(
+                vers_str % number, encoding='utf-8')
+
+        import nspkg.subpkg
+        import nspkg
+        expected = [
+            str(site.realpath() / 'nspkg')
+            for site in site_dirs
+        ]
+        assert nspkg.__path__ == expected
+        assert nspkg.subpkg.__version__ == 1
diff --git a/vendor/setuptools-39.0.1/pkg_resources/tests/test_working_set.py b/vendor/setuptools-39.0.1/pkg_resources/tests/test_working_set.py
new file mode 100644
index 00000000..42ddcc86
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pkg_resources/tests/test_working_set.py
@@ -0,0 +1,482 @@
+import inspect
+import re
+import textwrap
+import functools
+
+import pytest
+
+import pkg_resources
+
+from .test_resources import Metadata
+
+
+def strip_comments(s):
+    return '\n'.join(
+        l for l in s.split('\n')
+        if l.strip() and not l.strip().startswith('#')
+    )
+
+
+def parse_distributions(s):
+    '''
+    Parse a series of distribution specs of the form:
+    {project_name}-{version}
+       [optional, indented requirements specification]
+
+    Example:
+
+        foo-0.2
+        bar-1.0
+          foo>=3.0
+          [feature]
+          baz
+
+    yield 2 distributions:
+        - project_name=foo, version=0.2
+        - project_name=bar, version=1.0,
+          requires=['foo>=3.0', 'baz; extra=="feature"']
+    '''
+    s = s.strip()
+    for spec in re.split('\n(?=[^\s])', s):
+        if not spec:
+            continue
+        fields = spec.split('\n', 1)
+        assert 1 <= len(fields) <= 2
+        name, version = fields.pop(0).split('-')
+        if fields:
+            requires = textwrap.dedent(fields.pop(0))
+            metadata = Metadata(('requires.txt', requires))
+        else:
+            metadata = None
+        dist = pkg_resources.Distribution(project_name=name,
+                                          version=version,
+                                          metadata=metadata)
+        yield dist
+
+
+class FakeInstaller(object):
+
+    def __init__(self, installable_dists):
+        self._installable_dists = installable_dists
+
+    def __call__(self, req):
+        return next(iter(filter(lambda dist: dist in req,
+                                self._installable_dists)), None)
+
+
+def parametrize_test_working_set_resolve(*test_list):
+    idlist = []
+    argvalues = []
+    for test in test_list:
+        (
+            name,
+            installed_dists,
+            installable_dists,
+            requirements,
+            expected1, expected2
+        ) = [
+            strip_comments(s.lstrip()) for s in
+            textwrap.dedent(test).lstrip().split('\n\n', 5)
+        ]
+        installed_dists = list(parse_distributions(installed_dists))
+        installable_dists = list(parse_distributions(installable_dists))
+        requirements = list(pkg_resources.parse_requirements(requirements))
+        for id_, replace_conflicting, expected in (
+            (name, False, expected1),
+            (name + '_replace_conflicting', True, expected2),
+        ):
+            idlist.append(id_)
+            expected = strip_comments(expected.strip())
+            if re.match('\w+$', expected):
+                expected = getattr(pkg_resources, expected)
+                assert issubclass(expected, Exception)
+            else:
+                expected = list(parse_distributions(expected))
+            argvalues.append(pytest.param(installed_dists, installable_dists,
+                                          requirements, replace_conflicting,
+                                          expected))
+    return pytest.mark.parametrize('installed_dists,installable_dists,'
+                                   'requirements,replace_conflicting,'
+                                   'resolved_dists_or_exception',
+                                   argvalues, ids=idlist)
+
+
+@parametrize_test_working_set_resolve(
+    '''
+    # id
+    noop
+
+    # installed
+
+    # installable
+
+    # wanted
+
+    # resolved
+
+    # resolved [replace conflicting]
+    ''',
+
+    '''
+    # id
+    already_installed
+
+    # installed
+    foo-3.0
+
+    # installable
+
+    # wanted
+    foo>=2.1,!=3.1,<4
+
+    # resolved
+    foo-3.0
+
+    # resolved [replace conflicting]
+    foo-3.0
+    ''',
+
+    '''
+    # id
+    installable_not_installed
+
+    # installed
+
+    # installable
+    foo-3.0
+    foo-4.0
+
+    # wanted
+    foo>=2.1,!=3.1,<4
+
+    # resolved
+    foo-3.0
+
+    # resolved [replace conflicting]
+    foo-3.0
+    ''',
+
+    '''
+    # id
+    not_installable
+
+    # installed
+
+    # installable
+
+    # wanted
+    foo>=2.1,!=3.1,<4
+
+    # resolved
+    DistributionNotFound
+
+    # resolved [replace conflicting]
+    DistributionNotFound
+    ''',
+
+    '''
+    # id
+    no_matching_version
+
+    # installed
+
+    # installable
+    foo-3.1
+
+    # wanted
+    foo>=2.1,!=3.1,<4
+
+    # resolved
+    DistributionNotFound
+
+    # resolved [replace conflicting]
+    DistributionNotFound
+    ''',
+
+    '''
+    # id
+    installable_with_installed_conflict
+
+    # installed
+    foo-3.1
+
+    # installable
+    foo-3.5
+
+    # wanted
+    foo>=2.1,!=3.1,<4
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    foo-3.5
+    ''',
+
+    '''
+    # id
+    not_installable_with_installed_conflict
+
+    # installed
+    foo-3.1
+
+    # installable
+
+    # wanted
+    foo>=2.1,!=3.1,<4
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    DistributionNotFound
+    ''',
+
+    '''
+    # id
+    installed_with_installed_require
+
+    # installed
+    foo-3.9
+    baz-0.1
+        foo>=2.1,!=3.1,<4
+
+    # installable
+
+    # wanted
+    baz
+
+    # resolved
+    foo-3.9
+    baz-0.1
+
+    # resolved [replace conflicting]
+    foo-3.9
+    baz-0.1
+    ''',
+
+    '''
+    # id
+    installed_with_conflicting_installed_require
+
+    # installed
+    foo-5
+    baz-0.1
+        foo>=2.1,!=3.1,<4
+
+    # installable
+
+    # wanted
+    baz
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    DistributionNotFound
+    ''',
+
+    '''
+    # id
+    installed_with_installable_conflicting_require
+
+    # installed
+    foo-5
+    baz-0.1
+        foo>=2.1,!=3.1,<4
+
+    # installable
+    foo-2.9
+
+    # wanted
+    baz
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    baz-0.1
+    foo-2.9
+    ''',
+
+    '''
+    # id
+    installed_with_installable_require
+
+    # installed
+    baz-0.1
+        foo>=2.1,!=3.1,<4
+
+    # installable
+    foo-3.9
+
+    # wanted
+    baz
+
+    # resolved
+    foo-3.9
+    baz-0.1
+
+    # resolved [replace conflicting]
+    foo-3.9
+    baz-0.1
+    ''',
+
+    '''
+    # id
+    installable_with_installed_require
+
+    # installed
+    foo-3.9
+
+    # installable
+    baz-0.1
+        foo>=2.1,!=3.1,<4
+
+    # wanted
+    baz
+
+    # resolved
+    foo-3.9
+    baz-0.1
+
+    # resolved [replace conflicting]
+    foo-3.9
+    baz-0.1
+    ''',
+
+    '''
+    # id
+    installable_with_installable_require
+
+    # installed
+
+    # installable
+    foo-3.9
+    baz-0.1
+        foo>=2.1,!=3.1,<4
+
+    # wanted
+    baz
+
+    # resolved
+    foo-3.9
+    baz-0.1
+
+    # resolved [replace conflicting]
+    foo-3.9
+    baz-0.1
+    ''',
+
+    '''
+    # id
+    installable_with_conflicting_installable_require
+
+    # installed
+    foo-5
+
+    # installable
+    foo-2.9
+    baz-0.1
+        foo>=2.1,!=3.1,<4
+
+    # wanted
+    baz
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    baz-0.1
+    foo-2.9
+    ''',
+
+    '''
+    # id
+    conflicting_installables
+
+    # installed
+
+    # installable
+    foo-2.9
+    foo-5.0
+
+    # wanted
+    foo>=2.1,!=3.1,<4
+    foo>=4
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    VersionConflict
+    ''',
+
+    '''
+    # id
+    installables_with_conflicting_requires
+
+    # installed
+
+    # installable
+    foo-2.9
+        dep==1.0
+    baz-5.0
+        dep==2.0
+    dep-1.0
+    dep-2.0
+
+    # wanted
+    foo
+    baz
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    VersionConflict
+    ''',
+
+    '''
+    # id
+    installables_with_conflicting_nested_requires
+
+    # installed
+
+    # installable
+    foo-2.9
+        dep1
+    dep1-1.0
+        subdep<1.0
+    baz-5.0
+        dep2
+    dep2-1.0
+        subdep>1.0
+    subdep-0.9
+    subdep-1.1
+
+    # wanted
+    foo
+    baz
+
+    # resolved
+    VersionConflict
+
+    # resolved [replace conflicting]
+    VersionConflict
+    ''',
+)
+def test_working_set_resolve(installed_dists, installable_dists, requirements,
+                             replace_conflicting, resolved_dists_or_exception):
+    ws = pkg_resources.WorkingSet([])
+    list(map(ws.add, installed_dists))
+    resolve_call = functools.partial(
+        ws.resolve,
+        requirements, installer=FakeInstaller(installable_dists),
+        replace_conflicting=replace_conflicting,
+    )
+    if inspect.isclass(resolved_dists_or_exception):
+        with pytest.raises(resolved_dists_or_exception):
+            resolve_call()
+    else:
+        assert sorted(resolve_call()) == sorted(resolved_dists_or_exception)
diff --git a/vendor/setuptools-39.0.1/pytest.ini b/vendor/setuptools-39.0.1/pytest.ini
new file mode 100755
index 00000000..16fdc5af
--- /dev/null
+++ b/vendor/setuptools-39.0.1/pytest.ini
@@ -0,0 +1,6 @@
+[pytest]
+addopts=--doctest-modules --ignore release.py --ignore setuptools/lib2to3_ex.py --ignore tests/manual_test.py --ignore tests/test_pypi.py --ignore tests/shlib_test --doctest-glob=pkg_resources/api_tests.txt --ignore scripts/upload-old-releases-as-zip.py --ignore pavement.py --ignore setuptools/tests/mod_with_constant.py -rsxX
+norecursedirs=dist build *.egg setuptools/extern pkg_resources/extern .*
+flake8-ignore =
+    setuptools/site-patch.py F821
+    setuptools/py*compat.py F811
diff --git a/vendor/setuptools-39.0.1/setup.cfg b/vendor/setuptools-39.0.1/setup.cfg
new file mode 100755
index 00000000..750619bd
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setup.cfg
@@ -0,0 +1,29 @@
+[bumpversion]
+current_version = 39.0.1
+commit = True
+tag = True
+
+[egg_info]
+tag_build = 
+tag_date = 0
+
+[aliases]
+clean_egg_info = egg_info -Db ''
+release = clean_egg_info sdist bdist_wheel
+source = register sdist binary
+binary = bdist_egg upload --show-response
+
+[upload]
+repository = https://upload.pypi.org/legacy/
+
+[sdist]
+formats = zip
+
+[bdist_wheel]
+universal = 1
+
+[metadata]
+license_file = LICENSE
+
+[bumpversion:file:setup.py]
+
diff --git a/vendor/setuptools-39.0.1/setup.py b/vendor/setuptools-39.0.1/setup.py
new file mode 100755
index 00000000..9ac05104
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setup.py
@@ -0,0 +1,195 @@
+#!/usr/bin/env python
+"""
+Distutils setup file, used to install or test 'setuptools'
+"""
+
+import io
+import os
+import sys
+import textwrap
+
+import setuptools
+
+here = os.path.dirname(__file__)
+
+
+def require_metadata():
+    "Prevent improper installs without necessary metadata. See #659"
+    egg_info_dir = os.path.join(here, 'setuptools.egg-info')
+    if not os.path.exists(egg_info_dir):
+        msg = (
+            "Cannot build setuptools without metadata. "
+            "Run `bootstrap.py`."
+        )
+        raise RuntimeError(msg)
+
+
+def read_commands():
+    command_ns = {}
+    cmd_module_path = 'setuptools/command/__init__.py'
+    init_path = os.path.join(here, cmd_module_path)
+    with open(init_path) as init_file:
+        exec(init_file.read(), command_ns)
+    return command_ns['__all__']
+
+
+def _gen_console_scripts():
+    yield "easy_install = setuptools.command.easy_install:main"
+
+    # Gentoo distributions manage the python-version-specific scripts
+    # themselves, so those platforms define an environment variable to
+    # suppress the creation of the version-specific scripts.
+    var_names = (
+        'SETUPTOOLS_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT',
+        'DISTRIBUTE_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT',
+    )
+    if any(os.environ.get(var) not in (None, "", "0") for var in var_names):
+        return
+    tmpl = "easy_install-{shortver} = setuptools.command.easy_install:main"
+    yield tmpl.format(shortver=sys.version[:3])
+
+
+readme_path = os.path.join(here, 'README.rst')
+with io.open(readme_path, encoding='utf-8') as readme_file:
+    long_description = readme_file.read()
+
+package_data = dict(
+    setuptools=['script (dev).tmpl', 'script.tmpl', 'site-patch.py'],
+)
+
+force_windows_specific_files = (
+    os.environ.get("SETUPTOOLS_INSTALL_WINDOWS_SPECIFIC_FILES", "1").lower()
+    not in ("", "0", "false", "no")
+)
+
+include_windows_files = (
+    sys.platform == 'win32' or
+    os.name == 'java' and os._name == 'nt' or
+    force_windows_specific_files
+)
+
+if include_windows_files:
+    package_data.setdefault('setuptools', []).extend(['*.exe'])
+    package_data.setdefault('setuptools.command', []).extend(['*.xml'])
+
+needs_wheel = set(['release', 'bdist_wheel']).intersection(sys.argv)
+wheel = ['wheel'] if needs_wheel else []
+
+
+def pypi_link(pkg_filename):
+    """
+    Given the filename, including md5 fragment, construct the
+    dependency link for PyPI.
+    """
+    root = 'https://files.pythonhosted.org/packages/source'
+    name, sep, rest = pkg_filename.partition('-')
+    parts = root, name[0], name, pkg_filename
+    return '/'.join(parts)
+
+
+setup_params = dict(
+    name="setuptools",
+    version="39.0.1",
+    description=(
+        "Easily download, build, install, upgrade, and uninstall "
+        "Python packages"
+    ),
+    author="Python Packaging Authority",
+    author_email="distutils-sig@python.org",
+    long_description=long_description,
+    long_description_content_type='text/x-rst; charset=UTF-8',
+    keywords="CPAN PyPI distutils eggs package management",
+    url="https://github.com/pypa/setuptools",
+    project_urls={
+        "Documentation": "https://setuptools.readthedocs.io/",
+    },
+    src_root=None,
+    packages=setuptools.find_packages(exclude=['*.tests']),
+    package_data=package_data,
+    py_modules=['easy_install'],
+    zip_safe=True,
+    entry_points={
+        "distutils.commands": [
+            "%(cmd)s = setuptools.command.%(cmd)s:%(cmd)s" % locals()
+            for cmd in read_commands()
+        ],
+        "distutils.setup_keywords": [
+            "eager_resources        = setuptools.dist:assert_string_list",
+            "namespace_packages     = setuptools.dist:check_nsp",
+            "extras_require         = setuptools.dist:check_extras",
+            "install_requires       = setuptools.dist:check_requirements",
+            "tests_require          = setuptools.dist:check_requirements",
+            "setup_requires         = setuptools.dist:check_requirements",
+            "python_requires        = setuptools.dist:check_specifier",
+            "entry_points           = setuptools.dist:check_entry_points",
+            "test_suite             = setuptools.dist:check_test_suite",
+            "zip_safe               = setuptools.dist:assert_bool",
+            "package_data           = setuptools.dist:check_package_data",
+            "exclude_package_data   = setuptools.dist:check_package_data",
+            "include_package_data   = setuptools.dist:assert_bool",
+            "packages               = setuptools.dist:check_packages",
+            "dependency_links       = setuptools.dist:assert_string_list",
+            "test_loader            = setuptools.dist:check_importable",
+            "test_runner            = setuptools.dist:check_importable",
+            "use_2to3               = setuptools.dist:assert_bool",
+            "convert_2to3_doctests  = setuptools.dist:assert_string_list",
+            "use_2to3_fixers        = setuptools.dist:assert_string_list",
+            "use_2to3_exclude_fixers = setuptools.dist:assert_string_list",
+        ],
+        "egg_info.writers": [
+            "PKG-INFO = setuptools.command.egg_info:write_pkg_info",
+            "requires.txt = setuptools.command.egg_info:write_requirements",
+            "entry_points.txt = setuptools.command.egg_info:write_entries",
+            "eager_resources.txt = setuptools.command.egg_info:overwrite_arg",
+            (
+                "namespace_packages.txt = "
+                "setuptools.command.egg_info:overwrite_arg"
+            ),
+            "top_level.txt = setuptools.command.egg_info:write_toplevel_names",
+            "depends.txt = setuptools.command.egg_info:warn_depends_obsolete",
+            "dependency_links.txt = setuptools.command.egg_info:overwrite_arg",
+        ],
+        "console_scripts": list(_gen_console_scripts()),
+        "setuptools.installation":
+            ['eggsecutable = setuptools.command.easy_install:bootstrap'],
+    },
+    classifiers=textwrap.dedent("""
+        Development Status :: 5 - Production/Stable
+        Intended Audience :: Developers
+        License :: OSI Approved :: MIT License
+        Operating System :: OS Independent
+        Programming Language :: Python :: 2
+        Programming Language :: Python :: 2.7
+        Programming Language :: Python :: 3
+        Programming Language :: Python :: 3.3
+        Programming Language :: Python :: 3.4
+        Programming Language :: Python :: 3.5
+        Programming Language :: Python :: 3.6
+        Topic :: Software Development :: Libraries :: Python Modules
+        Topic :: System :: Archiving :: Packaging
+        Topic :: System :: Systems Administration
+        Topic :: Utilities
+        """).strip().splitlines(),
+    python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*',
+    extras_require={
+        "ssl:sys_platform=='win32'": "wincertstore==0.2",
+        "certs": "certifi==2016.9.26",
+    },
+    dependency_links=[
+        pypi_link(
+            'certifi-2016.9.26.tar.gz#md5=baa81e951a29958563689d868ef1064d',
+        ),
+        pypi_link(
+            'wincertstore-0.2.zip#md5=ae728f2f007185648d0c7a8679b361e2',
+        ),
+    ],
+    scripts=[],
+    setup_requires=[
+    ] + wheel,
+)
+
+if __name__ == '__main__':
+    # allow setup.py to run from another directory
+    here and os.chdir(here)
+    require_metadata()
+    dist = setuptools.setup(**setup_params)
diff --git a/vendor/setuptools-39.0.1/setuptools.egg-info/PKG-INFO b/vendor/setuptools-39.0.1/setuptools.egg-info/PKG-INFO
new file mode 100644
index 00000000..5413a505
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools.egg-info/PKG-INFO
@@ -0,0 +1,65 @@
+Metadata-Version: 2.1
+Name: setuptools
+Version: 39.0.1
+Summary: Easily download, build, install, upgrade, and uninstall Python packages
+Home-page: https://github.com/pypa/setuptools
+Author: Python Packaging Authority
+Author-email: distutils-sig@python.org
+License: UNKNOWN
+Project-URL: Documentation, https://setuptools.readthedocs.io/
+Description: .. image:: https://img.shields.io/pypi/v/setuptools.svg
+           :target: https://pypi.org/project/setuptools
+        
+        .. image:: https://readthedocs.org/projects/setuptools/badge/?version=latest
+            :target: https://setuptools.readthedocs.io
+        
+        .. image:: https://img.shields.io/travis/pypa/setuptools/master.svg?label=Linux%20build%20%40%20Travis%20CI
+           :target: https://travis-ci.org/pypa/setuptools
+        
+        .. image:: https://img.shields.io/appveyor/ci/jaraco/setuptools/master.svg?label=Windows%20build%20%40%20Appveyor
+           :target: https://ci.appveyor.com/project/jaraco/setuptools/branch/master
+        
+        .. image:: https://img.shields.io/pypi/pyversions/setuptools.svg
+        
+        See the `Installation Instructions
+        <https://packaging.python.org/installing/>`_ in the Python Packaging
+        User's Guide for instructions on installing, upgrading, and uninstalling
+        Setuptools.
+        
+        The project is `maintained at GitHub <https://github.com/pypa/setuptools>`_.
+        
+        Questions and comments should be directed to the `distutils-sig
+        mailing list <http://mail.python.org/pipermail/distutils-sig/>`_.
+        Bug reports and especially tested patches may be
+        submitted directly to the `bug tracker
+        <https://github.com/pypa/setuptools/issues>`_.
+        
+        
+        Code of Conduct
+        ---------------
+        
+        Everyone interacting in the setuptools project's codebases, issue trackers,
+        chat rooms, and mailing lists is expected to follow the
+        `PyPA Code of Conduct <https://www.pypa.io/en/latest/code-of-conduct/>`_.
+        
+Keywords: CPAN PyPI distutils eggs package management
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: System :: Archiving :: Packaging
+Classifier: Topic :: System :: Systems Administration
+Classifier: Topic :: Utilities
+Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*
+Description-Content-Type: text/x-rst; charset=UTF-8
+Provides-Extra: ssl
+Provides-Extra: certs
diff --git a/vendor/setuptools-39.0.1/setuptools.egg-info/SOURCES.txt b/vendor/setuptools-39.0.1/setuptools.egg-info/SOURCES.txt
new file mode 100644
index 00000000..93f588de
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools.egg-info/SOURCES.txt
@@ -0,0 +1,192 @@
+CHANGES.rst
+LICENSE
+MANIFEST.in
+README.rst
+bootstrap.py
+conftest.py
+easy_install.py
+launcher.c
+msvc-build-launcher.cmd
+pavement.py
+pytest.ini
+setup.cfg
+setup.py
+tox.ini
+docs/Makefile
+docs/conf.py
+docs/developer-guide.txt
+docs/development.txt
+docs/easy_install.txt
+docs/formats.txt
+docs/history.txt
+docs/index.txt
+docs/pkg_resources.txt
+docs/python3.txt
+docs/releases.txt
+docs/requirements.txt
+docs/roadmap.txt
+docs/setuptools.txt
+docs/_templates/indexsidebar.html
+docs/_theme/nature/theme.conf
+docs/_theme/nature/static/nature.css_t
+docs/_theme/nature/static/pygments.css
+pkg_resources/__init__.py
+pkg_resources/api_tests.txt
+pkg_resources/py31compat.py
+pkg_resources/_vendor/__init__.py
+pkg_resources/_vendor/appdirs.py
+pkg_resources/_vendor/pyparsing.py
+pkg_resources/_vendor/six.py
+pkg_resources/_vendor/vendored.txt
+pkg_resources/_vendor/packaging/__about__.py
+pkg_resources/_vendor/packaging/__init__.py
+pkg_resources/_vendor/packaging/_compat.py
+pkg_resources/_vendor/packaging/_structures.py
+pkg_resources/_vendor/packaging/markers.py
+pkg_resources/_vendor/packaging/requirements.py
+pkg_resources/_vendor/packaging/specifiers.py
+pkg_resources/_vendor/packaging/utils.py
+pkg_resources/_vendor/packaging/version.py
+pkg_resources/extern/__init__.py
+pkg_resources/tests/__init__.py
+pkg_resources/tests/test_find_distributions.py
+pkg_resources/tests/test_markers.py
+pkg_resources/tests/test_pkg_resources.py
+pkg_resources/tests/test_resources.py
+pkg_resources/tests/test_working_set.py
+setuptools/__init__.py
+setuptools/archive_util.py
+setuptools/build_meta.py
+setuptools/cli-32.exe
+setuptools/cli-64.exe
+setuptools/cli.exe
+setuptools/config.py
+setuptools/dep_util.py
+setuptools/depends.py
+setuptools/dist.py
+setuptools/extension.py
+setuptools/glibc.py
+setuptools/glob.py
+setuptools/gui-32.exe
+setuptools/gui-64.exe
+setuptools/gui.exe
+setuptools/launch.py
+setuptools/lib2to3_ex.py
+setuptools/monkey.py
+setuptools/msvc.py
+setuptools/namespaces.py
+setuptools/package_index.py
+setuptools/pep425tags.py
+setuptools/py27compat.py
+setuptools/py31compat.py
+setuptools/py33compat.py
+setuptools/py36compat.py
+setuptools/sandbox.py
+setuptools/script (dev).tmpl
+setuptools/script.tmpl
+setuptools/site-patch.py
+setuptools/ssl_support.py
+setuptools/unicode_utils.py
+setuptools/version.py
+setuptools/wheel.py
+setuptools/windows_support.py
+setuptools.egg-info/PKG-INFO
+setuptools.egg-info/SOURCES.txt
+setuptools.egg-info/dependency_links.txt
+setuptools.egg-info/entry_points.txt
+setuptools.egg-info/requires.txt
+setuptools.egg-info/top_level.txt
+setuptools.egg-info/zip-safe
+setuptools/_vendor/__init__.py
+setuptools/_vendor/pyparsing.py
+setuptools/_vendor/six.py
+setuptools/_vendor/vendored.txt
+setuptools/_vendor/__pycache__/__init__.cpython-36.pyc
+setuptools/_vendor/__pycache__/six.cpython-36.pyc
+setuptools/_vendor/packaging/__about__.py
+setuptools/_vendor/packaging/__init__.py
+setuptools/_vendor/packaging/_compat.py
+setuptools/_vendor/packaging/_structures.py
+setuptools/_vendor/packaging/markers.py
+setuptools/_vendor/packaging/requirements.py
+setuptools/_vendor/packaging/specifiers.py
+setuptools/_vendor/packaging/utils.py
+setuptools/_vendor/packaging/version.py
+setuptools/_vendor/packaging/__pycache__/__about__.cpython-36.pyc
+setuptools/_vendor/packaging/__pycache__/__init__.cpython-36.pyc
+setuptools/_vendor/packaging/__pycache__/_compat.cpython-36.pyc
+setuptools/_vendor/packaging/__pycache__/_structures.cpython-36.pyc
+setuptools/_vendor/packaging/__pycache__/specifiers.cpython-36.pyc
+setuptools/_vendor/packaging/__pycache__/version.cpython-36.pyc
+setuptools/command/__init__.py
+setuptools/command/alias.py
+setuptools/command/bdist_egg.py
+setuptools/command/bdist_rpm.py
+setuptools/command/bdist_wininst.py
+setuptools/command/build_clib.py
+setuptools/command/build_ext.py
+setuptools/command/build_py.py
+setuptools/command/develop.py
+setuptools/command/dist_info.py
+setuptools/command/easy_install.py
+setuptools/command/egg_info.py
+setuptools/command/install.py
+setuptools/command/install_egg_info.py
+setuptools/command/install_lib.py
+setuptools/command/install_scripts.py
+setuptools/command/launcher manifest.xml
+setuptools/command/py36compat.py
+setuptools/command/register.py
+setuptools/command/rotate.py
+setuptools/command/saveopts.py
+setuptools/command/sdist.py
+setuptools/command/setopt.py
+setuptools/command/test.py
+setuptools/command/upload.py
+setuptools/command/upload_docs.py
+setuptools/extern/__init__.py
+setuptools/tests/__init__.py
+setuptools/tests/contexts.py
+setuptools/tests/environment.py
+setuptools/tests/files.py
+setuptools/tests/fixtures.py
+setuptools/tests/mod_with_constant.py
+setuptools/tests/namespaces.py
+setuptools/tests/script-with-bom.py
+setuptools/tests/server.py
+setuptools/tests/test_archive_util.py
+setuptools/tests/test_bdist_egg.py
+setuptools/tests/test_build_clib.py
+setuptools/tests/test_build_ext.py
+setuptools/tests/test_build_meta.py
+setuptools/tests/test_build_py.py
+setuptools/tests/test_config.py
+setuptools/tests/test_dep_util.py
+setuptools/tests/test_depends.py
+setuptools/tests/test_develop.py
+setuptools/tests/test_dist.py
+setuptools/tests/test_dist_info.py
+setuptools/tests/test_easy_install.py
+setuptools/tests/test_egg_info.py
+setuptools/tests/test_find_packages.py
+setuptools/tests/test_install_scripts.py
+setuptools/tests/test_integration.py
+setuptools/tests/test_manifest.py
+setuptools/tests/test_msvc.py
+setuptools/tests/test_namespaces.py
+setuptools/tests/test_packageindex.py
+setuptools/tests/test_sandbox.py
+setuptools/tests/test_sdist.py
+setuptools/tests/test_setuptools.py
+setuptools/tests/test_test.py
+setuptools/tests/test_unicode_utils.py
+setuptools/tests/test_upload_docs.py
+setuptools/tests/test_virtualenv.py
+setuptools/tests/test_wheel.py
+setuptools/tests/test_windows_wrappers.py
+setuptools/tests/text.py
+setuptools/tests/textwrap.py
+setuptools/tests/indexes/test_links_priority/external.html
+setuptools/tests/indexes/test_links_priority/simple/foobar/index.html
+tests/manual_test.py
+tests/test_pypi.py
\ No newline at end of file
diff --git a/vendor/setuptools-39.0.1/setuptools.egg-info/dependency_links.txt b/vendor/setuptools-39.0.1/setuptools.egg-info/dependency_links.txt
new file mode 100644
index 00000000..e87d0210
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools.egg-info/dependency_links.txt
@@ -0,0 +1,2 @@
+https://files.pythonhosted.org/packages/source/c/certifi/certifi-2016.9.26.tar.gz#md5=baa81e951a29958563689d868ef1064d
+https://files.pythonhosted.org/packages/source/w/wincertstore/wincertstore-0.2.zip#md5=ae728f2f007185648d0c7a8679b361e2
diff --git a/vendor/setuptools-39.0.1/setuptools.egg-info/entry_points.txt b/vendor/setuptools-39.0.1/setuptools.egg-info/entry_points.txt
new file mode 100644
index 00000000..77c7c7fb
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools.egg-info/entry_points.txt
@@ -0,0 +1,65 @@
+[console_scripts]
+easy_install = setuptools.command.easy_install:main
+easy_install-2.7 = setuptools.command.easy_install:main
+
+[distutils.commands]
+alias = setuptools.command.alias:alias
+bdist_egg = setuptools.command.bdist_egg:bdist_egg
+bdist_rpm = setuptools.command.bdist_rpm:bdist_rpm
+bdist_wininst = setuptools.command.bdist_wininst:bdist_wininst
+build_clib = setuptools.command.build_clib:build_clib
+build_ext = setuptools.command.build_ext:build_ext
+build_py = setuptools.command.build_py:build_py
+develop = setuptools.command.develop:develop
+dist_info = setuptools.command.dist_info:dist_info
+easy_install = setuptools.command.easy_install:easy_install
+egg_info = setuptools.command.egg_info:egg_info
+install = setuptools.command.install:install
+install_egg_info = setuptools.command.install_egg_info:install_egg_info
+install_lib = setuptools.command.install_lib:install_lib
+install_scripts = setuptools.command.install_scripts:install_scripts
+register = setuptools.command.register:register
+rotate = setuptools.command.rotate:rotate
+saveopts = setuptools.command.saveopts:saveopts
+sdist = setuptools.command.sdist:sdist
+setopt = setuptools.command.setopt:setopt
+test = setuptools.command.test:test
+upload = setuptools.command.upload:upload
+upload_docs = setuptools.command.upload_docs:upload_docs
+
+[distutils.setup_keywords]
+convert_2to3_doctests = setuptools.dist:assert_string_list
+dependency_links = setuptools.dist:assert_string_list
+eager_resources = setuptools.dist:assert_string_list
+entry_points = setuptools.dist:check_entry_points
+exclude_package_data = setuptools.dist:check_package_data
+extras_require = setuptools.dist:check_extras
+include_package_data = setuptools.dist:assert_bool
+install_requires = setuptools.dist:check_requirements
+namespace_packages = setuptools.dist:check_nsp
+package_data = setuptools.dist:check_package_data
+packages = setuptools.dist:check_packages
+python_requires = setuptools.dist:check_specifier
+setup_requires = setuptools.dist:check_requirements
+test_loader = setuptools.dist:check_importable
+test_runner = setuptools.dist:check_importable
+test_suite = setuptools.dist:check_test_suite
+tests_require = setuptools.dist:check_requirements
+use_2to3 = setuptools.dist:assert_bool
+use_2to3_exclude_fixers = setuptools.dist:assert_string_list
+use_2to3_fixers = setuptools.dist:assert_string_list
+zip_safe = setuptools.dist:assert_bool
+
+[egg_info.writers]
+PKG-INFO = setuptools.command.egg_info:write_pkg_info
+dependency_links.txt = setuptools.command.egg_info:overwrite_arg
+depends.txt = setuptools.command.egg_info:warn_depends_obsolete
+eager_resources.txt = setuptools.command.egg_info:overwrite_arg
+entry_points.txt = setuptools.command.egg_info:write_entries
+namespace_packages.txt = setuptools.command.egg_info:overwrite_arg
+requires.txt = setuptools.command.egg_info:write_requirements
+top_level.txt = setuptools.command.egg_info:write_toplevel_names
+
+[setuptools.installation]
+eggsecutable = setuptools.command.easy_install:bootstrap
+
diff --git a/vendor/setuptools-39.0.1/setuptools.egg-info/requires.txt b/vendor/setuptools-39.0.1/setuptools.egg-info/requires.txt
new file mode 100644
index 00000000..c1529e48
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools.egg-info/requires.txt
@@ -0,0 +1,6 @@
+
+[certs]
+certifi==2016.9.26
+
+[ssl:sys_platform=='win32']
+wincertstore==0.2
diff --git a/vendor/setuptools-39.0.1/setuptools.egg-info/top_level.txt b/vendor/setuptools-39.0.1/setuptools.egg-info/top_level.txt
new file mode 100644
index 00000000..4577c6a7
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools.egg-info/top_level.txt
@@ -0,0 +1,3 @@
+easy_install
+pkg_resources
+setuptools
diff --git a/vendor/setuptools-39.0.1/setuptools.egg-info/zip-safe b/vendor/setuptools-39.0.1/setuptools.egg-info/zip-safe
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools.egg-info/zip-safe
@@ -0,0 +1 @@
+
diff --git a/vendor/setuptools-39.0.1/setuptools/__init__.py b/vendor/setuptools-39.0.1/setuptools/__init__.py
new file mode 100644
index 00000000..7da47fbe
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/__init__.py
@@ -0,0 +1,180 @@
+"""Extensions to the 'distutils' for large or complex distributions"""
+
+import os
+import functools
+import distutils.core
+import distutils.filelist
+from distutils.util import convert_path
+from fnmatch import fnmatchcase
+
+from setuptools.extern.six.moves import filter, map
+
+import setuptools.version
+from setuptools.extension import Extension
+from setuptools.dist import Distribution, Feature
+from setuptools.depends import Require
+from . import monkey
+
+__all__ = [
+    'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require',
+    'find_packages',
+]
+
+__version__ = setuptools.version.__version__
+
+bootstrap_install_from = None
+
+# If we run 2to3 on .py files, should we also convert docstrings?
+# Default: yes; assume that we can detect doctests reliably
+run_2to3_on_doctests = True
+# Standard package names for fixer packages
+lib2to3_fixer_packages = ['lib2to3.fixes']
+
+
+class PackageFinder(object):
+    """
+    Generate a list of all Python packages found within a directory
+    """
+
+    @classmethod
+    def find(cls, where='.', exclude=(), include=('*',)):
+        """Return a list all Python packages found within directory 'where'
+
+        'where' is the root directory which will be searched for packages.  It
+        should be supplied as a "cross-platform" (i.e. URL-style) path; it will
+        be converted to the appropriate local path syntax.
+
+        'exclude' is a sequence of package names to exclude; '*' can be used
+        as a wildcard in the names, such that 'foo.*' will exclude all
+        subpackages of 'foo' (but not 'foo' itself).
+
+        'include' is a sequence of package names to include.  If it's
+        specified, only the named packages will be included.  If it's not
+        specified, all found packages will be included.  'include' can contain
+        shell style wildcard patterns just like 'exclude'.
+        """
+
+        return list(cls._find_packages_iter(
+            convert_path(where),
+            cls._build_filter('ez_setup', '*__pycache__', *exclude),
+            cls._build_filter(*include)))
+
+    @classmethod
+    def _find_packages_iter(cls, where, exclude, include):
+        """
+        All the packages found in 'where' that pass the 'include' filter, but
+        not the 'exclude' filter.
+        """
+        for root, dirs, files in os.walk(where, followlinks=True):
+            # Copy dirs to iterate over it, then empty dirs.
+            all_dirs = dirs[:]
+            dirs[:] = []
+
+            for dir in all_dirs:
+                full_path = os.path.join(root, dir)
+                rel_path = os.path.relpath(full_path, where)
+                package = rel_path.replace(os.path.sep, '.')
+
+                # Skip directory trees that are not valid packages
+                if ('.' in dir or not cls._looks_like_package(full_path)):
+                    continue
+
+                # Should this package be included?
+                if include(package) and not exclude(package):
+                    yield package
+
+                # Keep searching subdirectories, as there may be more packages
+                # down there, even if the parent was excluded.
+                dirs.append(dir)
+
+    @staticmethod
+    def _looks_like_package(path):
+        """Does a directory look like a package?"""
+        return os.path.isfile(os.path.join(path, '__init__.py'))
+
+    @staticmethod
+    def _build_filter(*patterns):
+        """
+        Given a list of patterns, return a callable that will be true only if
+        the input matches at least one of the patterns.
+        """
+        return lambda name: any(fnmatchcase(name, pat=pat) for pat in patterns)
+
+
+class PEP420PackageFinder(PackageFinder):
+    @staticmethod
+    def _looks_like_package(path):
+        return True
+
+
+find_packages = PackageFinder.find
+
+
+def _install_setup_requires(attrs):
+    # Note: do not use `setuptools.Distribution` directly, as
+    # our PEP 517 backend patch `distutils.core.Distribution`.
+    dist = distutils.core.Distribution(dict(
+        (k, v) for k, v in attrs.items()
+        if k in ('dependency_links', 'setup_requires')
+    ))
+    # Honor setup.cfg's options.
+    dist.parse_config_files(ignore_option_errors=True)
+    if dist.setup_requires:
+        dist.fetch_build_eggs(dist.setup_requires)
+
+
+def setup(**attrs):
+    # Make sure we have any requirements needed to interpret 'attrs'.
+    _install_setup_requires(attrs)
+    return distutils.core.setup(**attrs)
+
+setup.__doc__ = distutils.core.setup.__doc__
+
+
+_Command = monkey.get_unpatched(distutils.core.Command)
+
+
+class Command(_Command):
+    __doc__ = _Command.__doc__
+
+    command_consumes_arguments = False
+
+    def __init__(self, dist, **kw):
+        """
+        Construct the command for dist, updating
+        vars(self) with any keyword parameters.
+        """
+        _Command.__init__(self, dist)
+        vars(self).update(kw)
+
+    def reinitialize_command(self, command, reinit_subcommands=0, **kw):
+        cmd = _Command.reinitialize_command(self, command, reinit_subcommands)
+        vars(cmd).update(kw)
+        return cmd
+
+
+def _find_all_simple(path):
+    """
+    Find all files under 'path'
+    """
+    results = (
+        os.path.join(base, file)
+        for base, dirs, files in os.walk(path, followlinks=True)
+        for file in files
+    )
+    return filter(os.path.isfile, results)
+
+
+def findall(dir=os.curdir):
+    """
+    Find all files under 'dir' and return the list of full filenames.
+    Unless dir is '.', return full filenames with dir prepended.
+    """
+    files = _find_all_simple(dir)
+    if dir == os.curdir:
+        make_rel = functools.partial(os.path.relpath, start=dir)
+        files = map(make_rel, files)
+    return list(files)
+
+
+monkey.patch_all()
diff --git a/vendor/setuptools-39.0.1/setuptools/_vendor/__init__.py b/vendor/setuptools-39.0.1/setuptools/_vendor/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/__about__.py b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/__about__.py
new file mode 100644
index 00000000..95d330ef
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/__about__.py
@@ -0,0 +1,21 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+__all__ = [
+    "__title__", "__summary__", "__uri__", "__version__", "__author__",
+    "__email__", "__license__", "__copyright__",
+]
+
+__title__ = "packaging"
+__summary__ = "Core utilities for Python packages"
+__uri__ = "https://github.com/pypa/packaging"
+
+__version__ = "16.8"
+
+__author__ = "Donald Stufft and individual contributors"
+__email__ = "donald@stufft.io"
+
+__license__ = "BSD or Apache License, Version 2.0"
+__copyright__ = "Copyright 2014-2016 %s" % __author__
diff --git a/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/__init__.py b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/__init__.py
new file mode 100644
index 00000000..5ee62202
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/__init__.py
@@ -0,0 +1,14 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+from .__about__ import (
+    __author__, __copyright__, __email__, __license__, __summary__, __title__,
+    __uri__, __version__
+)
+
+__all__ = [
+    "__title__", "__summary__", "__uri__", "__version__", "__author__",
+    "__email__", "__license__", "__copyright__",
+]
diff --git a/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/_compat.py b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/_compat.py
new file mode 100644
index 00000000..210bb80b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/_compat.py
@@ -0,0 +1,30 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import sys
+
+
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
+
+# flake8: noqa
+
+if PY3:
+    string_types = str,
+else:
+    string_types = basestring,
+
+
+def with_metaclass(meta, *bases):
+    """
+    Create a base class with a metaclass.
+    """
+    # This requires a bit of explanation: the basic idea is to make a dummy
+    # metaclass for one level of class instantiation that replaces itself with
+    # the actual metaclass.
+    class metaclass(meta):
+        def __new__(cls, name, this_bases, d):
+            return meta(name, bases, d)
+    return type.__new__(metaclass, 'temporary_class', (), {})
diff --git a/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/_structures.py b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/_structures.py
new file mode 100644
index 00000000..ccc27861
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/_structures.py
@@ -0,0 +1,68 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+
+class Infinity(object):
+
+    def __repr__(self):
+        return "Infinity"
+
+    def __hash__(self):
+        return hash(repr(self))
+
+    def __lt__(self, other):
+        return False
+
+    def __le__(self, other):
+        return False
+
+    def __eq__(self, other):
+        return isinstance(other, self.__class__)
+
+    def __ne__(self, other):
+        return not isinstance(other, self.__class__)
+
+    def __gt__(self, other):
+        return True
+
+    def __ge__(self, other):
+        return True
+
+    def __neg__(self):
+        return NegativeInfinity
+
+Infinity = Infinity()
+
+
+class NegativeInfinity(object):
+
+    def __repr__(self):
+        return "-Infinity"
+
+    def __hash__(self):
+        return hash(repr(self))
+
+    def __lt__(self, other):
+        return True
+
+    def __le__(self, other):
+        return True
+
+    def __eq__(self, other):
+        return isinstance(other, self.__class__)
+
+    def __ne__(self, other):
+        return not isinstance(other, self.__class__)
+
+    def __gt__(self, other):
+        return False
+
+    def __ge__(self, other):
+        return False
+
+    def __neg__(self):
+        return Infinity
+
+NegativeInfinity = NegativeInfinity()
diff --git a/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/markers.py b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/markers.py
new file mode 100644
index 00000000..031332a3
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/markers.py
@@ -0,0 +1,301 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import operator
+import os
+import platform
+import sys
+
+from setuptools.extern.pyparsing import ParseException, ParseResults, stringStart, stringEnd
+from setuptools.extern.pyparsing import ZeroOrMore, Group, Forward, QuotedString
+from setuptools.extern.pyparsing import Literal as L  # noqa
+
+from ._compat import string_types
+from .specifiers import Specifier, InvalidSpecifier
+
+
+__all__ = [
+    "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName",
+    "Marker", "default_environment",
+]
+
+
+class InvalidMarker(ValueError):
+    """
+    An invalid marker was found, users should refer to PEP 508.
+    """
+
+
+class UndefinedComparison(ValueError):
+    """
+    An invalid operation was attempted on a value that doesn't support it.
+    """
+
+
+class UndefinedEnvironmentName(ValueError):
+    """
+    A name was attempted to be used that does not exist inside of the
+    environment.
+    """
+
+
+class Node(object):
+
+    def __init__(self, value):
+        self.value = value
+
+    def __str__(self):
+        return str(self.value)
+
+    def __repr__(self):
+        return "<{0}({1!r})>".format(self.__class__.__name__, str(self))
+
+    def serialize(self):
+        raise NotImplementedError
+
+
+class Variable(Node):
+
+    def serialize(self):
+        return str(self)
+
+
+class Value(Node):
+
+    def serialize(self):
+        return '"{0}"'.format(self)
+
+
+class Op(Node):
+
+    def serialize(self):
+        return str(self)
+
+
+VARIABLE = (
+    L("implementation_version") |
+    L("platform_python_implementation") |
+    L("implementation_name") |
+    L("python_full_version") |
+    L("platform_release") |
+    L("platform_version") |
+    L("platform_machine") |
+    L("platform_system") |
+    L("python_version") |
+    L("sys_platform") |
+    L("os_name") |
+    L("os.name") |  # PEP-345
+    L("sys.platform") |  # PEP-345
+    L("platform.version") |  # PEP-345
+    L("platform.machine") |  # PEP-345
+    L("platform.python_implementation") |  # PEP-345
+    L("python_implementation") |  # undocumented setuptools legacy
+    L("extra")
+)
+ALIASES = {
+    'os.name': 'os_name',
+    'sys.platform': 'sys_platform',
+    'platform.version': 'platform_version',
+    'platform.machine': 'platform_machine',
+    'platform.python_implementation': 'platform_python_implementation',
+    'python_implementation': 'platform_python_implementation'
+}
+VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0])))
+
+VERSION_CMP = (
+    L("===") |
+    L("==") |
+    L(">=") |
+    L("<=") |
+    L("!=") |
+    L("~=") |
+    L(">") |
+    L("<")
+)
+
+MARKER_OP = VERSION_CMP | L("not in") | L("in")
+MARKER_OP.setParseAction(lambda s, l, t: Op(t[0]))
+
+MARKER_VALUE = QuotedString("'") | QuotedString('"')
+MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0]))
+
+BOOLOP = L("and") | L("or")
+
+MARKER_VAR = VARIABLE | MARKER_VALUE
+
+MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR)
+MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0]))
+
+LPAREN = L("(").suppress()
+RPAREN = L(")").suppress()
+
+MARKER_EXPR = Forward()
+MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN)
+MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR)
+
+MARKER = stringStart + MARKER_EXPR + stringEnd
+
+
+def _coerce_parse_result(results):
+    if isinstance(results, ParseResults):
+        return [_coerce_parse_result(i) for i in results]
+    else:
+        return results
+
+
+def _format_marker(marker, first=True):
+    assert isinstance(marker, (list, tuple, string_types))
+
+    # Sometimes we have a structure like [[...]] which is a single item list
+    # where the single item is itself it's own list. In that case we want skip
+    # the rest of this function so that we don't get extraneous () on the
+    # outside.
+    if (isinstance(marker, list) and len(marker) == 1 and
+            isinstance(marker[0], (list, tuple))):
+        return _format_marker(marker[0])
+
+    if isinstance(marker, list):
+        inner = (_format_marker(m, first=False) for m in marker)
+        if first:
+            return " ".join(inner)
+        else:
+            return "(" + " ".join(inner) + ")"
+    elif isinstance(marker, tuple):
+        return " ".join([m.serialize() for m in marker])
+    else:
+        return marker
+
+
+_operators = {
+    "in": lambda lhs, rhs: lhs in rhs,
+    "not in": lambda lhs, rhs: lhs not in rhs,
+    "<": operator.lt,
+    "<=": operator.le,
+    "==": operator.eq,
+    "!=": operator.ne,
+    ">=": operator.ge,
+    ">": operator.gt,
+}
+
+
+def _eval_op(lhs, op, rhs):
+    try:
+        spec = Specifier("".join([op.serialize(), rhs]))
+    except InvalidSpecifier:
+        pass
+    else:
+        return spec.contains(lhs)
+
+    oper = _operators.get(op.serialize())
+    if oper is None:
+        raise UndefinedComparison(
+            "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs)
+        )
+
+    return oper(lhs, rhs)
+
+
+_undefined = object()
+
+
+def _get_env(environment, name):
+    value = environment.get(name, _undefined)
+
+    if value is _undefined:
+        raise UndefinedEnvironmentName(
+            "{0!r} does not exist in evaluation environment.".format(name)
+        )
+
+    return value
+
+
+def _evaluate_markers(markers, environment):
+    groups = [[]]
+
+    for marker in markers:
+        assert isinstance(marker, (list, tuple, string_types))
+
+        if isinstance(marker, list):
+            groups[-1].append(_evaluate_markers(marker, environment))
+        elif isinstance(marker, tuple):
+            lhs, op, rhs = marker
+
+            if isinstance(lhs, Variable):
+                lhs_value = _get_env(environment, lhs.value)
+                rhs_value = rhs.value
+            else:
+                lhs_value = lhs.value
+                rhs_value = _get_env(environment, rhs.value)
+
+            groups[-1].append(_eval_op(lhs_value, op, rhs_value))
+        else:
+            assert marker in ["and", "or"]
+            if marker == "or":
+                groups.append([])
+
+    return any(all(item) for item in groups)
+
+
+def format_full_version(info):
+    version = '{0.major}.{0.minor}.{0.micro}'.format(info)
+    kind = info.releaselevel
+    if kind != 'final':
+        version += kind[0] + str(info.serial)
+    return version
+
+
+def default_environment():
+    if hasattr(sys, 'implementation'):
+        iver = format_full_version(sys.implementation.version)
+        implementation_name = sys.implementation.name
+    else:
+        iver = '0'
+        implementation_name = ''
+
+    return {
+        "implementation_name": implementation_name,
+        "implementation_version": iver,
+        "os_name": os.name,
+        "platform_machine": platform.machine(),
+        "platform_release": platform.release(),
+        "platform_system": platform.system(),
+        "platform_version": platform.version(),
+        "python_full_version": platform.python_version(),
+        "platform_python_implementation": platform.python_implementation(),
+        "python_version": platform.python_version()[:3],
+        "sys_platform": sys.platform,
+    }
+
+
+class Marker(object):
+
+    def __init__(self, marker):
+        try:
+            self._markers = _coerce_parse_result(MARKER.parseString(marker))
+        except ParseException as e:
+            err_str = "Invalid marker: {0!r}, parse error at {1!r}".format(
+                marker, marker[e.loc:e.loc + 8])
+            raise InvalidMarker(err_str)
+
+    def __str__(self):
+        return _format_marker(self._markers)
+
+    def __repr__(self):
+        return "<Marker({0!r})>".format(str(self))
+
+    def evaluate(self, environment=None):
+        """Evaluate a marker.
+
+        Return the boolean from evaluating the given marker against the
+        environment. environment is an optional argument to override all or
+        part of the determined environment.
+
+        The environment is determined from the current Python process.
+        """
+        current_environment = default_environment()
+        if environment is not None:
+            current_environment.update(environment)
+
+        return _evaluate_markers(self._markers, current_environment)
diff --git a/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/requirements.py b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/requirements.py
new file mode 100644
index 00000000..5b493416
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/requirements.py
@@ -0,0 +1,127 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import string
+import re
+
+from setuptools.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException
+from setuptools.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine
+from setuptools.extern.pyparsing import Literal as L  # noqa
+from setuptools.extern.six.moves.urllib import parse as urlparse
+
+from .markers import MARKER_EXPR, Marker
+from .specifiers import LegacySpecifier, Specifier, SpecifierSet
+
+
+class InvalidRequirement(ValueError):
+    """
+    An invalid requirement was found, users should refer to PEP 508.
+    """
+
+
+ALPHANUM = Word(string.ascii_letters + string.digits)
+
+LBRACKET = L("[").suppress()
+RBRACKET = L("]").suppress()
+LPAREN = L("(").suppress()
+RPAREN = L(")").suppress()
+COMMA = L(",").suppress()
+SEMICOLON = L(";").suppress()
+AT = L("@").suppress()
+
+PUNCTUATION = Word("-_.")
+IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM)
+IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END))
+
+NAME = IDENTIFIER("name")
+EXTRA = IDENTIFIER
+
+URI = Regex(r'[^ ]+')("url")
+URL = (AT + URI)
+
+EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA)
+EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras")
+
+VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE)
+VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE)
+
+VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY
+VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE),
+                       joinString=",", adjacent=False)("_raw_spec")
+_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY))
+_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '')
+
+VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier")
+VERSION_SPEC.setParseAction(lambda s, l, t: t[1])
+
+MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker")
+MARKER_EXPR.setParseAction(
+    lambda s, l, t: Marker(s[t._original_start:t._original_end])
+)
+MARKER_SEPERATOR = SEMICOLON
+MARKER = MARKER_SEPERATOR + MARKER_EXPR
+
+VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER)
+URL_AND_MARKER = URL + Optional(MARKER)
+
+NAMED_REQUIREMENT = \
+    NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER)
+
+REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd
+
+
+class Requirement(object):
+    """Parse a requirement.
+
+    Parse a given requirement string into its parts, such as name, specifier,
+    URL, and extras. Raises InvalidRequirement on a badly-formed requirement
+    string.
+    """
+
+    # TODO: Can we test whether something is contained within a requirement?
+    #       If so how do we do that? Do we need to test against the _name_ of
+    #       the thing as well as the version? What about the markers?
+    # TODO: Can we normalize the name and extra name?
+
+    def __init__(self, requirement_string):
+        try:
+            req = REQUIREMENT.parseString(requirement_string)
+        except ParseException as e:
+            raise InvalidRequirement(
+                "Invalid requirement, parse error at \"{0!r}\"".format(
+                    requirement_string[e.loc:e.loc + 8]))
+
+        self.name = req.name
+        if req.url:
+            parsed_url = urlparse.urlparse(req.url)
+            if not (parsed_url.scheme and parsed_url.netloc) or (
+                    not parsed_url.scheme and not parsed_url.netloc):
+                raise InvalidRequirement("Invalid URL given")
+            self.url = req.url
+        else:
+            self.url = None
+        self.extras = set(req.extras.asList() if req.extras else [])
+        self.specifier = SpecifierSet(req.specifier)
+        self.marker = req.marker if req.marker else None
+
+    def __str__(self):
+        parts = [self.name]
+
+        if self.extras:
+            parts.append("[{0}]".format(",".join(sorted(self.extras))))
+
+        if self.specifier:
+            parts.append(str(self.specifier))
+
+        if self.url:
+            parts.append("@ {0}".format(self.url))
+
+        if self.marker:
+            parts.append("; {0}".format(self.marker))
+
+        return "".join(parts)
+
+    def __repr__(self):
+        return "<Requirement({0!r})>".format(str(self))
diff --git a/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/specifiers.py b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/specifiers.py
new file mode 100644
index 00000000..7f5a76cf
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/specifiers.py
@@ -0,0 +1,774 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import abc
+import functools
+import itertools
+import re
+
+from ._compat import string_types, with_metaclass
+from .version import Version, LegacyVersion, parse
+
+
+class InvalidSpecifier(ValueError):
+    """
+    An invalid specifier was found, users should refer to PEP 440.
+    """
+
+
+class BaseSpecifier(with_metaclass(abc.ABCMeta, object)):
+
+    @abc.abstractmethod
+    def __str__(self):
+        """
+        Returns the str representation of this Specifier like object. This
+        should be representative of the Specifier itself.
+        """
+
+    @abc.abstractmethod
+    def __hash__(self):
+        """
+        Returns a hash value for this Specifier like object.
+        """
+
+    @abc.abstractmethod
+    def __eq__(self, other):
+        """
+        Returns a boolean representing whether or not the two Specifier like
+        objects are equal.
+        """
+
+    @abc.abstractmethod
+    def __ne__(self, other):
+        """
+        Returns a boolean representing whether or not the two Specifier like
+        objects are not equal.
+        """
+
+    @abc.abstractproperty
+    def prereleases(self):
+        """
+        Returns whether or not pre-releases as a whole are allowed by this
+        specifier.
+        """
+
+    @prereleases.setter
+    def prereleases(self, value):
+        """
+        Sets whether or not pre-releases as a whole are allowed by this
+        specifier.
+        """
+
+    @abc.abstractmethod
+    def contains(self, item, prereleases=None):
+        """
+        Determines if the given item is contained within this specifier.
+        """
+
+    @abc.abstractmethod
+    def filter(self, iterable, prereleases=None):
+        """
+        Takes an iterable of items and filters them so that only items which
+        are contained within this specifier are allowed in it.
+        """
+
+
+class _IndividualSpecifier(BaseSpecifier):
+
+    _operators = {}
+
+    def __init__(self, spec="", prereleases=None):
+        match = self._regex.search(spec)
+        if not match:
+            raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec))
+
+        self._spec = (
+            match.group("operator").strip(),
+            match.group("version").strip(),
+        )
+
+        # Store whether or not this Specifier should accept prereleases
+        self._prereleases = prereleases
+
+    def __repr__(self):
+        pre = (
+            ", prereleases={0!r}".format(self.prereleases)
+            if self._prereleases is not None
+            else ""
+        )
+
+        return "<{0}({1!r}{2})>".format(
+            self.__class__.__name__,
+            str(self),
+            pre,
+        )
+
+    def __str__(self):
+        return "{0}{1}".format(*self._spec)
+
+    def __hash__(self):
+        return hash(self._spec)
+
+    def __eq__(self, other):
+        if isinstance(other, string_types):
+            try:
+                other = self.__class__(other)
+            except InvalidSpecifier:
+                return NotImplemented
+        elif not isinstance(other, self.__class__):
+            return NotImplemented
+
+        return self._spec == other._spec
+
+    def __ne__(self, other):
+        if isinstance(other, string_types):
+            try:
+                other = self.__class__(other)
+            except InvalidSpecifier:
+                return NotImplemented
+        elif not isinstance(other, self.__class__):
+            return NotImplemented
+
+        return self._spec != other._spec
+
+    def _get_operator(self, op):
+        return getattr(self, "_compare_{0}".format(self._operators[op]))
+
+    def _coerce_version(self, version):
+        if not isinstance(version, (LegacyVersion, Version)):
+            version = parse(version)
+        return version
+
+    @property
+    def operator(self):
+        return self._spec[0]
+
+    @property
+    def version(self):
+        return self._spec[1]
+
+    @property
+    def prereleases(self):
+        return self._prereleases
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+    def __contains__(self, item):
+        return self.contains(item)
+
+    def contains(self, item, prereleases=None):
+        # Determine if prereleases are to be allowed or not.
+        if prereleases is None:
+            prereleases = self.prereleases
+
+        # Normalize item to a Version or LegacyVersion, this allows us to have
+        # a shortcut for ``"2.0" in Specifier(">=2")
+        item = self._coerce_version(item)
+
+        # Determine if we should be supporting prereleases in this specifier
+        # or not, if we do not support prereleases than we can short circuit
+        # logic if this version is a prereleases.
+        if item.is_prerelease and not prereleases:
+            return False
+
+        # Actually do the comparison to determine if this item is contained
+        # within this Specifier or not.
+        return self._get_operator(self.operator)(item, self.version)
+
+    def filter(self, iterable, prereleases=None):
+        yielded = False
+        found_prereleases = []
+
+        kw = {"prereleases": prereleases if prereleases is not None else True}
+
+        # Attempt to iterate over all the values in the iterable and if any of
+        # them match, yield them.
+        for version in iterable:
+            parsed_version = self._coerce_version(version)
+
+            if self.contains(parsed_version, **kw):
+                # If our version is a prerelease, and we were not set to allow
+                # prereleases, then we'll store it for later incase nothing
+                # else matches this specifier.
+                if (parsed_version.is_prerelease and not
+                        (prereleases or self.prereleases)):
+                    found_prereleases.append(version)
+                # Either this is not a prerelease, or we should have been
+                # accepting prereleases from the begining.
+                else:
+                    yielded = True
+                    yield version
+
+        # Now that we've iterated over everything, determine if we've yielded
+        # any values, and if we have not and we have any prereleases stored up
+        # then we will go ahead and yield the prereleases.
+        if not yielded and found_prereleases:
+            for version in found_prereleases:
+                yield version
+
+
+class LegacySpecifier(_IndividualSpecifier):
+
+    _regex_str = (
+        r"""
+        (?P<operator>(==|!=|<=|>=|<|>))
+        \s*
+        (?P<version>
+            [^,;\s)]* # Since this is a "legacy" specifier, and the version
+                      # string can be just about anything, we match everything
+                      # except for whitespace, a semi-colon for marker support,
+                      # a closing paren since versions can be enclosed in
+                      # them, and a comma since it's a version separator.
+        )
+        """
+    )
+
+    _regex = re.compile(
+        r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
+
+    _operators = {
+        "==": "equal",
+        "!=": "not_equal",
+        "<=": "less_than_equal",
+        ">=": "greater_than_equal",
+        "<": "less_than",
+        ">": "greater_than",
+    }
+
+    def _coerce_version(self, version):
+        if not isinstance(version, LegacyVersion):
+            version = LegacyVersion(str(version))
+        return version
+
+    def _compare_equal(self, prospective, spec):
+        return prospective == self._coerce_version(spec)
+
+    def _compare_not_equal(self, prospective, spec):
+        return prospective != self._coerce_version(spec)
+
+    def _compare_less_than_equal(self, prospective, spec):
+        return prospective <= self._coerce_version(spec)
+
+    def _compare_greater_than_equal(self, prospective, spec):
+        return prospective >= self._coerce_version(spec)
+
+    def _compare_less_than(self, prospective, spec):
+        return prospective < self._coerce_version(spec)
+
+    def _compare_greater_than(self, prospective, spec):
+        return prospective > self._coerce_version(spec)
+
+
+def _require_version_compare(fn):
+    @functools.wraps(fn)
+    def wrapped(self, prospective, spec):
+        if not isinstance(prospective, Version):
+            return False
+        return fn(self, prospective, spec)
+    return wrapped
+
+
+class Specifier(_IndividualSpecifier):
+
+    _regex_str = (
+        r"""
+        (?P<operator>(~=|==|!=|<=|>=|<|>|===))
+        (?P<version>
+            (?:
+                # The identity operators allow for an escape hatch that will
+                # do an exact string match of the version you wish to install.
+                # This will not be parsed by PEP 440 and we cannot determine
+                # any semantic meaning from it. This operator is discouraged
+                # but included entirely as an escape hatch.
+                (?<====)  # Only match for the identity operator
+                \s*
+                [^\s]*    # We just match everything, except for whitespace
+                          # since we are only testing for strict identity.
+            )
+            |
+            (?:
+                # The (non)equality operators allow for wild card and local
+                # versions to be specified so we have to define these two
+                # operators separately to enable that.
+                (?<===|!=)            # Only match for equals and not equals
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)*   # release
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+
+                # You cannot use a wild card and a dev or local version
+                # together so group them with a | and make them optional.
+                (?:
+                    (?:[-_\.]?dev[-_\.]?[0-9]*)?         # dev release
+                    (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local
+                    |
+                    \.\*  # Wild card syntax of .*
+                )?
+            )
+            |
+            (?:
+                # The compatible operator requires at least two digits in the
+                # release segment.
+                (?<=~=)               # Only match for the compatible operator
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)+   # release  (We have a + instead of a *)
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
+            )
+            |
+            (?:
+                # All other operators only allow a sub set of what the
+                # (non)equality operators do. Specifically they do not allow
+                # local versions to be specified nor do they allow the prefix
+                # matching wild cards.
+                (?<!==|!=|~=)         # We have special cases for these
+                                      # operators so we want to make sure they
+                                      # don't match here.
+
+                \s*
+                v?
+                (?:[0-9]+!)?          # epoch
+                [0-9]+(?:\.[0-9]+)*   # release
+                (?:                   # pre release
+                    [-_\.]?
+                    (a|b|c|rc|alpha|beta|pre|preview)
+                    [-_\.]?
+                    [0-9]*
+                )?
+                (?:                                   # post release
+                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
+                )?
+                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
+            )
+        )
+        """
+    )
+
+    _regex = re.compile(
+        r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
+
+    _operators = {
+        "~=": "compatible",
+        "==": "equal",
+        "!=": "not_equal",
+        "<=": "less_than_equal",
+        ">=": "greater_than_equal",
+        "<": "less_than",
+        ">": "greater_than",
+        "===": "arbitrary",
+    }
+
+    @_require_version_compare
+    def _compare_compatible(self, prospective, spec):
+        # Compatible releases have an equivalent combination of >= and ==. That
+        # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to
+        # implement this in terms of the other specifiers instead of
+        # implementing it ourselves. The only thing we need to do is construct
+        # the other specifiers.
+
+        # We want everything but the last item in the version, but we want to
+        # ignore post and dev releases and we want to treat the pre-release as
+        # it's own separate segment.
+        prefix = ".".join(
+            list(
+                itertools.takewhile(
+                    lambda x: (not x.startswith("post") and not
+                               x.startswith("dev")),
+                    _version_split(spec),
+                )
+            )[:-1]
+        )
+
+        # Add the prefix notation to the end of our string
+        prefix += ".*"
+
+        return (self._get_operator(">=")(prospective, spec) and
+                self._get_operator("==")(prospective, prefix))
+
+    @_require_version_compare
+    def _compare_equal(self, prospective, spec):
+        # We need special logic to handle prefix matching
+        if spec.endswith(".*"):
+            # In the case of prefix matching we want to ignore local segment.
+            prospective = Version(prospective.public)
+            # Split the spec out by dots, and pretend that there is an implicit
+            # dot in between a release segment and a pre-release segment.
+            spec = _version_split(spec[:-2])  # Remove the trailing .*
+
+            # Split the prospective version out by dots, and pretend that there
+            # is an implicit dot in between a release segment and a pre-release
+            # segment.
+            prospective = _version_split(str(prospective))
+
+            # Shorten the prospective version to be the same length as the spec
+            # so that we can determine if the specifier is a prefix of the
+            # prospective version or not.
+            prospective = prospective[:len(spec)]
+
+            # Pad out our two sides with zeros so that they both equal the same
+            # length.
+            spec, prospective = _pad_version(spec, prospective)
+        else:
+            # Convert our spec string into a Version
+            spec = Version(spec)
+
+            # If the specifier does not have a local segment, then we want to
+            # act as if the prospective version also does not have a local
+            # segment.
+            if not spec.local:
+                prospective = Version(prospective.public)
+
+        return prospective == spec
+
+    @_require_version_compare
+    def _compare_not_equal(self, prospective, spec):
+        return not self._compare_equal(prospective, spec)
+
+    @_require_version_compare
+    def _compare_less_than_equal(self, prospective, spec):
+        return prospective <= Version(spec)
+
+    @_require_version_compare
+    def _compare_greater_than_equal(self, prospective, spec):
+        return prospective >= Version(spec)
+
+    @_require_version_compare
+    def _compare_less_than(self, prospective, spec):
+        # Convert our spec to a Version instance, since we'll want to work with
+        # it as a version.
+        spec = Version(spec)
+
+        # Check to see if the prospective version is less than the spec
+        # version. If it's not we can short circuit and just return False now
+        # instead of doing extra unneeded work.
+        if not prospective < spec:
+            return False
+
+        # This special case is here so that, unless the specifier itself
+        # includes is a pre-release version, that we do not accept pre-release
+        # versions for the version mentioned in the specifier (e.g. <3.1 should
+        # not match 3.1.dev0, but should match 3.0.dev0).
+        if not spec.is_prerelease and prospective.is_prerelease:
+            if Version(prospective.base_version) == Version(spec.base_version):
+                return False
+
+        # If we've gotten to here, it means that prospective version is both
+        # less than the spec version *and* it's not a pre-release of the same
+        # version in the spec.
+        return True
+
+    @_require_version_compare
+    def _compare_greater_than(self, prospective, spec):
+        # Convert our spec to a Version instance, since we'll want to work with
+        # it as a version.
+        spec = Version(spec)
+
+        # Check to see if the prospective version is greater than the spec
+        # version. If it's not we can short circuit and just return False now
+        # instead of doing extra unneeded work.
+        if not prospective > spec:
+            return False
+
+        # This special case is here so that, unless the specifier itself
+        # includes is a post-release version, that we do not accept
+        # post-release versions for the version mentioned in the specifier
+        # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0).
+        if not spec.is_postrelease and prospective.is_postrelease:
+            if Version(prospective.base_version) == Version(spec.base_version):
+                return False
+
+        # Ensure that we do not allow a local version of the version mentioned
+        # in the specifier, which is techincally greater than, to match.
+        if prospective.local is not None:
+            if Version(prospective.base_version) == Version(spec.base_version):
+                return False
+
+        # If we've gotten to here, it means that prospective version is both
+        # greater than the spec version *and* it's not a pre-release of the
+        # same version in the spec.
+        return True
+
+    def _compare_arbitrary(self, prospective, spec):
+        return str(prospective).lower() == str(spec).lower()
+
+    @property
+    def prereleases(self):
+        # If there is an explicit prereleases set for this, then we'll just
+        # blindly use that.
+        if self._prereleases is not None:
+            return self._prereleases
+
+        # Look at all of our specifiers and determine if they are inclusive
+        # operators, and if they are if they are including an explicit
+        # prerelease.
+        operator, version = self._spec
+        if operator in ["==", ">=", "<=", "~=", "==="]:
+            # The == specifier can include a trailing .*, if it does we
+            # want to remove before parsing.
+            if operator == "==" and version.endswith(".*"):
+                version = version[:-2]
+
+            # Parse the version, and if it is a pre-release than this
+            # specifier allows pre-releases.
+            if parse(version).is_prerelease:
+                return True
+
+        return False
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+
+_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$")
+
+
+def _version_split(version):
+    result = []
+    for item in version.split("."):
+        match = _prefix_regex.search(item)
+        if match:
+            result.extend(match.groups())
+        else:
+            result.append(item)
+    return result
+
+
+def _pad_version(left, right):
+    left_split, right_split = [], []
+
+    # Get the release segment of our versions
+    left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left)))
+    right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right)))
+
+    # Get the rest of our versions
+    left_split.append(left[len(left_split[0]):])
+    right_split.append(right[len(right_split[0]):])
+
+    # Insert our padding
+    left_split.insert(
+        1,
+        ["0"] * max(0, len(right_split[0]) - len(left_split[0])),
+    )
+    right_split.insert(
+        1,
+        ["0"] * max(0, len(left_split[0]) - len(right_split[0])),
+    )
+
+    return (
+        list(itertools.chain(*left_split)),
+        list(itertools.chain(*right_split)),
+    )
+
+
+class SpecifierSet(BaseSpecifier):
+
+    def __init__(self, specifiers="", prereleases=None):
+        # Split on , to break each indidivual specifier into it's own item, and
+        # strip each item to remove leading/trailing whitespace.
+        specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
+
+        # Parsed each individual specifier, attempting first to make it a
+        # Specifier and falling back to a LegacySpecifier.
+        parsed = set()
+        for specifier in specifiers:
+            try:
+                parsed.add(Specifier(specifier))
+            except InvalidSpecifier:
+                parsed.add(LegacySpecifier(specifier))
+
+        # Turn our parsed specifiers into a frozen set and save them for later.
+        self._specs = frozenset(parsed)
+
+        # Store our prereleases value so we can use it later to determine if
+        # we accept prereleases or not.
+        self._prereleases = prereleases
+
+    def __repr__(self):
+        pre = (
+            ", prereleases={0!r}".format(self.prereleases)
+            if self._prereleases is not None
+            else ""
+        )
+
+        return "<SpecifierSet({0!r}{1})>".format(str(self), pre)
+
+    def __str__(self):
+        return ",".join(sorted(str(s) for s in self._specs))
+
+    def __hash__(self):
+        return hash(self._specs)
+
+    def __and__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        specifier = SpecifierSet()
+        specifier._specs = frozenset(self._specs | other._specs)
+
+        if self._prereleases is None and other._prereleases is not None:
+            specifier._prereleases = other._prereleases
+        elif self._prereleases is not None and other._prereleases is None:
+            specifier._prereleases = self._prereleases
+        elif self._prereleases == other._prereleases:
+            specifier._prereleases = self._prereleases
+        else:
+            raise ValueError(
+                "Cannot combine SpecifierSets with True and False prerelease "
+                "overrides."
+            )
+
+        return specifier
+
+    def __eq__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif isinstance(other, _IndividualSpecifier):
+            other = SpecifierSet(str(other))
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        return self._specs == other._specs
+
+    def __ne__(self, other):
+        if isinstance(other, string_types):
+            other = SpecifierSet(other)
+        elif isinstance(other, _IndividualSpecifier):
+            other = SpecifierSet(str(other))
+        elif not isinstance(other, SpecifierSet):
+            return NotImplemented
+
+        return self._specs != other._specs
+
+    def __len__(self):
+        return len(self._specs)
+
+    def __iter__(self):
+        return iter(self._specs)
+
+    @property
+    def prereleases(self):
+        # If we have been given an explicit prerelease modifier, then we'll
+        # pass that through here.
+        if self._prereleases is not None:
+            return self._prereleases
+
+        # If we don't have any specifiers, and we don't have a forced value,
+        # then we'll just return None since we don't know if this should have
+        # pre-releases or not.
+        if not self._specs:
+            return None
+
+        # Otherwise we'll see if any of the given specifiers accept
+        # prereleases, if any of them do we'll return True, otherwise False.
+        return any(s.prereleases for s in self._specs)
+
+    @prereleases.setter
+    def prereleases(self, value):
+        self._prereleases = value
+
+    def __contains__(self, item):
+        return self.contains(item)
+
+    def contains(self, item, prereleases=None):
+        # Ensure that our item is a Version or LegacyVersion instance.
+        if not isinstance(item, (LegacyVersion, Version)):
+            item = parse(item)
+
+        # Determine if we're forcing a prerelease or not, if we're not forcing
+        # one for this particular filter call, then we'll use whatever the
+        # SpecifierSet thinks for whether or not we should support prereleases.
+        if prereleases is None:
+            prereleases = self.prereleases
+
+        # We can determine if we're going to allow pre-releases by looking to
+        # see if any of the underlying items supports them. If none of them do
+        # and this item is a pre-release then we do not allow it and we can
+        # short circuit that here.
+        # Note: This means that 1.0.dev1 would not be contained in something
+        #       like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0
+        if not prereleases and item.is_prerelease:
+            return False
+
+        # We simply dispatch to the underlying specs here to make sure that the
+        # given version is contained within all of them.
+        # Note: This use of all() here means that an empty set of specifiers
+        #       will always return True, this is an explicit design decision.
+        return all(
+            s.contains(item, prereleases=prereleases)
+            for s in self._specs
+        )
+
+    def filter(self, iterable, prereleases=None):
+        # Determine if we're forcing a prerelease or not, if we're not forcing
+        # one for this particular filter call, then we'll use whatever the
+        # SpecifierSet thinks for whether or not we should support prereleases.
+        if prereleases is None:
+            prereleases = self.prereleases
+
+        # If we have any specifiers, then we want to wrap our iterable in the
+        # filter method for each one, this will act as a logical AND amongst
+        # each specifier.
+        if self._specs:
+            for spec in self._specs:
+                iterable = spec.filter(iterable, prereleases=bool(prereleases))
+            return iterable
+        # If we do not have any specifiers, then we need to have a rough filter
+        # which will filter out any pre-releases, unless there are no final
+        # releases, and which will filter out LegacyVersion in general.
+        else:
+            filtered = []
+            found_prereleases = []
+
+            for item in iterable:
+                # Ensure that we some kind of Version class for this item.
+                if not isinstance(item, (LegacyVersion, Version)):
+                    parsed_version = parse(item)
+                else:
+                    parsed_version = item
+
+                # Filter out any item which is parsed as a LegacyVersion
+                if isinstance(parsed_version, LegacyVersion):
+                    continue
+
+                # Store any item which is a pre-release for later unless we've
+                # already found a final version or we are accepting prereleases
+                if parsed_version.is_prerelease and not prereleases:
+                    if not filtered:
+                        found_prereleases.append(item)
+                else:
+                    filtered.append(item)
+
+            # If we've found no items except for pre-releases, then we'll go
+            # ahead and use the pre-releases
+            if not filtered and found_prereleases and prereleases is None:
+                return found_prereleases
+
+            return filtered
diff --git a/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/utils.py b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/utils.py
new file mode 100644
index 00000000..942387ce
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/utils.py
@@ -0,0 +1,14 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import re
+
+
+_canonicalize_regex = re.compile(r"[-_.]+")
+
+
+def canonicalize_name(name):
+    # This is taken from PEP 503.
+    return _canonicalize_regex.sub("-", name).lower()
diff --git a/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/version.py b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/version.py
new file mode 100644
index 00000000..83b5ee8c
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/_vendor/packaging/version.py
@@ -0,0 +1,393 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+from __future__ import absolute_import, division, print_function
+
+import collections
+import itertools
+import re
+
+from ._structures import Infinity
+
+
+__all__ = [
+    "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"
+]
+
+
+_Version = collections.namedtuple(
+    "_Version",
+    ["epoch", "release", "dev", "pre", "post", "local"],
+)
+
+
+def parse(version):
+    """
+    Parse the given version string and return either a :class:`Version` object
+    or a :class:`LegacyVersion` object depending on if the given version is
+    a valid PEP 440 version or a legacy version.
+    """
+    try:
+        return Version(version)
+    except InvalidVersion:
+        return LegacyVersion(version)
+
+
+class InvalidVersion(ValueError):
+    """
+    An invalid version was found, users should refer to PEP 440.
+    """
+
+
+class _BaseVersion(object):
+
+    def __hash__(self):
+        return hash(self._key)
+
+    def __lt__(self, other):
+        return self._compare(other, lambda s, o: s < o)
+
+    def __le__(self, other):
+        return self._compare(other, lambda s, o: s <= o)
+
+    def __eq__(self, other):
+        return self._compare(other, lambda s, o: s == o)
+
+    def __ge__(self, other):
+        return self._compare(other, lambda s, o: s >= o)
+
+    def __gt__(self, other):
+        return self._compare(other, lambda s, o: s > o)
+
+    def __ne__(self, other):
+        return self._compare(other, lambda s, o: s != o)
+
+    def _compare(self, other, method):
+        if not isinstance(other, _BaseVersion):
+            return NotImplemented
+
+        return method(self._key, other._key)
+
+
+class LegacyVersion(_BaseVersion):
+
+    def __init__(self, version):
+        self._version = str(version)
+        self._key = _legacy_cmpkey(self._version)
+
+    def __str__(self):
+        return self._version
+
+    def __repr__(self):
+        return "<LegacyVersion({0})>".format(repr(str(self)))
+
+    @property
+    def public(self):
+        return self._version
+
+    @property
+    def base_version(self):
+        return self._version
+
+    @property
+    def local(self):
+        return None
+
+    @property
+    def is_prerelease(self):
+        return False
+
+    @property
+    def is_postrelease(self):
+        return False
+
+
+_legacy_version_component_re = re.compile(
+    r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE,
+)
+
+_legacy_version_replacement_map = {
+    "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@",
+}
+
+
+def _parse_version_parts(s):
+    for part in _legacy_version_component_re.split(s):
+        part = _legacy_version_replacement_map.get(part, part)
+
+        if not part or part == ".":
+            continue
+
+        if part[:1] in "0123456789":
+            # pad for numeric comparison
+            yield part.zfill(8)
+        else:
+            yield "*" + part
+
+    # ensure that alpha/beta/candidate are before final
+    yield "*final"
+
+
+def _legacy_cmpkey(version):
+    # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch
+    # greater than or equal to 0. This will effectively put the LegacyVersion,
+    # which uses the defacto standard originally implemented by setuptools,
+    # as before all PEP 440 versions.
+    epoch = -1
+
+    # This scheme is taken from pkg_resources.parse_version setuptools prior to
+    # it's adoption of the packaging library.
+    parts = []
+    for part in _parse_version_parts(version.lower()):
+        if part.startswith("*"):
+            # remove "-" before a prerelease tag
+            if part < "*final":
+                while parts and parts[-1] == "*final-":
+                    parts.pop()
+
+            # remove trailing zeros from each series of numeric parts
+            while parts and parts[-1] == "00000000":
+                parts.pop()
+
+        parts.append(part)
+    parts = tuple(parts)
+
+    return epoch, parts
+
+# Deliberately not anchored to the start and end of the string, to make it
+# easier for 3rd party code to reuse
+VERSION_PATTERN = r"""
+    v?
+    (?:
+        (?:(?P<epoch>[0-9]+)!)?                           # epoch
+        (?P<release>[0-9]+(?:\.[0-9]+)*)                  # release segment
+        (?P<pre>                                          # pre-release
+            [-_\.]?
+            (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview))
+            [-_\.]?
+            (?P<pre_n>[0-9]+)?
+        )?
+        (?P<post>                                         # post release
+            (?:-(?P<post_n1>[0-9]+))
+            |
+            (?:
+                [-_\.]?
+                (?P<post_l>post|rev|r)
+                [-_\.]?
+                (?P<post_n2>[0-9]+)?
+            )
+        )?
+        (?P<dev>                                          # dev release
+            [-_\.]?
+            (?P<dev_l>dev)
+            [-_\.]?
+            (?P<dev_n>[0-9]+)?
+        )?
+    )
+    (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))?       # local version
+"""
+
+
+class Version(_BaseVersion):
+
+    _regex = re.compile(
+        r"^\s*" + VERSION_PATTERN + r"\s*$",
+        re.VERBOSE | re.IGNORECASE,
+    )
+
+    def __init__(self, version):
+        # Validate the version and parse it into pieces
+        match = self._regex.search(version)
+        if not match:
+            raise InvalidVersion("Invalid version: '{0}'".format(version))
+
+        # Store the parsed out pieces of the version
+        self._version = _Version(
+            epoch=int(match.group("epoch")) if match.group("epoch") else 0,
+            release=tuple(int(i) for i in match.group("release").split(".")),
+            pre=_parse_letter_version(
+                match.group("pre_l"),
+                match.group("pre_n"),
+            ),
+            post=_parse_letter_version(
+                match.group("post_l"),
+                match.group("post_n1") or match.group("post_n2"),
+            ),
+            dev=_parse_letter_version(
+                match.group("dev_l"),
+                match.group("dev_n"),
+            ),
+            local=_parse_local_version(match.group("local")),
+        )
+
+        # Generate a key which will be used for sorting
+        self._key = _cmpkey(
+            self._version.epoch,
+            self._version.release,
+            self._version.pre,
+            self._version.post,
+            self._version.dev,
+            self._version.local,
+        )
+
+    def __repr__(self):
+        return "<Version({0})>".format(repr(str(self)))
+
+    def __str__(self):
+        parts = []
+
+        # Epoch
+        if self._version.epoch != 0:
+            parts.append("{0}!".format(self._version.epoch))
+
+        # Release segment
+        parts.append(".".join(str(x) for x in self._version.release))
+
+        # Pre-release
+        if self._version.pre is not None:
+            parts.append("".join(str(x) for x in self._version.pre))
+
+        # Post-release
+        if self._version.post is not None:
+            parts.append(".post{0}".format(self._version.post[1]))
+
+        # Development release
+        if self._version.dev is not None:
+            parts.append(".dev{0}".format(self._version.dev[1]))
+
+        # Local version segment
+        if self._version.local is not None:
+            parts.append(
+                "+{0}".format(".".join(str(x) for x in self._version.local))
+            )
+
+        return "".join(parts)
+
+    @property
+    def public(self):
+        return str(self).split("+", 1)[0]
+
+    @property
+    def base_version(self):
+        parts = []
+
+        # Epoch
+        if self._version.epoch != 0:
+            parts.append("{0}!".format(self._version.epoch))
+
+        # Release segment
+        parts.append(".".join(str(x) for x in self._version.release))
+
+        return "".join(parts)
+
+    @property
+    def local(self):
+        version_string = str(self)
+        if "+" in version_string:
+            return version_string.split("+", 1)[1]
+
+    @property
+    def is_prerelease(self):
+        return bool(self._version.dev or self._version.pre)
+
+    @property
+    def is_postrelease(self):
+        return bool(self._version.post)
+
+
+def _parse_letter_version(letter, number):
+    if letter:
+        # We consider there to be an implicit 0 in a pre-release if there is
+        # not a numeral associated with it.
+        if number is None:
+            number = 0
+
+        # We normalize any letters to their lower case form
+        letter = letter.lower()
+
+        # We consider some words to be alternate spellings of other words and
+        # in those cases we want to normalize the spellings to our preferred
+        # spelling.
+        if letter == "alpha":
+            letter = "a"
+        elif letter == "beta":
+            letter = "b"
+        elif letter in ["c", "pre", "preview"]:
+            letter = "rc"
+        elif letter in ["rev", "r"]:
+            letter = "post"
+
+        return letter, int(number)
+    if not letter and number:
+        # We assume if we are given a number, but we are not given a letter
+        # then this is using the implicit post release syntax (e.g. 1.0-1)
+        letter = "post"
+
+        return letter, int(number)
+
+
+_local_version_seperators = re.compile(r"[\._-]")
+
+
+def _parse_local_version(local):
+    """
+    Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve").
+    """
+    if local is not None:
+        return tuple(
+            part.lower() if not part.isdigit() else int(part)
+            for part in _local_version_seperators.split(local)
+        )
+
+
+def _cmpkey(epoch, release, pre, post, dev, local):
+    # When we compare a release version, we want to compare it with all of the
+    # trailing zeros removed. So we'll use a reverse the list, drop all the now
+    # leading zeros until we come to something non zero, then take the rest
+    # re-reverse it back into the correct order and make it a tuple and use
+    # that for our sorting key.
+    release = tuple(
+        reversed(list(
+            itertools.dropwhile(
+                lambda x: x == 0,
+                reversed(release),
+            )
+        ))
+    )
+
+    # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
+    # We'll do this by abusing the pre segment, but we _only_ want to do this
+    # if there is not a pre or a post segment. If we have one of those then
+    # the normal sorting rules will handle this case correctly.
+    if pre is None and post is None and dev is not None:
+        pre = -Infinity
+    # Versions without a pre-release (except as noted above) should sort after
+    # those with one.
+    elif pre is None:
+        pre = Infinity
+
+    # Versions without a post segment should sort before those with one.
+    if post is None:
+        post = -Infinity
+
+    # Versions without a development segment should sort after those with one.
+    if dev is None:
+        dev = Infinity
+
+    if local is None:
+        # Versions without a local segment should sort before those with one.
+        local = -Infinity
+    else:
+        # Versions with a local segment need that segment parsed to implement
+        # the sorting rules in PEP440.
+        # - Alpha numeric segments sort before numeric segments
+        # - Alpha numeric segments sort lexicographically
+        # - Numeric segments sort numerically
+        # - Shorter versions sort before longer versions when the prefixes
+        #   match exactly
+        local = tuple(
+            (i, "") if isinstance(i, int) else (-Infinity, i)
+            for i in local
+        )
+
+    return epoch, release, pre, post, dev, local
diff --git a/vendor/setuptools-39.0.1/setuptools/_vendor/pyparsing.py b/vendor/setuptools-39.0.1/setuptools/_vendor/pyparsing.py
new file mode 100644
index 00000000..a2122435
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/_vendor/pyparsing.py
@@ -0,0 +1,5696 @@
+# module pyparsing.py
+#
+# Copyright (c) 2003-2016  Paul T. McGuire
+#
+# 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.
+#
+
+__doc__ = \
+"""
+pyparsing module - Classes and methods to define and execute parsing grammars
+
+The pyparsing module is an alternative approach to creating and executing simple grammars,
+vs. the traditional lex/yacc approach, or the use of regular expressions.  With pyparsing, you
+don't need to learn a new syntax for defining grammars or matching expressions - the parsing module
+provides a library of classes that you use to construct the grammar directly in Python.
+
+Here is a program to parse "Hello, World!" (or any greeting of the form 
+C{"<salutation>, <addressee>!"}), built up using L{Word}, L{Literal}, and L{And} elements 
+(L{'+'<ParserElement.__add__>} operator gives L{And} expressions, strings are auto-converted to
+L{Literal} expressions)::
+
+    from pyparsing import Word, alphas
+
+    # define grammar of a greeting
+    greet = Word(alphas) + "," + Word(alphas) + "!"
+
+    hello = "Hello, World!"
+    print (hello, "->", greet.parseString(hello))
+
+The program outputs the following::
+
+    Hello, World! -> ['Hello', ',', 'World', '!']
+
+The Python representation of the grammar is quite readable, owing to the self-explanatory
+class names, and the use of '+', '|' and '^' operators.
+
+The L{ParseResults} object returned from L{ParserElement.parseString<ParserElement.parseString>} can be accessed as a nested list, a dictionary, or an
+object with named attributes.
+
+The pyparsing module handles some of the problems that are typically vexing when writing text parsers:
+ - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello  ,  World  !", etc.)
+ - quoted strings
+ - embedded comments
+"""
+
+__version__ = "2.1.10"
+__versionTime__ = "07 Oct 2016 01:31 UTC"
+__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
+
+import string
+from weakref import ref as wkref
+import copy
+import sys
+import warnings
+import re
+import sre_constants
+import collections
+import pprint
+import traceback
+import types
+from datetime import datetime
+
+try:
+    from _thread import RLock
+except ImportError:
+    from threading import RLock
+
+try:
+    from collections import OrderedDict as _OrderedDict
+except ImportError:
+    try:
+        from ordereddict import OrderedDict as _OrderedDict
+    except ImportError:
+        _OrderedDict = None
+
+#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) )
+
+__all__ = [
+'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty',
+'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal',
+'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or',
+'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException',
+'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException',
+'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', 
+'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore',
+'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col',
+'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString',
+'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums',
+'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno',
+'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral',
+'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables',
+'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', 
+'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd',
+'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute',
+'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass',
+'CloseMatch', 'tokenMap', 'pyparsing_common',
+]
+
+system_version = tuple(sys.version_info)[:3]
+PY_3 = system_version[0] == 3
+if PY_3:
+    _MAX_INT = sys.maxsize
+    basestring = str
+    unichr = chr
+    _ustr = str
+
+    # build list of single arg builtins, that can be used as parse actions
+    singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max]
+
+else:
+    _MAX_INT = sys.maxint
+    range = xrange
+
+    def _ustr(obj):
+        """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries
+           str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It
+           then < returns the unicode object | encodes it with the default encoding | ... >.
+        """
+        if isinstance(obj,unicode):
+            return obj
+
+        try:
+            # If this works, then _ustr(obj) has the same behaviour as str(obj), so
+            # it won't break any existing code.
+            return str(obj)
+
+        except UnicodeEncodeError:
+            # Else encode it
+            ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace')
+            xmlcharref = Regex('&#\d+;')
+            xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:])
+            return xmlcharref.transformString(ret)
+
+    # build list of single arg builtins, tolerant of Python version, that can be used as parse actions
+    singleArgBuiltins = []
+    import __builtin__
+    for fname in "sum len sorted reversed list tuple set any all min max".split():
+        try:
+            singleArgBuiltins.append(getattr(__builtin__,fname))
+        except AttributeError:
+            continue
+            
+_generatorType = type((y for y in range(1)))
+ 
+def _xml_escape(data):
+    """Escape &, <, >, ", ', etc. in a string of data."""
+
+    # ampersand must be replaced first
+    from_symbols = '&><"\''
+    to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split())
+    for from_,to_ in zip(from_symbols, to_symbols):
+        data = data.replace(from_, to_)
+    return data
+
+class _Constants(object):
+    pass
+
+alphas     = string.ascii_uppercase + string.ascii_lowercase
+nums       = "0123456789"
+hexnums    = nums + "ABCDEFabcdef"
+alphanums  = alphas + nums
+_bslash    = chr(92)
+printables = "".join(c for c in string.printable if c not in string.whitespace)
+
+class ParseBaseException(Exception):
+    """base exception class for all parsing runtime exceptions"""
+    # Performance tuning: we construct a *lot* of these, so keep this
+    # constructor as small and fast as possible
+    def __init__( self, pstr, loc=0, msg=None, elem=None ):
+        self.loc = loc
+        if msg is None:
+            self.msg = pstr
+            self.pstr = ""
+        else:
+            self.msg = msg
+            self.pstr = pstr
+        self.parserElement = elem
+        self.args = (pstr, loc, msg)
+
+    @classmethod
+    def _from_exception(cls, pe):
+        """
+        internal factory method to simplify creating one type of ParseException 
+        from another - avoids having __init__ signature conflicts among subclasses
+        """
+        return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement)
+
+    def __getattr__( self, aname ):
+        """supported attributes by name are:
+            - lineno - returns the line number of the exception text
+            - col - returns the column number of the exception text
+            - line - returns the line containing the exception text
+        """
+        if( aname == "lineno" ):
+            return lineno( self.loc, self.pstr )
+        elif( aname in ("col", "column") ):
+            return col( self.loc, self.pstr )
+        elif( aname == "line" ):
+            return line( self.loc, self.pstr )
+        else:
+            raise AttributeError(aname)
+
+    def __str__( self ):
+        return "%s (at char %d), (line:%d, col:%d)" % \
+                ( self.msg, self.loc, self.lineno, self.column )
+    def __repr__( self ):
+        return _ustr(self)
+    def markInputline( self, markerString = ">!<" ):
+        """Extracts the exception line from the input string, and marks
+           the location of the exception with a special symbol.
+        """
+        line_str = self.line
+        line_column = self.column - 1
+        if markerString:
+            line_str = "".join((line_str[:line_column],
+                                markerString, line_str[line_column:]))
+        return line_str.strip()
+    def __dir__(self):
+        return "lineno col line".split() + dir(type(self))
+
+class ParseException(ParseBaseException):
+    """
+    Exception thrown when parse expressions don't match class;
+    supported attributes by name are:
+     - lineno - returns the line number of the exception text
+     - col - returns the column number of the exception text
+     - line - returns the line containing the exception text
+        
+    Example::
+        try:
+            Word(nums).setName("integer").parseString("ABC")
+        except ParseException as pe:
+            print(pe)
+            print("column: {}".format(pe.col))
+            
+    prints::
+       Expected integer (at char 0), (line:1, col:1)
+        column: 1
+    """
+    pass
+
+class ParseFatalException(ParseBaseException):
+    """user-throwable exception thrown when inconsistent parse content
+       is found; stops all parsing immediately"""
+    pass
+
+class ParseSyntaxException(ParseFatalException):
+    """just like L{ParseFatalException}, but thrown internally when an
+       L{ErrorStop<And._ErrorStop>} ('-' operator) indicates that parsing is to stop 
+       immediately because an unbacktrackable syntax error has been found"""
+    pass
+
+#~ class ReparseException(ParseBaseException):
+    #~ """Experimental class - parse actions can raise this exception to cause
+       #~ pyparsing to reparse the input string:
+        #~ - with a modified input string, and/or
+        #~ - with a modified start location
+       #~ Set the values of the ReparseException in the constructor, and raise the
+       #~ exception in a parse action to cause pyparsing to use the new string/location.
+       #~ Setting the values as None causes no change to be made.
+       #~ """
+    #~ def __init_( self, newstring, restartLoc ):
+        #~ self.newParseText = newstring
+        #~ self.reparseLoc = restartLoc
+
+class RecursiveGrammarException(Exception):
+    """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive"""
+    def __init__( self, parseElementList ):
+        self.parseElementTrace = parseElementList
+
+    def __str__( self ):
+        return "RecursiveGrammarException: %s" % self.parseElementTrace
+
+class _ParseResultsWithOffset(object):
+    def __init__(self,p1,p2):
+        self.tup = (p1,p2)
+    def __getitem__(self,i):
+        return self.tup[i]
+    def __repr__(self):
+        return repr(self.tup[0])
+    def setOffset(self,i):
+        self.tup = (self.tup[0],i)
+
+class ParseResults(object):
+    """
+    Structured parse results, to provide multiple means of access to the parsed data:
+       - as a list (C{len(results)})
+       - by list index (C{results[0], results[1]}, etc.)
+       - by attribute (C{results.<resultsName>} - see L{ParserElement.setResultsName})
+
+    Example::
+        integer = Word(nums)
+        date_str = (integer.setResultsName("year") + '/' 
+                        + integer.setResultsName("month") + '/' 
+                        + integer.setResultsName("day"))
+        # equivalent form:
+        # date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+
+        # parseString returns a ParseResults object
+        result = date_str.parseString("1999/12/31")
+
+        def test(s, fn=repr):
+            print("%s -> %s" % (s, fn(eval(s))))
+        test("list(result)")
+        test("result[0]")
+        test("result['month']")
+        test("result.day")
+        test("'month' in result")
+        test("'minutes' in result")
+        test("result.dump()", str)
+    prints::
+        list(result) -> ['1999', '/', '12', '/', '31']
+        result[0] -> '1999'
+        result['month'] -> '12'
+        result.day -> '31'
+        'month' in result -> True
+        'minutes' in result -> False
+        result.dump() -> ['1999', '/', '12', '/', '31']
+        - day: 31
+        - month: 12
+        - year: 1999
+    """
+    def __new__(cls, toklist=None, name=None, asList=True, modal=True ):
+        if isinstance(toklist, cls):
+            return toklist
+        retobj = object.__new__(cls)
+        retobj.__doinit = True
+        return retobj
+
+    # Performance tuning: we construct a *lot* of these, so keep this
+    # constructor as small and fast as possible
+    def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ):
+        if self.__doinit:
+            self.__doinit = False
+            self.__name = None
+            self.__parent = None
+            self.__accumNames = {}
+            self.__asList = asList
+            self.__modal = modal
+            if toklist is None:
+                toklist = []
+            if isinstance(toklist, list):
+                self.__toklist = toklist[:]
+            elif isinstance(toklist, _generatorType):
+                self.__toklist = list(toklist)
+            else:
+                self.__toklist = [toklist]
+            self.__tokdict = dict()
+
+        if name is not None and name:
+            if not modal:
+                self.__accumNames[name] = 0
+            if isinstance(name,int):
+                name = _ustr(name) # will always return a str, but use _ustr for consistency
+            self.__name = name
+            if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])):
+                if isinstance(toklist,basestring):
+                    toklist = [ toklist ]
+                if asList:
+                    if isinstance(toklist,ParseResults):
+                        self[name] = _ParseResultsWithOffset(toklist.copy(),0)
+                    else:
+                        self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0)
+                    self[name].__name = name
+                else:
+                    try:
+                        self[name] = toklist[0]
+                    except (KeyError,TypeError,IndexError):
+                        self[name] = toklist
+
+    def __getitem__( self, i ):
+        if isinstance( i, (int,slice) ):
+            return self.__toklist[i]
+        else:
+            if i not in self.__accumNames:
+                return self.__tokdict[i][-1][0]
+            else:
+                return ParseResults([ v[0] for v in self.__tokdict[i] ])
+
+    def __setitem__( self, k, v, isinstance=isinstance ):
+        if isinstance(v,_ParseResultsWithOffset):
+            self.__tokdict[k] = self.__tokdict.get(k,list()) + [v]
+            sub = v[0]
+        elif isinstance(k,(int,slice)):
+            self.__toklist[k] = v
+            sub = v
+        else:
+            self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)]
+            sub = v
+        if isinstance(sub,ParseResults):
+            sub.__parent = wkref(self)
+
+    def __delitem__( self, i ):
+        if isinstance(i,(int,slice)):
+            mylen = len( self.__toklist )
+            del self.__toklist[i]
+
+            # convert int to slice
+            if isinstance(i, int):
+                if i < 0:
+                    i += mylen
+                i = slice(i, i+1)
+            # get removed indices
+            removed = list(range(*i.indices(mylen)))
+            removed.reverse()
+            # fixup indices in token dictionary
+            for name,occurrences in self.__tokdict.items():
+                for j in removed:
+                    for k, (value, position) in enumerate(occurrences):
+                        occurrences[k] = _ParseResultsWithOffset(value, position - (position > j))
+        else:
+            del self.__tokdict[i]
+
+    def __contains__( self, k ):
+        return k in self.__tokdict
+
+    def __len__( self ): return len( self.__toklist )
+    def __bool__(self): return ( not not self.__toklist )
+    __nonzero__ = __bool__
+    def __iter__( self ): return iter( self.__toklist )
+    def __reversed__( self ): return iter( self.__toklist[::-1] )
+    def _iterkeys( self ):
+        if hasattr(self.__tokdict, "iterkeys"):
+            return self.__tokdict.iterkeys()
+        else:
+            return iter(self.__tokdict)
+
+    def _itervalues( self ):
+        return (self[k] for k in self._iterkeys())
+            
+    def _iteritems( self ):
+        return ((k, self[k]) for k in self._iterkeys())
+
+    if PY_3:
+        keys = _iterkeys       
+        """Returns an iterator of all named result keys (Python 3.x only)."""
+
+        values = _itervalues
+        """Returns an iterator of all named result values (Python 3.x only)."""
+
+        items = _iteritems
+        """Returns an iterator of all named result key-value tuples (Python 3.x only)."""
+
+    else:
+        iterkeys = _iterkeys
+        """Returns an iterator of all named result keys (Python 2.x only)."""
+
+        itervalues = _itervalues
+        """Returns an iterator of all named result values (Python 2.x only)."""
+
+        iteritems = _iteritems
+        """Returns an iterator of all named result key-value tuples (Python 2.x only)."""
+
+        def keys( self ):
+            """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x)."""
+            return list(self.iterkeys())
+
+        def values( self ):
+            """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x)."""
+            return list(self.itervalues())
+                
+        def items( self ):
+            """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x)."""
+            return list(self.iteritems())
+
+    def haskeys( self ):
+        """Since keys() returns an iterator, this method is helpful in bypassing
+           code that looks for the existence of any defined results names."""
+        return bool(self.__tokdict)
+        
+    def pop( self, *args, **kwargs):
+        """
+        Removes and returns item at specified index (default=C{last}).
+        Supports both C{list} and C{dict} semantics for C{pop()}. If passed no
+        argument or an integer argument, it will use C{list} semantics
+        and pop tokens from the list of parsed tokens. If passed a 
+        non-integer argument (most likely a string), it will use C{dict}
+        semantics and pop the corresponding value from any defined 
+        results names. A second default return value argument is 
+        supported, just as in C{dict.pop()}.
+
+        Example::
+            def remove_first(tokens):
+                tokens.pop(0)
+            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
+            print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321']
+
+            label = Word(alphas)
+            patt = label("LABEL") + OneOrMore(Word(nums))
+            print(patt.parseString("AAB 123 321").dump())
+
+            # Use pop() in a parse action to remove named result (note that corresponding value is not
+            # removed from list form of results)
+            def remove_LABEL(tokens):
+                tokens.pop("LABEL")
+                return tokens
+            patt.addParseAction(remove_LABEL)
+            print(patt.parseString("AAB 123 321").dump())
+        prints::
+            ['AAB', '123', '321']
+            - LABEL: AAB
+
+            ['AAB', '123', '321']
+        """
+        if not args:
+            args = [-1]
+        for k,v in kwargs.items():
+            if k == 'default':
+                args = (args[0], v)
+            else:
+                raise TypeError("pop() got an unexpected keyword argument '%s'" % k)
+        if (isinstance(args[0], int) or 
+                        len(args) == 1 or 
+                        args[0] in self):
+            index = args[0]
+            ret = self[index]
+            del self[index]
+            return ret
+        else:
+            defaultvalue = args[1]
+            return defaultvalue
+
+    def get(self, key, defaultValue=None):
+        """
+        Returns named result matching the given key, or if there is no
+        such name, then returns the given C{defaultValue} or C{None} if no
+        C{defaultValue} is specified.
+
+        Similar to C{dict.get()}.
+        
+        Example::
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
+
+            result = date_str.parseString("1999/12/31")
+            print(result.get("year")) # -> '1999'
+            print(result.get("hour", "not specified")) # -> 'not specified'
+            print(result.get("hour")) # -> None
+        """
+        if key in self:
+            return self[key]
+        else:
+            return defaultValue
+
+    def insert( self, index, insStr ):
+        """
+        Inserts new element at location index in the list of parsed tokens.
+        
+        Similar to C{list.insert()}.
+
+        Example::
+            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
+
+            # use a parse action to insert the parse location in the front of the parsed results
+            def insert_locn(locn, tokens):
+                tokens.insert(0, locn)
+            print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321']
+        """
+        self.__toklist.insert(index, insStr)
+        # fixup indices in token dictionary
+        for name,occurrences in self.__tokdict.items():
+            for k, (value, position) in enumerate(occurrences):
+                occurrences[k] = _ParseResultsWithOffset(value, position + (position > index))
+
+    def append( self, item ):
+        """
+        Add single element to end of ParseResults list of elements.
+
+        Example::
+            print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321']
+            
+            # use a parse action to compute the sum of the parsed integers, and add it to the end
+            def append_sum(tokens):
+                tokens.append(sum(map(int, tokens)))
+            print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444]
+        """
+        self.__toklist.append(item)
+
+    def extend( self, itemseq ):
+        """
+        Add sequence of elements to end of ParseResults list of elements.
+
+        Example::
+            patt = OneOrMore(Word(alphas))
+            
+            # use a parse action to append the reverse of the matched strings, to make a palindrome
+            def make_palindrome(tokens):
+                tokens.extend(reversed([t[::-1] for t in tokens]))
+                return ''.join(tokens)
+            print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl'
+        """
+        if isinstance(itemseq, ParseResults):
+            self += itemseq
+        else:
+            self.__toklist.extend(itemseq)
+
+    def clear( self ):
+        """
+        Clear all elements and results names.
+        """
+        del self.__toklist[:]
+        self.__tokdict.clear()
+
+    def __getattr__( self, name ):
+        try:
+            return self[name]
+        except KeyError:
+            return ""
+            
+        if name in self.__tokdict:
+            if name not in self.__accumNames:
+                return self.__tokdict[name][-1][0]
+            else:
+                return ParseResults([ v[0] for v in self.__tokdict[name] ])
+        else:
+            return ""
+
+    def __add__( self, other ):
+        ret = self.copy()
+        ret += other
+        return ret
+
+    def __iadd__( self, other ):
+        if other.__tokdict:
+            offset = len(self.__toklist)
+            addoffset = lambda a: offset if a<0 else a+offset
+            otheritems = other.__tokdict.items()
+            otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) )
+                                for (k,vlist) in otheritems for v in vlist]
+            for k,v in otherdictitems:
+                self[k] = v
+                if isinstance(v[0],ParseResults):
+                    v[0].__parent = wkref(self)
+            
+        self.__toklist += other.__toklist
+        self.__accumNames.update( other.__accumNames )
+        return self
+
+    def __radd__(self, other):
+        if isinstance(other,int) and other == 0:
+            # useful for merging many ParseResults using sum() builtin
+            return self.copy()
+        else:
+            # this may raise a TypeError - so be it
+            return other + self
+        
+    def __repr__( self ):
+        return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) )
+
+    def __str__( self ):
+        return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']'
+
+    def _asStringList( self, sep='' ):
+        out = []
+        for item in self.__toklist:
+            if out and sep:
+                out.append(sep)
+            if isinstance( item, ParseResults ):
+                out += item._asStringList()
+            else:
+                out.append( _ustr(item) )
+        return out
+
+    def asList( self ):
+        """
+        Returns the parse results as a nested list of matching tokens, all converted to strings.
+
+        Example::
+            patt = OneOrMore(Word(alphas))
+            result = patt.parseString("sldkj lsdkj sldkj")
+            # even though the result prints in string-like form, it is actually a pyparsing ParseResults
+            print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj']
+            
+            # Use asList() to create an actual list
+            result_list = result.asList()
+            print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj']
+        """
+        return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist]
+
+    def asDict( self ):
+        """
+        Returns the named parse results as a nested dictionary.
+
+        Example::
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+            
+            result = date_str.parseString('12/31/1999')
+            print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]})
+            
+            result_dict = result.asDict()
+            print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'}
+
+            # even though a ParseResults supports dict-like access, sometime you just need to have a dict
+            import json
+            print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable
+            print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"}
+        """
+        if PY_3:
+            item_fn = self.items
+        else:
+            item_fn = self.iteritems
+            
+        def toItem(obj):
+            if isinstance(obj, ParseResults):
+                if obj.haskeys():
+                    return obj.asDict()
+                else:
+                    return [toItem(v) for v in obj]
+            else:
+                return obj
+                
+        return dict((k,toItem(v)) for k,v in item_fn())
+
+    def copy( self ):
+        """
+        Returns a new copy of a C{ParseResults} object.
+        """
+        ret = ParseResults( self.__toklist )
+        ret.__tokdict = self.__tokdict.copy()
+        ret.__parent = self.__parent
+        ret.__accumNames.update( self.__accumNames )
+        ret.__name = self.__name
+        return ret
+
+    def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ):
+        """
+        (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names.
+        """
+        nl = "\n"
+        out = []
+        namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items()
+                                                            for v in vlist)
+        nextLevelIndent = indent + "  "
+
+        # collapse out indents if formatting is not desired
+        if not formatted:
+            indent = ""
+            nextLevelIndent = ""
+            nl = ""
+
+        selfTag = None
+        if doctag is not None:
+            selfTag = doctag
+        else:
+            if self.__name:
+                selfTag = self.__name
+
+        if not selfTag:
+            if namedItemsOnly:
+                return ""
+            else:
+                selfTag = "ITEM"
+
+        out += [ nl, indent, "<", selfTag, ">" ]
+
+        for i,res in enumerate(self.__toklist):
+            if isinstance(res,ParseResults):
+                if i in namedItems:
+                    out += [ res.asXML(namedItems[i],
+                                        namedItemsOnly and doctag is None,
+                                        nextLevelIndent,
+                                        formatted)]
+                else:
+                    out += [ res.asXML(None,
+                                        namedItemsOnly and doctag is None,
+                                        nextLevelIndent,
+                                        formatted)]
+            else:
+                # individual token, see if there is a name for it
+                resTag = None
+                if i in namedItems:
+                    resTag = namedItems[i]
+                if not resTag:
+                    if namedItemsOnly:
+                        continue
+                    else:
+                        resTag = "ITEM"
+                xmlBodyText = _xml_escape(_ustr(res))
+                out += [ nl, nextLevelIndent, "<", resTag, ">",
+                                                xmlBodyText,
+                                                "</", resTag, ">" ]
+
+        out += [ nl, indent, "</", selfTag, ">" ]
+        return "".join(out)
+
+    def __lookup(self,sub):
+        for k,vlist in self.__tokdict.items():
+            for v,loc in vlist:
+                if sub is v:
+                    return k
+        return None
+
+    def getName(self):
+        """
+        Returns the results name for this token expression. Useful when several 
+        different expressions might match at a particular location.
+
+        Example::
+            integer = Word(nums)
+            ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d")
+            house_number_expr = Suppress('#') + Word(nums, alphanums)
+            user_data = (Group(house_number_expr)("house_number") 
+                        | Group(ssn_expr)("ssn")
+                        | Group(integer)("age"))
+            user_info = OneOrMore(user_data)
+            
+            result = user_info.parseString("22 111-22-3333 #221B")
+            for item in result:
+                print(item.getName(), ':', item[0])
+        prints::
+            age : 22
+            ssn : 111-22-3333
+            house_number : 221B
+        """
+        if self.__name:
+            return self.__name
+        elif self.__parent:
+            par = self.__parent()
+            if par:
+                return par.__lookup(self)
+            else:
+                return None
+        elif (len(self) == 1 and
+               len(self.__tokdict) == 1 and
+               next(iter(self.__tokdict.values()))[0][1] in (0,-1)):
+            return next(iter(self.__tokdict.keys()))
+        else:
+            return None
+
+    def dump(self, indent='', depth=0, full=True):
+        """
+        Diagnostic method for listing out the contents of a C{ParseResults}.
+        Accepts an optional C{indent} argument so that this string can be embedded
+        in a nested display of other data.
+
+        Example::
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+            
+            result = date_str.parseString('12/31/1999')
+            print(result.dump())
+        prints::
+            ['12', '/', '31', '/', '1999']
+            - day: 1999
+            - month: 31
+            - year: 12
+        """
+        out = []
+        NL = '\n'
+        out.append( indent+_ustr(self.asList()) )
+        if full:
+            if self.haskeys():
+                items = sorted((str(k), v) for k,v in self.items())
+                for k,v in items:
+                    if out:
+                        out.append(NL)
+                    out.append( "%s%s- %s: " % (indent,('  '*depth), k) )
+                    if isinstance(v,ParseResults):
+                        if v:
+                            out.append( v.dump(indent,depth+1) )
+                        else:
+                            out.append(_ustr(v))
+                    else:
+                        out.append(repr(v))
+            elif any(isinstance(vv,ParseResults) for vv in self):
+                v = self
+                for i,vv in enumerate(v):
+                    if isinstance(vv,ParseResults):
+                        out.append("\n%s%s[%d]:\n%s%s%s" % (indent,('  '*(depth)),i,indent,('  '*(depth+1)),vv.dump(indent,depth+1) ))
+                    else:
+                        out.append("\n%s%s[%d]:\n%s%s%s" % (indent,('  '*(depth)),i,indent,('  '*(depth+1)),_ustr(vv)))
+            
+        return "".join(out)
+
+    def pprint(self, *args, **kwargs):
+        """
+        Pretty-printer for parsed results as a list, using the C{pprint} module.
+        Accepts additional positional or keyword args as defined for the 
+        C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint})
+
+        Example::
+            ident = Word(alphas, alphanums)
+            num = Word(nums)
+            func = Forward()
+            term = ident | num | Group('(' + func + ')')
+            func <<= ident + Group(Optional(delimitedList(term)))
+            result = func.parseString("fna a,b,(fnb c,d,200),100")
+            result.pprint(width=40)
+        prints::
+            ['fna',
+             ['a',
+              'b',
+              ['(', 'fnb', ['c', 'd', '200'], ')'],
+              '100']]
+        """
+        pprint.pprint(self.asList(), *args, **kwargs)
+
+    # add support for pickle protocol
+    def __getstate__(self):
+        return ( self.__toklist,
+                 ( self.__tokdict.copy(),
+                   self.__parent is not None and self.__parent() or None,
+                   self.__accumNames,
+                   self.__name ) )
+
+    def __setstate__(self,state):
+        self.__toklist = state[0]
+        (self.__tokdict,
+         par,
+         inAccumNames,
+         self.__name) = state[1]
+        self.__accumNames = {}
+        self.__accumNames.update(inAccumNames)
+        if par is not None:
+            self.__parent = wkref(par)
+        else:
+            self.__parent = None
+
+    def __getnewargs__(self):
+        return self.__toklist, self.__name, self.__asList, self.__modal
+
+    def __dir__(self):
+        return (dir(type(self)) + list(self.keys()))
+
+collections.MutableMapping.register(ParseResults)
+
+def col (loc,strg):
+    """Returns current column within a string, counting newlines as line separators.
+   The first column is number 1.
+
+   Note: the default parsing behavior is to expand tabs in the input string
+   before starting the parsing process.  See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information
+   on parsing strings containing C{<TAB>}s, and suggested methods to maintain a
+   consistent view of the parsed string, the parse location, and line and column
+   positions within the parsed string.
+   """
+    s = strg
+    return 1 if 0<loc<len(s) and s[loc-1] == '\n' else loc - s.rfind("\n", 0, loc)
+
+def lineno(loc,strg):
+    """Returns current line number within a string, counting newlines as line separators.
+   The first line is number 1.
+
+   Note: the default parsing behavior is to expand tabs in the input string
+   before starting the parsing process.  See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information
+   on parsing strings containing C{<TAB>}s, and suggested methods to maintain a
+   consistent view of the parsed string, the parse location, and line and column
+   positions within the parsed string.
+   """
+    return strg.count("\n",0,loc) + 1
+
+def line( loc, strg ):
+    """Returns the line of text containing loc within a string, counting newlines as line separators.
+       """
+    lastCR = strg.rfind("\n", 0, loc)
+    nextCR = strg.find("\n", loc)
+    if nextCR >= 0:
+        return strg[lastCR+1:nextCR]
+    else:
+        return strg[lastCR+1:]
+
+def _defaultStartDebugAction( instring, loc, expr ):
+    print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )))
+
+def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ):
+    print ("Matched " + _ustr(expr) + " -> " + str(toks.asList()))
+
+def _defaultExceptionDebugAction( instring, loc, expr, exc ):
+    print ("Exception raised:" + _ustr(exc))
+
+def nullDebugAction(*args):
+    """'Do-nothing' debug action, to suppress debugging output during parsing."""
+    pass
+
+# Only works on Python 3.x - nonlocal is toxic to Python 2 installs
+#~ 'decorator to trim function calls to match the arity of the target'
+#~ def _trim_arity(func, maxargs=3):
+    #~ if func in singleArgBuiltins:
+        #~ return lambda s,l,t: func(t)
+    #~ limit = 0
+    #~ foundArity = False
+    #~ def wrapper(*args):
+        #~ nonlocal limit,foundArity
+        #~ while 1:
+            #~ try:
+                #~ ret = func(*args[limit:])
+                #~ foundArity = True
+                #~ return ret
+            #~ except TypeError:
+                #~ if limit == maxargs or foundArity:
+                    #~ raise
+                #~ limit += 1
+                #~ continue
+    #~ return wrapper
+
+# this version is Python 2.x-3.x cross-compatible
+'decorator to trim function calls to match the arity of the target'
+def _trim_arity(func, maxargs=2):
+    if func in singleArgBuiltins:
+        return lambda s,l,t: func(t)
+    limit = [0]
+    foundArity = [False]
+    
+    # traceback return data structure changed in Py3.5 - normalize back to plain tuples
+    if system_version[:2] >= (3,5):
+        def extract_stack(limit=0):
+            # special handling for Python 3.5.0 - extra deep call stack by 1
+            offset = -3 if system_version == (3,5,0) else -2
+            frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset]
+            return [(frame_summary.filename, frame_summary.lineno)]
+        def extract_tb(tb, limit=0):
+            frames = traceback.extract_tb(tb, limit=limit)
+            frame_summary = frames[-1]
+            return [(frame_summary.filename, frame_summary.lineno)]
+    else:
+        extract_stack = traceback.extract_stack
+        extract_tb = traceback.extract_tb
+    
+    # synthesize what would be returned by traceback.extract_stack at the call to 
+    # user's parse action 'func', so that we don't incur call penalty at parse time
+    
+    LINE_DIFF = 6
+    # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND 
+    # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!!
+    this_line = extract_stack(limit=2)[-1]
+    pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF)
+
+    def wrapper(*args):
+        while 1:
+            try:
+                ret = func(*args[limit[0]:])
+                foundArity[0] = True
+                return ret
+            except TypeError:
+                # re-raise TypeErrors if they did not come from our arity testing
+                if foundArity[0]:
+                    raise
+                else:
+                    try:
+                        tb = sys.exc_info()[-1]
+                        if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth:
+                            raise
+                    finally:
+                        del tb
+
+                if limit[0] <= maxargs:
+                    limit[0] += 1
+                    continue
+                raise
+
+    # copy func name to wrapper for sensible debug output
+    func_name = "<parse action>"
+    try:
+        func_name = getattr(func, '__name__', 
+                            getattr(func, '__class__').__name__)
+    except Exception:
+        func_name = str(func)
+    wrapper.__name__ = func_name
+
+    return wrapper
+
+class ParserElement(object):
+    """Abstract base level parser element class."""
+    DEFAULT_WHITE_CHARS = " \n\t\r"
+    verbose_stacktrace = False
+
+    @staticmethod
+    def setDefaultWhitespaceChars( chars ):
+        r"""
+        Overrides the default whitespace chars
+
+        Example::
+            # default whitespace chars are space, <TAB> and newline
+            OneOrMore(Word(alphas)).parseString("abc def\nghi jkl")  # -> ['abc', 'def', 'ghi', 'jkl']
+            
+            # change to just treat newline as significant
+            ParserElement.setDefaultWhitespaceChars(" \t")
+            OneOrMore(Word(alphas)).parseString("abc def\nghi jkl")  # -> ['abc', 'def']
+        """
+        ParserElement.DEFAULT_WHITE_CHARS = chars
+
+    @staticmethod
+    def inlineLiteralsUsing(cls):
+        """
+        Set class to be used for inclusion of string literals into a parser.
+        
+        Example::
+            # default literal class used is Literal
+            integer = Word(nums)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
+
+            date_str.parseString("1999/12/31")  # -> ['1999', '/', '12', '/', '31']
+
+
+            # change to Suppress
+            ParserElement.inlineLiteralsUsing(Suppress)
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")           
+
+            date_str.parseString("1999/12/31")  # -> ['1999', '12', '31']
+        """
+        ParserElement._literalStringClass = cls
+
+    def __init__( self, savelist=False ):
+        self.parseAction = list()
+        self.failAction = None
+        #~ self.name = "<unknown>"  # don't define self.name, let subclasses try/except upcall
+        self.strRepr = None
+        self.resultsName = None
+        self.saveAsList = savelist
+        self.skipWhitespace = True
+        self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
+        self.copyDefaultWhiteChars = True
+        self.mayReturnEmpty = False # used when checking for left-recursion
+        self.keepTabs = False
+        self.ignoreExprs = list()
+        self.debug = False
+        self.streamlined = False
+        self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index
+        self.errmsg = ""
+        self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all)
+        self.debugActions = ( None, None, None ) #custom debug actions
+        self.re = None
+        self.callPreparse = True # used to avoid redundant calls to preParse
+        self.callDuringTry = False
+
+    def copy( self ):
+        """
+        Make a copy of this C{ParserElement}.  Useful for defining different parse actions
+        for the same parsing pattern, using copies of the original parse element.
+        
+        Example::
+            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
+            integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K")
+            integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
+            
+            print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M"))
+        prints::
+            [5120, 100, 655360, 268435456]
+        Equivalent form of C{expr.copy()} is just C{expr()}::
+            integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M")
+        """
+        cpy = copy.copy( self )
+        cpy.parseAction = self.parseAction[:]
+        cpy.ignoreExprs = self.ignoreExprs[:]
+        if self.copyDefaultWhiteChars:
+            cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
+        return cpy
+
+    def setName( self, name ):
+        """
+        Define name for this expression, makes debugging and exception messages clearer.
+        
+        Example::
+            Word(nums).parseString("ABC")  # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1)
+            Word(nums).setName("integer").parseString("ABC")  # -> Exception: Expected integer (at char 0), (line:1, col:1)
+        """
+        self.name = name
+        self.errmsg = "Expected " + self.name
+        if hasattr(self,"exception"):
+            self.exception.msg = self.errmsg
+        return self
+
+    def setResultsName( self, name, listAllMatches=False ):
+        """
+        Define name for referencing matching tokens as a nested attribute
+        of the returned parse results.
+        NOTE: this returns a *copy* of the original C{ParserElement} object;
+        this is so that the client can define a basic element, such as an
+        integer, and reference it in multiple places with different names.
+
+        You can also set results names using the abbreviated syntax,
+        C{expr("name")} in place of C{expr.setResultsName("name")} - 
+        see L{I{__call__}<__call__>}.
+
+        Example::
+            date_str = (integer.setResultsName("year") + '/' 
+                        + integer.setResultsName("month") + '/' 
+                        + integer.setResultsName("day"))
+
+            # equivalent form:
+            date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
+        """
+        newself = self.copy()
+        if name.endswith("*"):
+            name = name[:-1]
+            listAllMatches=True
+        newself.resultsName = name
+        newself.modalResults = not listAllMatches
+        return newself
+
+    def setBreak(self,breakFlag = True):
+        """Method to invoke the Python pdb debugger when this element is
+           about to be parsed. Set C{breakFlag} to True to enable, False to
+           disable.
+        """
+        if breakFlag:
+            _parseMethod = self._parse
+            def breaker(instring, loc, doActions=True, callPreParse=True):
+                import pdb
+                pdb.set_trace()
+                return _parseMethod( instring, loc, doActions, callPreParse )
+            breaker._originalParseMethod = _parseMethod
+            self._parse = breaker
+        else:
+            if hasattr(self._parse,"_originalParseMethod"):
+                self._parse = self._parse._originalParseMethod
+        return self
+
+    def setParseAction( self, *fns, **kwargs ):
+        """
+        Define action to perform when successfully matching parse element definition.
+        Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)},
+        C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where:
+         - s   = the original string being parsed (see note below)
+         - loc = the location of the matching substring
+         - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object
+        If the functions in fns modify the tokens, they can return them as the return
+        value from fn, and the modified list of tokens will replace the original.
+        Otherwise, fn does not need to return any value.
+
+        Optional keyword arguments:
+         - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing
+
+        Note: the default parsing behavior is to expand tabs in the input string
+        before starting the parsing process.  See L{I{parseString}<parseString>} for more information
+        on parsing strings containing C{<TAB>}s, and suggested methods to maintain a
+        consistent view of the parsed string, the parse location, and line and column
+        positions within the parsed string.
+        
+        Example::
+            integer = Word(nums)
+            date_str = integer + '/' + integer + '/' + integer
+
+            date_str.parseString("1999/12/31")  # -> ['1999', '/', '12', '/', '31']
+
+            # use parse action to convert to ints at parse time
+            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
+            date_str = integer + '/' + integer + '/' + integer
+
+            # note that integer fields are now ints, not strings
+            date_str.parseString("1999/12/31")  # -> [1999, '/', 12, '/', 31]
+        """
+        self.parseAction = list(map(_trim_arity, list(fns)))
+        self.callDuringTry = kwargs.get("callDuringTry", False)
+        return self
+
+    def addParseAction( self, *fns, **kwargs ):
+        """
+        Add parse action to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}.
+        
+        See examples in L{I{copy}<copy>}.
+        """
+        self.parseAction += list(map(_trim_arity, list(fns)))
+        self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False)
+        return self
+
+    def addCondition(self, *fns, **kwargs):
+        """Add a boolean predicate function to expression's list of parse actions. See 
+        L{I{setParseAction}<setParseAction>} for function call signatures. Unlike C{setParseAction}, 
+        functions passed to C{addCondition} need to return boolean success/fail of the condition.
+
+        Optional keyword arguments:
+         - message = define a custom message to be used in the raised exception
+         - fatal   = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException
+         
+        Example::
+            integer = Word(nums).setParseAction(lambda toks: int(toks[0]))
+            year_int = integer.copy()
+            year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later")
+            date_str = year_int + '/' + integer + '/' + integer
+
+            result = date_str.parseString("1999/12/31")  # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1)
+        """
+        msg = kwargs.get("message", "failed user-defined condition")
+        exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException
+        for fn in fns:
+            def pa(s,l,t):
+                if not bool(_trim_arity(fn)(s,l,t)):
+                    raise exc_type(s,l,msg)
+            self.parseAction.append(pa)
+        self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False)
+        return self
+
+    def setFailAction( self, fn ):
+        """Define action to perform if parsing fails at this expression.
+           Fail acton fn is a callable function that takes the arguments
+           C{fn(s,loc,expr,err)} where:
+            - s = string being parsed
+            - loc = location where expression match was attempted and failed
+            - expr = the parse expression that failed
+            - err = the exception thrown
+           The function returns no value.  It may throw C{L{ParseFatalException}}
+           if it is desired to stop parsing immediately."""
+        self.failAction = fn
+        return self
+
+    def _skipIgnorables( self, instring, loc ):
+        exprsFound = True
+        while exprsFound:
+            exprsFound = False
+            for e in self.ignoreExprs:
+                try:
+                    while 1:
+                        loc,dummy = e._parse( instring, loc )
+                        exprsFound = True
+                except ParseException:
+                    pass
+        return loc
+
+    def preParse( self, instring, loc ):
+        if self.ignoreExprs:
+            loc = self._skipIgnorables( instring, loc )
+
+        if self.skipWhitespace:
+            wt = self.whiteChars
+            instrlen = len(instring)
+            while loc < instrlen and instring[loc] in wt:
+                loc += 1
+
+        return loc
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        return loc, []
+
+    def postParse( self, instring, loc, tokenlist ):
+        return tokenlist
+
+    #~ @profile
+    def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ):
+        debugging = ( self.debug ) #and doActions )
+
+        if debugging or self.failAction:
+            #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))
+            if (self.debugActions[0] ):
+                self.debugActions[0]( instring, loc, self )
+            if callPreParse and self.callPreparse:
+                preloc = self.preParse( instring, loc )
+            else:
+                preloc = loc
+            tokensStart = preloc
+            try:
+                try:
+                    loc,tokens = self.parseImpl( instring, preloc, doActions )
+                except IndexError:
+                    raise ParseException( instring, len(instring), self.errmsg, self )
+            except ParseBaseException as err:
+                #~ print ("Exception raised:", err)
+                if self.debugActions[2]:
+                    self.debugActions[2]( instring, tokensStart, self, err )
+                if self.failAction:
+                    self.failAction( instring, tokensStart, self, err )
+                raise
+        else:
+            if callPreParse and self.callPreparse:
+                preloc = self.preParse( instring, loc )
+            else:
+                preloc = loc
+            tokensStart = preloc
+            if self.mayIndexError or loc >= len(instring):
+                try:
+                    loc,tokens = self.parseImpl( instring, preloc, doActions )
+                except IndexError:
+                    raise ParseException( instring, len(instring), self.errmsg, self )
+            else:
+                loc,tokens = self.parseImpl( instring, preloc, doActions )
+
+        tokens = self.postParse( instring, loc, tokens )
+
+        retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults )
+        if self.parseAction and (doActions or self.callDuringTry):
+            if debugging:
+                try:
+                    for fn in self.parseAction:
+                        tokens = fn( instring, tokensStart, retTokens )
+                        if tokens is not None:
+                            retTokens = ParseResults( tokens,
+                                                      self.resultsName,
+                                                      asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
+                                                      modal=self.modalResults )
+                except ParseBaseException as err:
+                    #~ print "Exception raised in user parse action:", err
+                    if (self.debugActions[2] ):
+                        self.debugActions[2]( instring, tokensStart, self, err )
+                    raise
+            else:
+                for fn in self.parseAction:
+                    tokens = fn( instring, tokensStart, retTokens )
+                    if tokens is not None:
+                        retTokens = ParseResults( tokens,
+                                                  self.resultsName,
+                                                  asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
+                                                  modal=self.modalResults )
+
+        if debugging:
+            #~ print ("Matched",self,"->",retTokens.asList())
+            if (self.debugActions[1] ):
+                self.debugActions[1]( instring, tokensStart, loc, self, retTokens )
+
+        return loc, retTokens
+
+    def tryParse( self, instring, loc ):
+        try:
+            return self._parse( instring, loc, doActions=False )[0]
+        except ParseFatalException:
+            raise ParseException( instring, loc, self.errmsg, self)
+    
+    def canParseNext(self, instring, loc):
+        try:
+            self.tryParse(instring, loc)
+        except (ParseException, IndexError):
+            return False
+        else:
+            return True
+
+    class _UnboundedCache(object):
+        def __init__(self):
+            cache = {}
+            self.not_in_cache = not_in_cache = object()
+
+            def get(self, key):
+                return cache.get(key, not_in_cache)
+
+            def set(self, key, value):
+                cache[key] = value
+
+            def clear(self):
+                cache.clear()
+
+            self.get = types.MethodType(get, self)
+            self.set = types.MethodType(set, self)
+            self.clear = types.MethodType(clear, self)
+
+    if _OrderedDict is not None:
+        class _FifoCache(object):
+            def __init__(self, size):
+                self.not_in_cache = not_in_cache = object()
+
+                cache = _OrderedDict()
+
+                def get(self, key):
+                    return cache.get(key, not_in_cache)
+
+                def set(self, key, value):
+                    cache[key] = value
+                    if len(cache) > size:
+                        cache.popitem(False)
+
+                def clear(self):
+                    cache.clear()
+
+                self.get = types.MethodType(get, self)
+                self.set = types.MethodType(set, self)
+                self.clear = types.MethodType(clear, self)
+
+    else:
+        class _FifoCache(object):
+            def __init__(self, size):
+                self.not_in_cache = not_in_cache = object()
+
+                cache = {}
+                key_fifo = collections.deque([], size)
+
+                def get(self, key):
+                    return cache.get(key, not_in_cache)
+
+                def set(self, key, value):
+                    cache[key] = value
+                    if len(cache) > size:
+                        cache.pop(key_fifo.popleft(), None)
+                    key_fifo.append(key)
+
+                def clear(self):
+                    cache.clear()
+                    key_fifo.clear()
+
+                self.get = types.MethodType(get, self)
+                self.set = types.MethodType(set, self)
+                self.clear = types.MethodType(clear, self)
+
+    # argument cache for optimizing repeated calls when backtracking through recursive expressions
+    packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail
+    packrat_cache_lock = RLock()
+    packrat_cache_stats = [0, 0]
+
+    # this method gets repeatedly called during backtracking with the same arguments -
+    # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression
+    def _parseCache( self, instring, loc, doActions=True, callPreParse=True ):
+        HIT, MISS = 0, 1
+        lookup = (self, instring, loc, callPreParse, doActions)
+        with ParserElement.packrat_cache_lock:
+            cache = ParserElement.packrat_cache
+            value = cache.get(lookup)
+            if value is cache.not_in_cache:
+                ParserElement.packrat_cache_stats[MISS] += 1
+                try:
+                    value = self._parseNoCache(instring, loc, doActions, callPreParse)
+                except ParseBaseException as pe:
+                    # cache a copy of the exception, without the traceback
+                    cache.set(lookup, pe.__class__(*pe.args))
+                    raise
+                else:
+                    cache.set(lookup, (value[0], value[1].copy()))
+                    return value
+            else:
+                ParserElement.packrat_cache_stats[HIT] += 1
+                if isinstance(value, Exception):
+                    raise value
+                return (value[0], value[1].copy())
+
+    _parse = _parseNoCache
+
+    @staticmethod
+    def resetCache():
+        ParserElement.packrat_cache.clear()
+        ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats)
+
+    _packratEnabled = False
+    @staticmethod
+    def enablePackrat(cache_size_limit=128):
+        """Enables "packrat" parsing, which adds memoizing to the parsing logic.
+           Repeated parse attempts at the same string location (which happens
+           often in many complex grammars) can immediately return a cached value,
+           instead of re-executing parsing/validating code.  Memoizing is done of
+           both valid results and parsing exceptions.
+           
+           Parameters:
+            - cache_size_limit - (default=C{128}) - if an integer value is provided
+              will limit the size of the packrat cache; if None is passed, then
+              the cache size will be unbounded; if 0 is passed, the cache will
+              be effectively disabled.
+            
+           This speedup may break existing programs that use parse actions that
+           have side-effects.  For this reason, packrat parsing is disabled when
+           you first import pyparsing.  To activate the packrat feature, your
+           program must call the class method C{ParserElement.enablePackrat()}.  If
+           your program uses C{psyco} to "compile as you go", you must call
+           C{enablePackrat} before calling C{psyco.full()}.  If you do not do this,
+           Python will crash.  For best results, call C{enablePackrat()} immediately
+           after importing pyparsing.
+           
+           Example::
+               import pyparsing
+               pyparsing.ParserElement.enablePackrat()
+        """
+        if not ParserElement._packratEnabled:
+            ParserElement._packratEnabled = True
+            if cache_size_limit is None:
+                ParserElement.packrat_cache = ParserElement._UnboundedCache()
+            else:
+                ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit)
+            ParserElement._parse = ParserElement._parseCache
+
+    def parseString( self, instring, parseAll=False ):
+        """
+        Execute the parse expression with the given string.
+        This is the main interface to the client code, once the complete
+        expression has been built.
+
+        If you want the grammar to require that the entire input string be
+        successfully parsed, then set C{parseAll} to True (equivalent to ending
+        the grammar with C{L{StringEnd()}}).
+
+        Note: C{parseString} implicitly calls C{expandtabs()} on the input string,
+        in order to report proper column numbers in parse actions.
+        If the input string contains tabs and
+        the grammar uses parse actions that use the C{loc} argument to index into the
+        string being parsed, you can ensure you have a consistent view of the input
+        string by:
+         - calling C{parseWithTabs} on your grammar before calling C{parseString}
+           (see L{I{parseWithTabs}<parseWithTabs>})
+         - define your parse action using the full C{(s,loc,toks)} signature, and
+           reference the input string using the parse action's C{s} argument
+         - explictly expand the tabs in your input string before calling
+           C{parseString}
+        
+        Example::
+            Word('a').parseString('aaaaabaaa')  # -> ['aaaaa']
+            Word('a').parseString('aaaaabaaa', parseAll=True)  # -> Exception: Expected end of text
+        """
+        ParserElement.resetCache()
+        if not self.streamlined:
+            self.streamline()
+            #~ self.saveAsList = True
+        for e in self.ignoreExprs:
+            e.streamline()
+        if not self.keepTabs:
+            instring = instring.expandtabs()
+        try:
+            loc, tokens = self._parse( instring, 0 )
+            if parseAll:
+                loc = self.preParse( instring, loc )
+                se = Empty() + StringEnd()
+                se._parse( instring, loc )
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+        else:
+            return tokens
+
+    def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ):
+        """
+        Scan the input string for expression matches.  Each match will return the
+        matching tokens, start location, and end location.  May be called with optional
+        C{maxMatches} argument, to clip scanning after 'n' matches are found.  If
+        C{overlap} is specified, then overlapping matches will be reported.
+
+        Note that the start and end locations are reported relative to the string
+        being parsed.  See L{I{parseString}<parseString>} for more information on parsing
+        strings with embedded tabs.
+
+        Example::
+            source = "sldjf123lsdjjkf345sldkjf879lkjsfd987"
+            print(source)
+            for tokens,start,end in Word(alphas).scanString(source):
+                print(' '*start + '^'*(end-start))
+                print(' '*start + tokens[0])
+        
+        prints::
+        
+            sldjf123lsdjjkf345sldkjf879lkjsfd987
+            ^^^^^
+            sldjf
+                    ^^^^^^^
+                    lsdjjkf
+                              ^^^^^^
+                              sldkjf
+                                       ^^^^^^
+                                       lkjsfd
+        """
+        if not self.streamlined:
+            self.streamline()
+        for e in self.ignoreExprs:
+            e.streamline()
+
+        if not self.keepTabs:
+            instring = _ustr(instring).expandtabs()
+        instrlen = len(instring)
+        loc = 0
+        preparseFn = self.preParse
+        parseFn = self._parse
+        ParserElement.resetCache()
+        matches = 0
+        try:
+            while loc <= instrlen and matches < maxMatches:
+                try:
+                    preloc = preparseFn( instring, loc )
+                    nextLoc,tokens = parseFn( instring, preloc, callPreParse=False )
+                except ParseException:
+                    loc = preloc+1
+                else:
+                    if nextLoc > loc:
+                        matches += 1
+                        yield tokens, preloc, nextLoc
+                        if overlap:
+                            nextloc = preparseFn( instring, loc )
+                            if nextloc > loc:
+                                loc = nextLoc
+                            else:
+                                loc += 1
+                        else:
+                            loc = nextLoc
+                    else:
+                        loc = preloc+1
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def transformString( self, instring ):
+        """
+        Extension to C{L{scanString}}, to modify matching text with modified tokens that may
+        be returned from a parse action.  To use C{transformString}, define a grammar and
+        attach a parse action to it that modifies the returned token list.
+        Invoking C{transformString()} on a target string will then scan for matches,
+        and replace the matched text patterns according to the logic in the parse
+        action.  C{transformString()} returns the resulting transformed string.
+        
+        Example::
+            wd = Word(alphas)
+            wd.setParseAction(lambda toks: toks[0].title())
+            
+            print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york."))
+        Prints::
+            Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York.
+        """
+        out = []
+        lastE = 0
+        # force preservation of <TAB>s, to minimize unwanted transformation of string, and to
+        # keep string locs straight between transformString and scanString
+        self.keepTabs = True
+        try:
+            for t,s,e in self.scanString( instring ):
+                out.append( instring[lastE:s] )
+                if t:
+                    if isinstance(t,ParseResults):
+                        out += t.asList()
+                    elif isinstance(t,list):
+                        out += t
+                    else:
+                        out.append(t)
+                lastE = e
+            out.append(instring[lastE:])
+            out = [o for o in out if o]
+            return "".join(map(_ustr,_flatten(out)))
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def searchString( self, instring, maxMatches=_MAX_INT ):
+        """
+        Another extension to C{L{scanString}}, simplifying the access to the tokens found
+        to match the given parse expression.  May be called with optional
+        C{maxMatches} argument, to clip searching after 'n' matches are found.
+        
+        Example::
+            # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters
+            cap_word = Word(alphas.upper(), alphas.lower())
+            
+            print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))
+        prints::
+            ['More', 'Iron', 'Lead', 'Gold', 'I']
+        """
+        try:
+            return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ])
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False):
+        """
+        Generator method to split a string using the given expression as a separator.
+        May be called with optional C{maxsplit} argument, to limit the number of splits;
+        and the optional C{includeSeparators} argument (default=C{False}), if the separating
+        matching text should be included in the split results.
+        
+        Example::        
+            punc = oneOf(list(".,;:/-!?"))
+            print(list(punc.split("This, this?, this sentence, is badly punctuated!")))
+        prints::
+            ['This', ' this', '', ' this sentence', ' is badly punctuated', '']
+        """
+        splits = 0
+        last = 0
+        for t,s,e in self.scanString(instring, maxMatches=maxsplit):
+            yield instring[last:s]
+            if includeSeparators:
+                yield t[0]
+            last = e
+        yield instring[last:]
+
+    def __add__(self, other ):
+        """
+        Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement
+        converts them to L{Literal}s by default.
+        
+        Example::
+            greet = Word(alphas) + "," + Word(alphas) + "!"
+            hello = "Hello, World!"
+            print (hello, "->", greet.parseString(hello))
+        Prints::
+            Hello, World! -> ['Hello', ',', 'World', '!']
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return And( [ self, other ] )
+
+    def __radd__(self, other ):
+        """
+        Implementation of + operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other + self
+
+    def __sub__(self, other):
+        """
+        Implementation of - operator, returns C{L{And}} with error stop
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return And( [ self, And._ErrorStop(), other ] )
+
+    def __rsub__(self, other ):
+        """
+        Implementation of - operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other - self
+
+    def __mul__(self,other):
+        """
+        Implementation of * operator, allows use of C{expr * 3} in place of
+        C{expr + expr + expr}.  Expressions may also me multiplied by a 2-integer
+        tuple, similar to C{{min,max}} multipliers in regular expressions.  Tuples
+        may also include C{None} as in:
+         - C{expr*(n,None)} or C{expr*(n,)} is equivalent
+              to C{expr*n + L{ZeroOrMore}(expr)}
+              (read as "at least n instances of C{expr}")
+         - C{expr*(None,n)} is equivalent to C{expr*(0,n)}
+              (read as "0 to n instances of C{expr}")
+         - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)}
+         - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)}
+
+        Note that C{expr*(None,n)} does not raise an exception if
+        more than n exprs exist in the input stream; that is,
+        C{expr*(None,n)} does not enforce a maximum number of expr
+        occurrences.  If this behavior is desired, then write
+        C{expr*(None,n) + ~expr}
+        """
+        if isinstance(other,int):
+            minElements, optElements = other,0
+        elif isinstance(other,tuple):
+            other = (other + (None, None))[:2]
+            if other[0] is None:
+                other = (0, other[1])
+            if isinstance(other[0],int) and other[1] is None:
+                if other[0] == 0:
+                    return ZeroOrMore(self)
+                if other[0] == 1:
+                    return OneOrMore(self)
+                else:
+                    return self*other[0] + ZeroOrMore(self)
+            elif isinstance(other[0],int) and isinstance(other[1],int):
+                minElements, optElements = other
+                optElements -= minElements
+            else:
+                raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1]))
+        else:
+            raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other))
+
+        if minElements < 0:
+            raise ValueError("cannot multiply ParserElement by negative value")
+        if optElements < 0:
+            raise ValueError("second tuple value must be greater or equal to first tuple value")
+        if minElements == optElements == 0:
+            raise ValueError("cannot multiply ParserElement by 0 or (0,0)")
+
+        if (optElements):
+            def makeOptionalList(n):
+                if n>1:
+                    return Optional(self + makeOptionalList(n-1))
+                else:
+                    return Optional(self)
+            if minElements:
+                if minElements == 1:
+                    ret = self + makeOptionalList(optElements)
+                else:
+                    ret = And([self]*minElements) + makeOptionalList(optElements)
+            else:
+                ret = makeOptionalList(optElements)
+        else:
+            if minElements == 1:
+                ret = self
+            else:
+                ret = And([self]*minElements)
+        return ret
+
+    def __rmul__(self, other):
+        return self.__mul__(other)
+
+    def __or__(self, other ):
+        """
+        Implementation of | operator - returns C{L{MatchFirst}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return MatchFirst( [ self, other ] )
+
+    def __ror__(self, other ):
+        """
+        Implementation of | operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other | self
+
+    def __xor__(self, other ):
+        """
+        Implementation of ^ operator - returns C{L{Or}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return Or( [ self, other ] )
+
+    def __rxor__(self, other ):
+        """
+        Implementation of ^ operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other ^ self
+
+    def __and__(self, other ):
+        """
+        Implementation of & operator - returns C{L{Each}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return Each( [ self, other ] )
+
+    def __rand__(self, other ):
+        """
+        Implementation of & operator when left operand is not a C{L{ParserElement}}
+        """
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        if not isinstance( other, ParserElement ):
+            warnings.warn("Cannot combine element of type %s with ParserElement" % type(other),
+                    SyntaxWarning, stacklevel=2)
+            return None
+        return other & self
+
+    def __invert__( self ):
+        """
+        Implementation of ~ operator - returns C{L{NotAny}}
+        """
+        return NotAny( self )
+
+    def __call__(self, name=None):
+        """
+        Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}.
+        
+        If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be
+        passed as C{True}.
+           
+        If C{name} is omitted, same as calling C{L{copy}}.
+
+        Example::
+            # these are equivalent
+            userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno")
+            userdata = Word(alphas)("name") + Word(nums+"-")("socsecno")             
+        """
+        if name is not None:
+            return self.setResultsName(name)
+        else:
+            return self.copy()
+
+    def suppress( self ):
+        """
+        Suppresses the output of this C{ParserElement}; useful to keep punctuation from
+        cluttering up returned output.
+        """
+        return Suppress( self )
+
+    def leaveWhitespace( self ):
+        """
+        Disables the skipping of whitespace before matching the characters in the
+        C{ParserElement}'s defined pattern.  This is normally only used internally by
+        the pyparsing module, but may be needed in some whitespace-sensitive grammars.
+        """
+        self.skipWhitespace = False
+        return self
+
+    def setWhitespaceChars( self, chars ):
+        """
+        Overrides the default whitespace chars
+        """
+        self.skipWhitespace = True
+        self.whiteChars = chars
+        self.copyDefaultWhiteChars = False
+        return self
+
+    def parseWithTabs( self ):
+        """
+        Overrides default behavior to expand C{<TAB>}s to spaces before parsing the input string.
+        Must be called before C{parseString} when the input grammar contains elements that
+        match C{<TAB>} characters.
+        """
+        self.keepTabs = True
+        return self
+
+    def ignore( self, other ):
+        """
+        Define expression to be ignored (e.g., comments) while doing pattern
+        matching; may be called repeatedly, to define multiple comment or other
+        ignorable patterns.
+        
+        Example::
+            patt = OneOrMore(Word(alphas))
+            patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj']
+            
+            patt.ignore(cStyleComment)
+            patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd']
+        """
+        if isinstance(other, basestring):
+            other = Suppress(other)
+
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                self.ignoreExprs.append(other)
+        else:
+            self.ignoreExprs.append( Suppress( other.copy() ) )
+        return self
+
+    def setDebugActions( self, startAction, successAction, exceptionAction ):
+        """
+        Enable display of debugging messages while doing pattern matching.
+        """
+        self.debugActions = (startAction or _defaultStartDebugAction,
+                             successAction or _defaultSuccessDebugAction,
+                             exceptionAction or _defaultExceptionDebugAction)
+        self.debug = True
+        return self
+
+    def setDebug( self, flag=True ):
+        """
+        Enable display of debugging messages while doing pattern matching.
+        Set C{flag} to True to enable, False to disable.
+
+        Example::
+            wd = Word(alphas).setName("alphaword")
+            integer = Word(nums).setName("numword")
+            term = wd | integer
+            
+            # turn on debugging for wd
+            wd.setDebug()
+
+            OneOrMore(term).parseString("abc 123 xyz 890")
+        
+        prints::
+            Match alphaword at loc 0(1,1)
+            Matched alphaword -> ['abc']
+            Match alphaword at loc 3(1,4)
+            Exception raised:Expected alphaword (at char 4), (line:1, col:5)
+            Match alphaword at loc 7(1,8)
+            Matched alphaword -> ['xyz']
+            Match alphaword at loc 11(1,12)
+            Exception raised:Expected alphaword (at char 12), (line:1, col:13)
+            Match alphaword at loc 15(1,16)
+            Exception raised:Expected alphaword (at char 15), (line:1, col:16)
+
+        The output shown is that produced by the default debug actions - custom debug actions can be
+        specified using L{setDebugActions}. Prior to attempting
+        to match the C{wd} expression, the debugging message C{"Match <exprname> at loc <n>(<line>,<col>)"}
+        is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"}
+        message is shown. Also note the use of L{setName} to assign a human-readable name to the expression,
+        which makes debugging and exception messages easier to understand - for instance, the default
+        name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}.
+        """
+        if flag:
+            self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction )
+        else:
+            self.debug = False
+        return self
+
+    def __str__( self ):
+        return self.name
+
+    def __repr__( self ):
+        return _ustr(self)
+
+    def streamline( self ):
+        self.streamlined = True
+        self.strRepr = None
+        return self
+
+    def checkRecursion( self, parseElementList ):
+        pass
+
+    def validate( self, validateTrace=[] ):
+        """
+        Check defined expressions for valid structure, check for infinite recursive definitions.
+        """
+        self.checkRecursion( [] )
+
+    def parseFile( self, file_or_filename, parseAll=False ):
+        """
+        Execute the parse expression on the given file or filename.
+        If a filename is specified (instead of a file object),
+        the entire file is opened, read, and closed before parsing.
+        """
+        try:
+            file_contents = file_or_filename.read()
+        except AttributeError:
+            with open(file_or_filename, "r") as f:
+                file_contents = f.read()
+        try:
+            return self.parseString(file_contents, parseAll)
+        except ParseBaseException as exc:
+            if ParserElement.verbose_stacktrace:
+                raise
+            else:
+                # catch and re-raise exception from here, clears out pyparsing internal stack trace
+                raise exc
+
+    def __eq__(self,other):
+        if isinstance(other, ParserElement):
+            return self is other or vars(self) == vars(other)
+        elif isinstance(other, basestring):
+            return self.matches(other)
+        else:
+            return super(ParserElement,self)==other
+
+    def __ne__(self,other):
+        return not (self == other)
+
+    def __hash__(self):
+        return hash(id(self))
+
+    def __req__(self,other):
+        return self == other
+
+    def __rne__(self,other):
+        return not (self == other)
+
+    def matches(self, testString, parseAll=True):
+        """
+        Method for quick testing of a parser against a test string. Good for simple 
+        inline microtests of sub expressions while building up larger parser.
+           
+        Parameters:
+         - testString - to test against this expression for a match
+         - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests
+            
+        Example::
+            expr = Word(nums)
+            assert expr.matches("100")
+        """
+        try:
+            self.parseString(_ustr(testString), parseAll=parseAll)
+            return True
+        except ParseBaseException:
+            return False
+                
+    def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False):
+        """
+        Execute the parse expression on a series of test strings, showing each
+        test, the parsed results or where the parse failed. Quick and easy way to
+        run a parse expression against a list of sample strings.
+           
+        Parameters:
+         - tests - a list of separate test strings, or a multiline string of test strings
+         - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests           
+         - comment - (default=C{'#'}) - expression for indicating embedded comments in the test 
+              string; pass None to disable comment filtering
+         - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline;
+              if False, only dump nested list
+         - printResults - (default=C{True}) prints test output to stdout
+         - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing
+
+        Returns: a (success, results) tuple, where success indicates that all tests succeeded
+        (or failed if C{failureTests} is True), and the results contain a list of lines of each 
+        test's output
+        
+        Example::
+            number_expr = pyparsing_common.number.copy()
+
+            result = number_expr.runTests('''
+                # unsigned integer
+                100
+                # negative integer
+                -100
+                # float with scientific notation
+                6.02e23
+                # integer with scientific notation
+                1e-12
+                ''')
+            print("Success" if result[0] else "Failed!")
+
+            result = number_expr.runTests('''
+                # stray character
+                100Z
+                # missing leading digit before '.'
+                -.100
+                # too many '.'
+                3.14.159
+                ''', failureTests=True)
+            print("Success" if result[0] else "Failed!")
+        prints::
+            # unsigned integer
+            100
+            [100]
+
+            # negative integer
+            -100
+            [-100]
+
+            # float with scientific notation
+            6.02e23
+            [6.02e+23]
+
+            # integer with scientific notation
+            1e-12
+            [1e-12]
+
+            Success
+            
+            # stray character
+            100Z
+               ^
+            FAIL: Expected end of text (at char 3), (line:1, col:4)
+
+            # missing leading digit before '.'
+            -.100
+            ^
+            FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1)
+
+            # too many '.'
+            3.14.159
+                ^
+            FAIL: Expected end of text (at char 4), (line:1, col:5)
+
+            Success
+
+        Each test string must be on a single line. If you want to test a string that spans multiple
+        lines, create a test like this::
+
+            expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines")
+        
+        (Note that this is a raw string literal, you must include the leading 'r'.)
+        """
+        if isinstance(tests, basestring):
+            tests = list(map(str.strip, tests.rstrip().splitlines()))
+        if isinstance(comment, basestring):
+            comment = Literal(comment)
+        allResults = []
+        comments = []
+        success = True
+        for t in tests:
+            if comment is not None and comment.matches(t, False) or comments and not t:
+                comments.append(t)
+                continue
+            if not t:
+                continue
+            out = ['\n'.join(comments), t]
+            comments = []
+            try:
+                t = t.replace(r'\n','\n')
+                result = self.parseString(t, parseAll=parseAll)
+                out.append(result.dump(full=fullDump))
+                success = success and not failureTests
+            except ParseBaseException as pe:
+                fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else ""
+                if '\n' in t:
+                    out.append(line(pe.loc, t))
+                    out.append(' '*(col(pe.loc,t)-1) + '^' + fatal)
+                else:
+                    out.append(' '*pe.loc + '^' + fatal)
+                out.append("FAIL: " + str(pe))
+                success = success and failureTests
+                result = pe
+            except Exception as exc:
+                out.append("FAIL-EXCEPTION: " + str(exc))
+                success = success and failureTests
+                result = exc
+
+            if printResults:
+                if fullDump:
+                    out.append('')
+                print('\n'.join(out))
+
+            allResults.append((t, result))
+        
+        return success, allResults
+
+        
+class Token(ParserElement):
+    """
+    Abstract C{ParserElement} subclass, for defining atomic matching patterns.
+    """
+    def __init__( self ):
+        super(Token,self).__init__( savelist=False )
+
+
+class Empty(Token):
+    """
+    An empty token, will always match.
+    """
+    def __init__( self ):
+        super(Empty,self).__init__()
+        self.name = "Empty"
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+
+
+class NoMatch(Token):
+    """
+    A token that will never match.
+    """
+    def __init__( self ):
+        super(NoMatch,self).__init__()
+        self.name = "NoMatch"
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+        self.errmsg = "Unmatchable token"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        raise ParseException(instring, loc, self.errmsg, self)
+
+
+class Literal(Token):
+    """
+    Token to exactly match a specified string.
+    
+    Example::
+        Literal('blah').parseString('blah')  # -> ['blah']
+        Literal('blah').parseString('blahfooblah')  # -> ['blah']
+        Literal('blah').parseString('bla')  # -> Exception: Expected "blah"
+    
+    For case-insensitive matching, use L{CaselessLiteral}.
+    
+    For keyword matching (force word break before and after the matched string),
+    use L{Keyword} or L{CaselessKeyword}.
+    """
+    def __init__( self, matchString ):
+        super(Literal,self).__init__()
+        self.match = matchString
+        self.matchLen = len(matchString)
+        try:
+            self.firstMatchChar = matchString[0]
+        except IndexError:
+            warnings.warn("null string passed to Literal; use Empty() instead",
+                            SyntaxWarning, stacklevel=2)
+            self.__class__ = Empty
+        self.name = '"%s"' % _ustr(self.match)
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = False
+        self.mayIndexError = False
+
+    # Performance tuning: this routine gets called a *lot*
+    # if this is a single character match string  and the first character matches,
+    # short-circuit as quickly as possible, and avoid calling startswith
+    #~ @profile
+    def parseImpl( self, instring, loc, doActions=True ):
+        if (instring[loc] == self.firstMatchChar and
+            (self.matchLen==1 or instring.startswith(self.match,loc)) ):
+            return loc+self.matchLen, self.match
+        raise ParseException(instring, loc, self.errmsg, self)
+_L = Literal
+ParserElement._literalStringClass = Literal
+
+class Keyword(Token):
+    """
+    Token to exactly match a specified string as a keyword, that is, it must be
+    immediately followed by a non-keyword character.  Compare with C{L{Literal}}:
+     - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}.
+     - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'}
+    Accepts two optional constructor arguments in addition to the keyword string:
+     - C{identChars} is a string of characters that would be valid identifier characters,
+          defaulting to all alphanumerics + "_" and "$"
+     - C{caseless} allows case-insensitive matching, default is C{False}.
+       
+    Example::
+        Keyword("start").parseString("start")  # -> ['start']
+        Keyword("start").parseString("starting")  # -> Exception
+
+    For case-insensitive matching, use L{CaselessKeyword}.
+    """
+    DEFAULT_KEYWORD_CHARS = alphanums+"_$"
+
+    def __init__( self, matchString, identChars=None, caseless=False ):
+        super(Keyword,self).__init__()
+        if identChars is None:
+            identChars = Keyword.DEFAULT_KEYWORD_CHARS
+        self.match = matchString
+        self.matchLen = len(matchString)
+        try:
+            self.firstMatchChar = matchString[0]
+        except IndexError:
+            warnings.warn("null string passed to Keyword; use Empty() instead",
+                            SyntaxWarning, stacklevel=2)
+        self.name = '"%s"' % self.match
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = False
+        self.mayIndexError = False
+        self.caseless = caseless
+        if caseless:
+            self.caselessmatch = matchString.upper()
+            identChars = identChars.upper()
+        self.identChars = set(identChars)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.caseless:
+            if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
+                 (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and
+                 (loc == 0 or instring[loc-1].upper() not in self.identChars) ):
+                return loc+self.matchLen, self.match
+        else:
+            if (instring[loc] == self.firstMatchChar and
+                (self.matchLen==1 or instring.startswith(self.match,loc)) and
+                (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and
+                (loc == 0 or instring[loc-1] not in self.identChars) ):
+                return loc+self.matchLen, self.match
+        raise ParseException(instring, loc, self.errmsg, self)
+
+    def copy(self):
+        c = super(Keyword,self).copy()
+        c.identChars = Keyword.DEFAULT_KEYWORD_CHARS
+        return c
+
+    @staticmethod
+    def setDefaultKeywordChars( chars ):
+        """Overrides the default Keyword chars
+        """
+        Keyword.DEFAULT_KEYWORD_CHARS = chars
+
+class CaselessLiteral(Literal):
+    """
+    Token to match a specified string, ignoring case of letters.
+    Note: the matched results will always be in the case of the given
+    match string, NOT the case of the input text.
+
+    Example::
+        OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD']
+        
+    (Contrast with example for L{CaselessKeyword}.)
+    """
+    def __init__( self, matchString ):
+        super(CaselessLiteral,self).__init__( matchString.upper() )
+        # Preserve the defining literal.
+        self.returnString = matchString
+        self.name = "'%s'" % self.returnString
+        self.errmsg = "Expected " + self.name
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if instring[ loc:loc+self.matchLen ].upper() == self.match:
+            return loc+self.matchLen, self.returnString
+        raise ParseException(instring, loc, self.errmsg, self)
+
+class CaselessKeyword(Keyword):
+    """
+    Caseless version of L{Keyword}.
+
+    Example::
+        OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD']
+        
+    (Contrast with example for L{CaselessLiteral}.)
+    """
+    def __init__( self, matchString, identChars=None ):
+        super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True )
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
+             (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ):
+            return loc+self.matchLen, self.match
+        raise ParseException(instring, loc, self.errmsg, self)
+
+class CloseMatch(Token):
+    """
+    A variation on L{Literal} which matches "close" matches, that is, 
+    strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters:
+     - C{match_string} - string to be matched
+     - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match
+    
+    The results from a successful parse will contain the matched text from the input string and the following named results:
+     - C{mismatches} - a list of the positions within the match_string where mismatches were found
+     - C{original} - the original match_string used to compare against the input string
+    
+    If C{mismatches} is an empty list, then the match was an exact match.
+    
+    Example::
+        patt = CloseMatch("ATCATCGAATGGA")
+        patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']})
+        patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1)
+
+        # exact match
+        patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']})
+
+        # close match allowing up to 2 mismatches
+        patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2)
+        patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']})
+    """
+    def __init__(self, match_string, maxMismatches=1):
+        super(CloseMatch,self).__init__()
+        self.name = match_string
+        self.match_string = match_string
+        self.maxMismatches = maxMismatches
+        self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches)
+        self.mayIndexError = False
+        self.mayReturnEmpty = False
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        start = loc
+        instrlen = len(instring)
+        maxloc = start + len(self.match_string)
+
+        if maxloc <= instrlen:
+            match_string = self.match_string
+            match_stringloc = 0
+            mismatches = []
+            maxMismatches = self.maxMismatches
+
+            for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)):
+                src,mat = s_m
+                if src != mat:
+                    mismatches.append(match_stringloc)
+                    if len(mismatches) > maxMismatches:
+                        break
+            else:
+                loc = match_stringloc + 1
+                results = ParseResults([instring[start:loc]])
+                results['original'] = self.match_string
+                results['mismatches'] = mismatches
+                return loc, results
+
+        raise ParseException(instring, loc, self.errmsg, self)
+
+
+class Word(Token):
+    """
+    Token for matching words composed of allowed character sets.
+    Defined with string containing all allowed initial characters,
+    an optional string containing allowed body characters (if omitted,
+    defaults to the initial character set), and an optional minimum,
+    maximum, and/or exact length.  The default value for C{min} is 1 (a
+    minimum value < 1 is not valid); the default values for C{max} and C{exact}
+    are 0, meaning no maximum or exact length restriction. An optional
+    C{excludeChars} parameter can list characters that might be found in 
+    the input C{bodyChars} string; useful to define a word of all printables
+    except for one or two characters, for instance.
+    
+    L{srange} is useful for defining custom character set strings for defining 
+    C{Word} expressions, using range notation from regular expression character sets.
+    
+    A common mistake is to use C{Word} to match a specific literal string, as in 
+    C{Word("Address")}. Remember that C{Word} uses the string argument to define
+    I{sets} of matchable characters. This expression would match "Add", "AAA",
+    "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'.
+    To match an exact literal string, use L{Literal} or L{Keyword}.
+
+    pyparsing includes helper strings for building Words:
+     - L{alphas}
+     - L{nums}
+     - L{alphanums}
+     - L{hexnums}
+     - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.)
+     - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.)
+     - L{printables} (any non-whitespace character)
+
+    Example::
+        # a word composed of digits
+        integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9"))
+        
+        # a word with a leading capital, and zero or more lowercase
+        capital_word = Word(alphas.upper(), alphas.lower())
+
+        # hostnames are alphanumeric, with leading alpha, and '-'
+        hostname = Word(alphas, alphanums+'-')
+        
+        # roman numeral (not a strict parser, accepts invalid mix of characters)
+        roman = Word("IVXLCDM")
+        
+        # any string of non-whitespace characters, except for ','
+        csv_value = Word(printables, excludeChars=",")
+    """
+    def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ):
+        super(Word,self).__init__()
+        if excludeChars:
+            initChars = ''.join(c for c in initChars if c not in excludeChars)
+            if bodyChars:
+                bodyChars = ''.join(c for c in bodyChars if c not in excludeChars)
+        self.initCharsOrig = initChars
+        self.initChars = set(initChars)
+        if bodyChars :
+            self.bodyCharsOrig = bodyChars
+            self.bodyChars = set(bodyChars)
+        else:
+            self.bodyCharsOrig = initChars
+            self.bodyChars = set(initChars)
+
+        self.maxSpecified = max > 0
+
+        if min < 1:
+            raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted")
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayIndexError = False
+        self.asKeyword = asKeyword
+
+        if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0):
+            if self.bodyCharsOrig == self.initCharsOrig:
+                self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig)
+            elif len(self.initCharsOrig) == 1:
+                self.reString = "%s[%s]*" % \
+                                      (re.escape(self.initCharsOrig),
+                                      _escapeRegexRangeChars(self.bodyCharsOrig),)
+            else:
+                self.reString = "[%s][%s]*" % \
+                                      (_escapeRegexRangeChars(self.initCharsOrig),
+                                      _escapeRegexRangeChars(self.bodyCharsOrig),)
+            if self.asKeyword:
+                self.reString = r"\b"+self.reString+r"\b"
+            try:
+                self.re = re.compile( self.reString )
+            except Exception:
+                self.re = None
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.re:
+            result = self.re.match(instring,loc)
+            if not result:
+                raise ParseException(instring, loc, self.errmsg, self)
+
+            loc = result.end()
+            return loc, result.group()
+
+        if not(instring[ loc ] in self.initChars):
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        start = loc
+        loc += 1
+        instrlen = len(instring)
+        bodychars = self.bodyChars
+        maxloc = start + self.maxLen
+        maxloc = min( maxloc, instrlen )
+        while loc < maxloc and instring[loc] in bodychars:
+            loc += 1
+
+        throwException = False
+        if loc - start < self.minLen:
+            throwException = True
+        if self.maxSpecified and loc < instrlen and instring[loc] in bodychars:
+            throwException = True
+        if self.asKeyword:
+            if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars):
+                throwException = True
+
+        if throwException:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        return loc, instring[start:loc]
+
+    def __str__( self ):
+        try:
+            return super(Word,self).__str__()
+        except Exception:
+            pass
+
+
+        if self.strRepr is None:
+
+            def charsAsStr(s):
+                if len(s)>4:
+                    return s[:4]+"..."
+                else:
+                    return s
+
+            if ( self.initCharsOrig != self.bodyCharsOrig ):
+                self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) )
+            else:
+                self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig)
+
+        return self.strRepr
+
+
+class Regex(Token):
+    """
+    Token for matching strings that match a given regular expression.
+    Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module.
+    If the given regex contains named groups (defined using C{(?P<name>...)}), these will be preserved as 
+    named parse results.
+
+    Example::
+        realnum = Regex(r"[+-]?\d+\.\d*")
+        date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)')
+        # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression
+        roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})")
+    """
+    compiledREtype = type(re.compile("[A-Z]"))
+    def __init__( self, pattern, flags=0):
+        """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags."""
+        super(Regex,self).__init__()
+
+        if isinstance(pattern, basestring):
+            if not pattern:
+                warnings.warn("null string passed to Regex; use Empty() instead",
+                        SyntaxWarning, stacklevel=2)
+
+            self.pattern = pattern
+            self.flags = flags
+
+            try:
+                self.re = re.compile(self.pattern, self.flags)
+                self.reString = self.pattern
+            except sre_constants.error:
+                warnings.warn("invalid pattern (%s) passed to Regex" % pattern,
+                    SyntaxWarning, stacklevel=2)
+                raise
+
+        elif isinstance(pattern, Regex.compiledREtype):
+            self.re = pattern
+            self.pattern = \
+            self.reString = str(pattern)
+            self.flags = flags
+            
+        else:
+            raise ValueError("Regex may only be constructed with a string or a compiled RE object")
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayIndexError = False
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        result = self.re.match(instring,loc)
+        if not result:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        loc = result.end()
+        d = result.groupdict()
+        ret = ParseResults(result.group())
+        if d:
+            for k in d:
+                ret[k] = d[k]
+        return loc,ret
+
+    def __str__( self ):
+        try:
+            return super(Regex,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "Re:(%s)" % repr(self.pattern)
+
+        return self.strRepr
+
+
+class QuotedString(Token):
+    r"""
+    Token for matching strings that are delimited by quoting characters.
+    
+    Defined with the following parameters:
+        - quoteChar - string of one or more characters defining the quote delimiting string
+        - escChar - character to escape quotes, typically backslash (default=C{None})
+        - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None})
+        - multiline - boolean indicating whether quotes can span multiple lines (default=C{False})
+        - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True})
+        - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar)
+        - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True})
+
+    Example::
+        qs = QuotedString('"')
+        print(qs.searchString('lsjdf "This is the quote" sldjf'))
+        complex_qs = QuotedString('{{', endQuoteChar='}}')
+        print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf'))
+        sql_qs = QuotedString('"', escQuote='""')
+        print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf'))
+    prints::
+        [['This is the quote']]
+        [['This is the "quote"']]
+        [['This is the quote with "embedded" quotes']]
+    """
+    def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True):
+        super(QuotedString,self).__init__()
+
+        # remove white space from quote chars - wont work anyway
+        quoteChar = quoteChar.strip()
+        if not quoteChar:
+            warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
+            raise SyntaxError()
+
+        if endQuoteChar is None:
+            endQuoteChar = quoteChar
+        else:
+            endQuoteChar = endQuoteChar.strip()
+            if not endQuoteChar:
+                warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
+                raise SyntaxError()
+
+        self.quoteChar = quoteChar
+        self.quoteCharLen = len(quoteChar)
+        self.firstQuoteChar = quoteChar[0]
+        self.endQuoteChar = endQuoteChar
+        self.endQuoteCharLen = len(endQuoteChar)
+        self.escChar = escChar
+        self.escQuote = escQuote
+        self.unquoteResults = unquoteResults
+        self.convertWhitespaceEscapes = convertWhitespaceEscapes
+
+        if multiline:
+            self.flags = re.MULTILINE | re.DOTALL
+            self.pattern = r'%s(?:[^%s%s]' % \
+                ( re.escape(self.quoteChar),
+                  _escapeRegexRangeChars(self.endQuoteChar[0]),
+                  (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
+        else:
+            self.flags = 0
+            self.pattern = r'%s(?:[^%s\n\r%s]' % \
+                ( re.escape(self.quoteChar),
+                  _escapeRegexRangeChars(self.endQuoteChar[0]),
+                  (escChar is not None and _escapeRegexRangeChars(escChar) or '') )
+        if len(self.endQuoteChar) > 1:
+            self.pattern += (
+                '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]),
+                                               _escapeRegexRangeChars(self.endQuoteChar[i]))
+                                    for i in range(len(self.endQuoteChar)-1,0,-1)) + ')'
+                )
+        if escQuote:
+            self.pattern += (r'|(?:%s)' % re.escape(escQuote))
+        if escChar:
+            self.pattern += (r'|(?:%s.)' % re.escape(escChar))
+            self.escCharReplacePattern = re.escape(self.escChar)+"(.)"
+        self.pattern += (r')*%s' % re.escape(self.endQuoteChar))
+
+        try:
+            self.re = re.compile(self.pattern, self.flags)
+            self.reString = self.pattern
+        except sre_constants.error:
+            warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern,
+                SyntaxWarning, stacklevel=2)
+            raise
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayIndexError = False
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None
+        if not result:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        loc = result.end()
+        ret = result.group()
+
+        if self.unquoteResults:
+
+            # strip off quotes
+            ret = ret[self.quoteCharLen:-self.endQuoteCharLen]
+
+            if isinstance(ret,basestring):
+                # replace escaped whitespace
+                if '\\' in ret and self.convertWhitespaceEscapes:
+                    ws_map = {
+                        r'\t' : '\t',
+                        r'\n' : '\n',
+                        r'\f' : '\f',
+                        r'\r' : '\r',
+                    }
+                    for wslit,wschar in ws_map.items():
+                        ret = ret.replace(wslit, wschar)
+
+                # replace escaped characters
+                if self.escChar:
+                    ret = re.sub(self.escCharReplacePattern,"\g<1>",ret)
+
+                # replace escaped quotes
+                if self.escQuote:
+                    ret = ret.replace(self.escQuote, self.endQuoteChar)
+
+        return loc, ret
+
+    def __str__( self ):
+        try:
+            return super(QuotedString,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar)
+
+        return self.strRepr
+
+
+class CharsNotIn(Token):
+    """
+    Token for matching words composed of characters I{not} in a given set (will
+    include whitespace in matched characters if not listed in the provided exclusion set - see example).
+    Defined with string containing all disallowed characters, and an optional
+    minimum, maximum, and/or exact length.  The default value for C{min} is 1 (a
+    minimum value < 1 is not valid); the default values for C{max} and C{exact}
+    are 0, meaning no maximum or exact length restriction.
+
+    Example::
+        # define a comma-separated-value as anything that is not a ','
+        csv_value = CharsNotIn(',')
+        print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213"))
+    prints::
+        ['dkls', 'lsdkjf', 's12 34', '@!#', '213']
+    """
+    def __init__( self, notChars, min=1, max=0, exact=0 ):
+        super(CharsNotIn,self).__init__()
+        self.skipWhitespace = False
+        self.notChars = notChars
+
+        if min < 1:
+            raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted")
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+        self.name = _ustr(self)
+        self.errmsg = "Expected " + self.name
+        self.mayReturnEmpty = ( self.minLen == 0 )
+        self.mayIndexError = False
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if instring[loc] in self.notChars:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        start = loc
+        loc += 1
+        notchars = self.notChars
+        maxlen = min( start+self.maxLen, len(instring) )
+        while loc < maxlen and \
+              (instring[loc] not in notchars):
+            loc += 1
+
+        if loc - start < self.minLen:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        return loc, instring[start:loc]
+
+    def __str__( self ):
+        try:
+            return super(CharsNotIn, self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            if len(self.notChars) > 4:
+                self.strRepr = "!W:(%s...)" % self.notChars[:4]
+            else:
+                self.strRepr = "!W:(%s)" % self.notChars
+
+        return self.strRepr
+
+class White(Token):
+    """
+    Special matching class for matching whitespace.  Normally, whitespace is ignored
+    by pyparsing grammars.  This class is included when some whitespace structures
+    are significant.  Define with a string containing the whitespace characters to be
+    matched; default is C{" \\t\\r\\n"}.  Also takes optional C{min}, C{max}, and C{exact} arguments,
+    as defined for the C{L{Word}} class.
+    """
+    whiteStrs = {
+        " " : "<SPC>",
+        "\t": "<TAB>",
+        "\n": "<LF>",
+        "\r": "<CR>",
+        "\f": "<FF>",
+        }
+    def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0):
+        super(White,self).__init__()
+        self.matchWhite = ws
+        self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) )
+        #~ self.leaveWhitespace()
+        self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite))
+        self.mayReturnEmpty = True
+        self.errmsg = "Expected " + self.name
+
+        self.minLen = min
+
+        if max > 0:
+            self.maxLen = max
+        else:
+            self.maxLen = _MAX_INT
+
+        if exact > 0:
+            self.maxLen = exact
+            self.minLen = exact
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if not(instring[ loc ] in self.matchWhite):
+            raise ParseException(instring, loc, self.errmsg, self)
+        start = loc
+        loc += 1
+        maxloc = start + self.maxLen
+        maxloc = min( maxloc, len(instring) )
+        while loc < maxloc and instring[loc] in self.matchWhite:
+            loc += 1
+
+        if loc - start < self.minLen:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        return loc, instring[start:loc]
+
+
+class _PositionToken(Token):
+    def __init__( self ):
+        super(_PositionToken,self).__init__()
+        self.name=self.__class__.__name__
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+
+class GoToColumn(_PositionToken):
+    """
+    Token to advance to a specific column of input text; useful for tabular report scraping.
+    """
+    def __init__( self, colno ):
+        super(GoToColumn,self).__init__()
+        self.col = colno
+
+    def preParse( self, instring, loc ):
+        if col(loc,instring) != self.col:
+            instrlen = len(instring)
+            if self.ignoreExprs:
+                loc = self._skipIgnorables( instring, loc )
+            while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col :
+                loc += 1
+        return loc
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        thiscol = col( loc, instring )
+        if thiscol > self.col:
+            raise ParseException( instring, loc, "Text not in expected column", self )
+        newloc = loc + self.col - thiscol
+        ret = instring[ loc: newloc ]
+        return newloc, ret
+
+
+class LineStart(_PositionToken):
+    """
+    Matches if current position is at the beginning of a line within the parse string
+    
+    Example::
+    
+        test = '''\
+        AAA this line
+        AAA and this line
+          AAA but not this one
+        B AAA and definitely not this one
+        '''
+
+        for t in (LineStart() + 'AAA' + restOfLine).searchString(test):
+            print(t)
+    
+    Prints::
+        ['AAA', ' this line']
+        ['AAA', ' and this line']    
+
+    """
+    def __init__( self ):
+        super(LineStart,self).__init__()
+        self.errmsg = "Expected start of line"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if col(loc, instring) == 1:
+            return loc, []
+        raise ParseException(instring, loc, self.errmsg, self)
+
+class LineEnd(_PositionToken):
+    """
+    Matches if current position is at the end of a line within the parse string
+    """
+    def __init__( self ):
+        super(LineEnd,self).__init__()
+        self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") )
+        self.errmsg = "Expected end of line"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc<len(instring):
+            if instring[loc] == "\n":
+                return loc+1, "\n"
+            else:
+                raise ParseException(instring, loc, self.errmsg, self)
+        elif loc == len(instring):
+            return loc+1, []
+        else:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+class StringStart(_PositionToken):
+    """
+    Matches if current position is at the beginning of the parse string
+    """
+    def __init__( self ):
+        super(StringStart,self).__init__()
+        self.errmsg = "Expected start of text"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc != 0:
+            # see if entire string up to here is just whitespace and ignoreables
+            if loc != self.preParse( instring, 0 ):
+                raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+class StringEnd(_PositionToken):
+    """
+    Matches if current position is at the end of the parse string
+    """
+    def __init__( self ):
+        super(StringEnd,self).__init__()
+        self.errmsg = "Expected end of text"
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if loc < len(instring):
+            raise ParseException(instring, loc, self.errmsg, self)
+        elif loc == len(instring):
+            return loc+1, []
+        elif loc > len(instring):
+            return loc, []
+        else:
+            raise ParseException(instring, loc, self.errmsg, self)
+
+class WordStart(_PositionToken):
+    """
+    Matches if the current position is at the beginning of a Word, and
+    is not preceded by any character in a given set of C{wordChars}
+    (default=C{printables}). To emulate the C{\b} behavior of regular expressions,
+    use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of
+    the string being parsed, or at the beginning of a line.
+    """
+    def __init__(self, wordChars = printables):
+        super(WordStart,self).__init__()
+        self.wordChars = set(wordChars)
+        self.errmsg = "Not at the start of a word"
+
+    def parseImpl(self, instring, loc, doActions=True ):
+        if loc != 0:
+            if (instring[loc-1] in self.wordChars or
+                instring[loc] not in self.wordChars):
+                raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+class WordEnd(_PositionToken):
+    """
+    Matches if the current position is at the end of a Word, and
+    is not followed by any character in a given set of C{wordChars}
+    (default=C{printables}). To emulate the C{\b} behavior of regular expressions,
+    use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of
+    the string being parsed, or at the end of a line.
+    """
+    def __init__(self, wordChars = printables):
+        super(WordEnd,self).__init__()
+        self.wordChars = set(wordChars)
+        self.skipWhitespace = False
+        self.errmsg = "Not at the end of a word"
+
+    def parseImpl(self, instring, loc, doActions=True ):
+        instrlen = len(instring)
+        if instrlen>0 and loc<instrlen:
+            if (instring[loc] in self.wordChars or
+                instring[loc-1] not in self.wordChars):
+                raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+
+class ParseExpression(ParserElement):
+    """
+    Abstract subclass of ParserElement, for combining and post-processing parsed tokens.
+    """
+    def __init__( self, exprs, savelist = False ):
+        super(ParseExpression,self).__init__(savelist)
+        if isinstance( exprs, _generatorType ):
+            exprs = list(exprs)
+
+        if isinstance( exprs, basestring ):
+            self.exprs = [ ParserElement._literalStringClass( exprs ) ]
+        elif isinstance( exprs, collections.Iterable ):
+            exprs = list(exprs)
+            # if sequence of strings provided, wrap with Literal
+            if all(isinstance(expr, basestring) for expr in exprs):
+                exprs = map(ParserElement._literalStringClass, exprs)
+            self.exprs = list(exprs)
+        else:
+            try:
+                self.exprs = list( exprs )
+            except TypeError:
+                self.exprs = [ exprs ]
+        self.callPreparse = False
+
+    def __getitem__( self, i ):
+        return self.exprs[i]
+
+    def append( self, other ):
+        self.exprs.append( other )
+        self.strRepr = None
+        return self
+
+    def leaveWhitespace( self ):
+        """Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on
+           all contained expressions."""
+        self.skipWhitespace = False
+        self.exprs = [ e.copy() for e in self.exprs ]
+        for e in self.exprs:
+            e.leaveWhitespace()
+        return self
+
+    def ignore( self, other ):
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                super( ParseExpression, self).ignore( other )
+                for e in self.exprs:
+                    e.ignore( self.ignoreExprs[-1] )
+        else:
+            super( ParseExpression, self).ignore( other )
+            for e in self.exprs:
+                e.ignore( self.ignoreExprs[-1] )
+        return self
+
+    def __str__( self ):
+        try:
+            return super(ParseExpression,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None:
+            self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) )
+        return self.strRepr
+
+    def streamline( self ):
+        super(ParseExpression,self).streamline()
+
+        for e in self.exprs:
+            e.streamline()
+
+        # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d )
+        # but only if there are no parse actions or resultsNames on the nested And's
+        # (likewise for Or's and MatchFirst's)
+        if ( len(self.exprs) == 2 ):
+            other = self.exprs[0]
+            if ( isinstance( other, self.__class__ ) and
+                  not(other.parseAction) and
+                  other.resultsName is None and
+                  not other.debug ):
+                self.exprs = other.exprs[:] + [ self.exprs[1] ]
+                self.strRepr = None
+                self.mayReturnEmpty |= other.mayReturnEmpty
+                self.mayIndexError  |= other.mayIndexError
+
+            other = self.exprs[-1]
+            if ( isinstance( other, self.__class__ ) and
+                  not(other.parseAction) and
+                  other.resultsName is None and
+                  not other.debug ):
+                self.exprs = self.exprs[:-1] + other.exprs[:]
+                self.strRepr = None
+                self.mayReturnEmpty |= other.mayReturnEmpty
+                self.mayIndexError  |= other.mayIndexError
+
+        self.errmsg = "Expected " + _ustr(self)
+        
+        return self
+
+    def setResultsName( self, name, listAllMatches=False ):
+        ret = super(ParseExpression,self).setResultsName(name,listAllMatches)
+        return ret
+
+    def validate( self, validateTrace=[] ):
+        tmp = validateTrace[:]+[self]
+        for e in self.exprs:
+            e.validate(tmp)
+        self.checkRecursion( [] )
+        
+    def copy(self):
+        ret = super(ParseExpression,self).copy()
+        ret.exprs = [e.copy() for e in self.exprs]
+        return ret
+
+class And(ParseExpression):
+    """
+    Requires all given C{ParseExpression}s to be found in the given order.
+    Expressions may be separated by whitespace.
+    May be constructed using the C{'+'} operator.
+    May also be constructed using the C{'-'} operator, which will suppress backtracking.
+
+    Example::
+        integer = Word(nums)
+        name_expr = OneOrMore(Word(alphas))
+
+        expr = And([integer("id"),name_expr("name"),integer("age")])
+        # more easily written as:
+        expr = integer("id") + name_expr("name") + integer("age")
+    """
+
+    class _ErrorStop(Empty):
+        def __init__(self, *args, **kwargs):
+            super(And._ErrorStop,self).__init__(*args, **kwargs)
+            self.name = '-'
+            self.leaveWhitespace()
+
+    def __init__( self, exprs, savelist = True ):
+        super(And,self).__init__(exprs, savelist)
+        self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
+        self.setWhitespaceChars( self.exprs[0].whiteChars )
+        self.skipWhitespace = self.exprs[0].skipWhitespace
+        self.callPreparse = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        # pass False as last arg to _parse for first element, since we already
+        # pre-parsed the string as part of our And pre-parsing
+        loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False )
+        errorStop = False
+        for e in self.exprs[1:]:
+            if isinstance(e, And._ErrorStop):
+                errorStop = True
+                continue
+            if errorStop:
+                try:
+                    loc, exprtokens = e._parse( instring, loc, doActions )
+                except ParseSyntaxException:
+                    raise
+                except ParseBaseException as pe:
+                    pe.__traceback__ = None
+                    raise ParseSyntaxException._from_exception(pe)
+                except IndexError:
+                    raise ParseSyntaxException(instring, len(instring), self.errmsg, self)
+            else:
+                loc, exprtokens = e._parse( instring, loc, doActions )
+            if exprtokens or exprtokens.haskeys():
+                resultlist += exprtokens
+        return loc, resultlist
+
+    def __iadd__(self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        return self.append( other ) #And( [ self, other ] )
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+            if not e.mayReturnEmpty:
+                break
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+
+class Or(ParseExpression):
+    """
+    Requires that at least one C{ParseExpression} is found.
+    If two expressions match, the expression that matches the longest string will be used.
+    May be constructed using the C{'^'} operator.
+
+    Example::
+        # construct Or using '^' operator
+        
+        number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums))
+        print(number.searchString("123 3.1416 789"))
+    prints::
+        [['123'], ['3.1416'], ['789']]
+    """
+    def __init__( self, exprs, savelist = False ):
+        super(Or,self).__init__(exprs, savelist)
+        if self.exprs:
+            self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs)
+        else:
+            self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        maxExcLoc = -1
+        maxException = None
+        matches = []
+        for e in self.exprs:
+            try:
+                loc2 = e.tryParse( instring, loc )
+            except ParseException as err:
+                err.__traceback__ = None
+                if err.loc > maxExcLoc:
+                    maxException = err
+                    maxExcLoc = err.loc
+            except IndexError:
+                if len(instring) > maxExcLoc:
+                    maxException = ParseException(instring,len(instring),e.errmsg,self)
+                    maxExcLoc = len(instring)
+            else:
+                # save match among all matches, to retry longest to shortest
+                matches.append((loc2, e))
+
+        if matches:
+            matches.sort(key=lambda x: -x[0])
+            for _,e in matches:
+                try:
+                    return e._parse( instring, loc, doActions )
+                except ParseException as err:
+                    err.__traceback__ = None
+                    if err.loc > maxExcLoc:
+                        maxException = err
+                        maxExcLoc = err.loc
+
+        if maxException is not None:
+            maxException.msg = self.errmsg
+            raise maxException
+        else:
+            raise ParseException(instring, loc, "no defined alternatives to match", self)
+
+
+    def __ixor__(self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        return self.append( other ) #Or( [ self, other ] )
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class MatchFirst(ParseExpression):
+    """
+    Requires that at least one C{ParseExpression} is found.
+    If two expressions match, the first one listed is the one that will match.
+    May be constructed using the C{'|'} operator.
+
+    Example::
+        # construct MatchFirst using '|' operator
+        
+        # watch the order of expressions to match
+        number = Word(nums) | Combine(Word(nums) + '.' + Word(nums))
+        print(number.searchString("123 3.1416 789")) #  Fail! -> [['123'], ['3'], ['1416'], ['789']]
+
+        # put more selective expression first
+        number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums)
+        print(number.searchString("123 3.1416 789")) #  Better -> [['123'], ['3.1416'], ['789']]
+    """
+    def __init__( self, exprs, savelist = False ):
+        super(MatchFirst,self).__init__(exprs, savelist)
+        if self.exprs:
+            self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs)
+        else:
+            self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        maxExcLoc = -1
+        maxException = None
+        for e in self.exprs:
+            try:
+                ret = e._parse( instring, loc, doActions )
+                return ret
+            except ParseException as err:
+                if err.loc > maxExcLoc:
+                    maxException = err
+                    maxExcLoc = err.loc
+            except IndexError:
+                if len(instring) > maxExcLoc:
+                    maxException = ParseException(instring,len(instring),e.errmsg,self)
+                    maxExcLoc = len(instring)
+
+        # only got here if no expression matched, raise exception for match that made it the furthest
+        else:
+            if maxException is not None:
+                maxException.msg = self.errmsg
+                raise maxException
+            else:
+                raise ParseException(instring, loc, "no defined alternatives to match", self)
+
+    def __ior__(self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass( other )
+        return self.append( other ) #MatchFirst( [ self, other ] )
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class Each(ParseExpression):
+    """
+    Requires all given C{ParseExpression}s to be found, but in any order.
+    Expressions may be separated by whitespace.
+    May be constructed using the C{'&'} operator.
+
+    Example::
+        color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN")
+        shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON")
+        integer = Word(nums)
+        shape_attr = "shape:" + shape_type("shape")
+        posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn")
+        color_attr = "color:" + color("color")
+        size_attr = "size:" + integer("size")
+
+        # use Each (using operator '&') to accept attributes in any order 
+        # (shape and posn are required, color and size are optional)
+        shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr)
+
+        shape_spec.runTests('''
+            shape: SQUARE color: BLACK posn: 100, 120
+            shape: CIRCLE size: 50 color: BLUE posn: 50,80
+            color:GREEN size:20 shape:TRIANGLE posn:20,40
+            '''
+            )
+    prints::
+        shape: SQUARE color: BLACK posn: 100, 120
+        ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']]
+        - color: BLACK
+        - posn: ['100', ',', '120']
+          - x: 100
+          - y: 120
+        - shape: SQUARE
+
+
+        shape: CIRCLE size: 50 color: BLUE posn: 50,80
+        ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']]
+        - color: BLUE
+        - posn: ['50', ',', '80']
+          - x: 50
+          - y: 80
+        - shape: CIRCLE
+        - size: 50
+
+
+        color: GREEN size: 20 shape: TRIANGLE posn: 20,40
+        ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']]
+        - color: GREEN
+        - posn: ['20', ',', '40']
+          - x: 20
+          - y: 40
+        - shape: TRIANGLE
+        - size: 20
+    """
+    def __init__( self, exprs, savelist = True ):
+        super(Each,self).__init__(exprs, savelist)
+        self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
+        self.skipWhitespace = True
+        self.initExprGroups = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.initExprGroups:
+            self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional))
+            opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ]
+            opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)]
+            self.optionals = opt1 + opt2
+            self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ]
+            self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ]
+            self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ]
+            self.required += self.multirequired
+            self.initExprGroups = False
+        tmpLoc = loc
+        tmpReqd = self.required[:]
+        tmpOpt  = self.optionals[:]
+        matchOrder = []
+
+        keepMatching = True
+        while keepMatching:
+            tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired
+            failed = []
+            for e in tmpExprs:
+                try:
+                    tmpLoc = e.tryParse( instring, tmpLoc )
+                except ParseException:
+                    failed.append(e)
+                else:
+                    matchOrder.append(self.opt1map.get(id(e),e))
+                    if e in tmpReqd:
+                        tmpReqd.remove(e)
+                    elif e in tmpOpt:
+                        tmpOpt.remove(e)
+            if len(failed) == len(tmpExprs):
+                keepMatching = False
+
+        if tmpReqd:
+            missing = ", ".join(_ustr(e) for e in tmpReqd)
+            raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing )
+
+        # add any unmatched Optionals, in case they have default values defined
+        matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt]
+
+        resultlist = []
+        for e in matchOrder:
+            loc,results = e._parse(instring,loc,doActions)
+            resultlist.append(results)
+
+        finalResults = sum(resultlist, ParseResults([]))
+        return loc, finalResults
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}"
+
+        return self.strRepr
+
+    def checkRecursion( self, parseElementList ):
+        subRecCheckList = parseElementList[:] + [ self ]
+        for e in self.exprs:
+            e.checkRecursion( subRecCheckList )
+
+
+class ParseElementEnhance(ParserElement):
+    """
+    Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens.
+    """
+    def __init__( self, expr, savelist=False ):
+        super(ParseElementEnhance,self).__init__(savelist)
+        if isinstance( expr, basestring ):
+            if issubclass(ParserElement._literalStringClass, Token):
+                expr = ParserElement._literalStringClass(expr)
+            else:
+                expr = ParserElement._literalStringClass(Literal(expr))
+        self.expr = expr
+        self.strRepr = None
+        if expr is not None:
+            self.mayIndexError = expr.mayIndexError
+            self.mayReturnEmpty = expr.mayReturnEmpty
+            self.setWhitespaceChars( expr.whiteChars )
+            self.skipWhitespace = expr.skipWhitespace
+            self.saveAsList = expr.saveAsList
+            self.callPreparse = expr.callPreparse
+            self.ignoreExprs.extend(expr.ignoreExprs)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.expr is not None:
+            return self.expr._parse( instring, loc, doActions, callPreParse=False )
+        else:
+            raise ParseException("",loc,self.errmsg,self)
+
+    def leaveWhitespace( self ):
+        self.skipWhitespace = False
+        self.expr = self.expr.copy()
+        if self.expr is not None:
+            self.expr.leaveWhitespace()
+        return self
+
+    def ignore( self, other ):
+        if isinstance( other, Suppress ):
+            if other not in self.ignoreExprs:
+                super( ParseElementEnhance, self).ignore( other )
+                if self.expr is not None:
+                    self.expr.ignore( self.ignoreExprs[-1] )
+        else:
+            super( ParseElementEnhance, self).ignore( other )
+            if self.expr is not None:
+                self.expr.ignore( self.ignoreExprs[-1] )
+        return self
+
+    def streamline( self ):
+        super(ParseElementEnhance,self).streamline()
+        if self.expr is not None:
+            self.expr.streamline()
+        return self
+
+    def checkRecursion( self, parseElementList ):
+        if self in parseElementList:
+            raise RecursiveGrammarException( parseElementList+[self] )
+        subRecCheckList = parseElementList[:] + [ self ]
+        if self.expr is not None:
+            self.expr.checkRecursion( subRecCheckList )
+
+    def validate( self, validateTrace=[] ):
+        tmp = validateTrace[:]+[self]
+        if self.expr is not None:
+            self.expr.validate(tmp)
+        self.checkRecursion( [] )
+
+    def __str__( self ):
+        try:
+            return super(ParseElementEnhance,self).__str__()
+        except Exception:
+            pass
+
+        if self.strRepr is None and self.expr is not None:
+            self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) )
+        return self.strRepr
+
+
+class FollowedBy(ParseElementEnhance):
+    """
+    Lookahead matching of the given parse expression.  C{FollowedBy}
+    does I{not} advance the parsing position within the input string, it only
+    verifies that the specified parse expression matches at the current
+    position.  C{FollowedBy} always returns a null token list.
+
+    Example::
+        # use FollowedBy to match a label only if it is followed by a ':'
+        data_word = Word(alphas)
+        label = data_word + FollowedBy(':')
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        
+        OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint()
+    prints::
+        [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']]
+    """
+    def __init__( self, expr ):
+        super(FollowedBy,self).__init__(expr)
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        self.expr.tryParse( instring, loc )
+        return loc, []
+
+
+class NotAny(ParseElementEnhance):
+    """
+    Lookahead to disallow matching with the given parse expression.  C{NotAny}
+    does I{not} advance the parsing position within the input string, it only
+    verifies that the specified parse expression does I{not} match at the current
+    position.  Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny}
+    always returns a null token list.  May be constructed using the '~' operator.
+
+    Example::
+        
+    """
+    def __init__( self, expr ):
+        super(NotAny,self).__init__(expr)
+        #~ self.leaveWhitespace()
+        self.skipWhitespace = False  # do NOT use self.leaveWhitespace(), don't want to propagate to exprs
+        self.mayReturnEmpty = True
+        self.errmsg = "Found unwanted token, "+_ustr(self.expr)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        if self.expr.canParseNext(instring, loc):
+            raise ParseException(instring, loc, self.errmsg, self)
+        return loc, []
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "~{" + _ustr(self.expr) + "}"
+
+        return self.strRepr
+
+class _MultipleMatch(ParseElementEnhance):
+    def __init__( self, expr, stopOn=None):
+        super(_MultipleMatch, self).__init__(expr)
+        self.saveAsList = True
+        ender = stopOn
+        if isinstance(ender, basestring):
+            ender = ParserElement._literalStringClass(ender)
+        self.not_ender = ~ender if ender is not None else None
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        self_expr_parse = self.expr._parse
+        self_skip_ignorables = self._skipIgnorables
+        check_ender = self.not_ender is not None
+        if check_ender:
+            try_not_ender = self.not_ender.tryParse
+        
+        # must be at least one (but first see if we are the stopOn sentinel;
+        # if so, fail)
+        if check_ender:
+            try_not_ender(instring, loc)
+        loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False )
+        try:
+            hasIgnoreExprs = (not not self.ignoreExprs)
+            while 1:
+                if check_ender:
+                    try_not_ender(instring, loc)
+                if hasIgnoreExprs:
+                    preloc = self_skip_ignorables( instring, loc )
+                else:
+                    preloc = loc
+                loc, tmptokens = self_expr_parse( instring, preloc, doActions )
+                if tmptokens or tmptokens.haskeys():
+                    tokens += tmptokens
+        except (ParseException,IndexError):
+            pass
+
+        return loc, tokens
+        
+class OneOrMore(_MultipleMatch):
+    """
+    Repetition of one or more of the given expression.
+    
+    Parameters:
+     - expr - expression that must match one or more times
+     - stopOn - (default=C{None}) - expression for a terminating sentinel
+          (only required if the sentinel would ordinarily match the repetition 
+          expression)          
+
+    Example::
+        data_word = Word(alphas)
+        label = data_word + FollowedBy(':')
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join))
+
+        text = "shape: SQUARE posn: upper left color: BLACK"
+        OneOrMore(attr_expr).parseString(text).pprint()  # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']]
+
+        # use stopOn attribute for OneOrMore to avoid reading label string as part of the data
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']]
+        
+        # could also be written as
+        (attr_expr * (1,)).parseString(text).pprint()
+    """
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "{" + _ustr(self.expr) + "}..."
+
+        return self.strRepr
+
+class ZeroOrMore(_MultipleMatch):
+    """
+    Optional repetition of zero or more of the given expression.
+    
+    Parameters:
+     - expr - expression that must match zero or more times
+     - stopOn - (default=C{None}) - expression for a terminating sentinel
+          (only required if the sentinel would ordinarily match the repetition 
+          expression)          
+
+    Example: similar to L{OneOrMore}
+    """
+    def __init__( self, expr, stopOn=None):
+        super(ZeroOrMore,self).__init__(expr, stopOn=stopOn)
+        self.mayReturnEmpty = True
+        
+    def parseImpl( self, instring, loc, doActions=True ):
+        try:
+            return super(ZeroOrMore, self).parseImpl(instring, loc, doActions)
+        except (ParseException,IndexError):
+            return loc, []
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "[" + _ustr(self.expr) + "]..."
+
+        return self.strRepr
+
+class _NullToken(object):
+    def __bool__(self):
+        return False
+    __nonzero__ = __bool__
+    def __str__(self):
+        return ""
+
+_optionalNotMatched = _NullToken()
+class Optional(ParseElementEnhance):
+    """
+    Optional matching of the given expression.
+
+    Parameters:
+     - expr - expression that must match zero or more times
+     - default (optional) - value to be returned if the optional expression is not found.
+
+    Example::
+        # US postal code can be a 5-digit zip, plus optional 4-digit qualifier
+        zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4)))
+        zip.runTests('''
+            # traditional ZIP code
+            12345
+            
+            # ZIP+4 form
+            12101-0001
+            
+            # invalid ZIP
+            98765-
+            ''')
+    prints::
+        # traditional ZIP code
+        12345
+        ['12345']
+
+        # ZIP+4 form
+        12101-0001
+        ['12101-0001']
+
+        # invalid ZIP
+        98765-
+             ^
+        FAIL: Expected end of text (at char 5), (line:1, col:6)
+    """
+    def __init__( self, expr, default=_optionalNotMatched ):
+        super(Optional,self).__init__( expr, savelist=False )
+        self.saveAsList = self.expr.saveAsList
+        self.defaultValue = default
+        self.mayReturnEmpty = True
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        try:
+            loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False )
+        except (ParseException,IndexError):
+            if self.defaultValue is not _optionalNotMatched:
+                if self.expr.resultsName:
+                    tokens = ParseResults([ self.defaultValue ])
+                    tokens[self.expr.resultsName] = self.defaultValue
+                else:
+                    tokens = [ self.defaultValue ]
+            else:
+                tokens = []
+        return loc, tokens
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+
+        if self.strRepr is None:
+            self.strRepr = "[" + _ustr(self.expr) + "]"
+
+        return self.strRepr
+
+class SkipTo(ParseElementEnhance):
+    """
+    Token for skipping over all undefined text until the matched expression is found.
+
+    Parameters:
+     - expr - target expression marking the end of the data to be skipped
+     - include - (default=C{False}) if True, the target expression is also parsed 
+          (the skipped text and target expression are returned as a 2-element list).
+     - ignore - (default=C{None}) used to define grammars (typically quoted strings and 
+          comments) that might contain false matches to the target expression
+     - failOn - (default=C{None}) define expressions that are not allowed to be 
+          included in the skipped test; if found before the target expression is found, 
+          the SkipTo is not a match
+
+    Example::
+        report = '''
+            Outstanding Issues Report - 1 Jan 2000
+
+               # | Severity | Description                               |  Days Open
+            -----+----------+-------------------------------------------+-----------
+             101 | Critical | Intermittent system crash                 |          6
+              94 | Cosmetic | Spelling error on Login ('log|n')         |         14
+              79 | Minor    | System slow when running too many reports |         47
+            '''
+        integer = Word(nums)
+        SEP = Suppress('|')
+        # use SkipTo to simply match everything up until the next SEP
+        # - ignore quoted strings, so that a '|' character inside a quoted string does not match
+        # - parse action will call token.strip() for each matched token, i.e., the description body
+        string_data = SkipTo(SEP, ignore=quotedString)
+        string_data.setParseAction(tokenMap(str.strip))
+        ticket_expr = (integer("issue_num") + SEP 
+                      + string_data("sev") + SEP 
+                      + string_data("desc") + SEP 
+                      + integer("days_open"))
+        
+        for tkt in ticket_expr.searchString(report):
+            print tkt.dump()
+    prints::
+        ['101', 'Critical', 'Intermittent system crash', '6']
+        - days_open: 6
+        - desc: Intermittent system crash
+        - issue_num: 101
+        - sev: Critical
+        ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14']
+        - days_open: 14
+        - desc: Spelling error on Login ('log|n')
+        - issue_num: 94
+        - sev: Cosmetic
+        ['79', 'Minor', 'System slow when running too many reports', '47']
+        - days_open: 47
+        - desc: System slow when running too many reports
+        - issue_num: 79
+        - sev: Minor
+    """
+    def __init__( self, other, include=False, ignore=None, failOn=None ):
+        super( SkipTo, self ).__init__( other )
+        self.ignoreExpr = ignore
+        self.mayReturnEmpty = True
+        self.mayIndexError = False
+        self.includeMatch = include
+        self.asList = False
+        if isinstance(failOn, basestring):
+            self.failOn = ParserElement._literalStringClass(failOn)
+        else:
+            self.failOn = failOn
+        self.errmsg = "No match found for "+_ustr(self.expr)
+
+    def parseImpl( self, instring, loc, doActions=True ):
+        startloc = loc
+        instrlen = len(instring)
+        expr = self.expr
+        expr_parse = self.expr._parse
+        self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None
+        self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None
+        
+        tmploc = loc
+        while tmploc <= instrlen:
+            if self_failOn_canParseNext is not None:
+                # break if failOn expression matches
+                if self_failOn_canParseNext(instring, tmploc):
+                    break
+                    
+            if self_ignoreExpr_tryParse is not None:
+                # advance past ignore expressions
+                while 1:
+                    try:
+                        tmploc = self_ignoreExpr_tryParse(instring, tmploc)
+                    except ParseBaseException:
+                        break
+            
+            try:
+                expr_parse(instring, tmploc, doActions=False, callPreParse=False)
+            except (ParseException, IndexError):
+                # no match, advance loc in string
+                tmploc += 1
+            else:
+                # matched skipto expr, done
+                break
+
+        else:
+            # ran off the end of the input string without matching skipto expr, fail
+            raise ParseException(instring, loc, self.errmsg, self)
+
+        # build up return values
+        loc = tmploc
+        skiptext = instring[startloc:loc]
+        skipresult = ParseResults(skiptext)
+        
+        if self.includeMatch:
+            loc, mat = expr_parse(instring,loc,doActions,callPreParse=False)
+            skipresult += mat
+
+        return loc, skipresult
+
+class Forward(ParseElementEnhance):
+    """
+    Forward declaration of an expression to be defined later -
+    used for recursive grammars, such as algebraic infix notation.
+    When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator.
+
+    Note: take care when assigning to C{Forward} not to overlook precedence of operators.
+    Specifically, '|' has a lower precedence than '<<', so that::
+        fwdExpr << a | b | c
+    will actually be evaluated as::
+        (fwdExpr << a) | b | c
+    thereby leaving b and c out as parseable alternatives.  It is recommended that you
+    explicitly group the values inserted into the C{Forward}::
+        fwdExpr << (a | b | c)
+    Converting to use the '<<=' operator instead will avoid this problem.
+
+    See L{ParseResults.pprint} for an example of a recursive parser created using
+    C{Forward}.
+    """
+    def __init__( self, other=None ):
+        super(Forward,self).__init__( other, savelist=False )
+
+    def __lshift__( self, other ):
+        if isinstance( other, basestring ):
+            other = ParserElement._literalStringClass(other)
+        self.expr = other
+        self.strRepr = None
+        self.mayIndexError = self.expr.mayIndexError
+        self.mayReturnEmpty = self.expr.mayReturnEmpty
+        self.setWhitespaceChars( self.expr.whiteChars )
+        self.skipWhitespace = self.expr.skipWhitespace
+        self.saveAsList = self.expr.saveAsList
+        self.ignoreExprs.extend(self.expr.ignoreExprs)
+        return self
+        
+    def __ilshift__(self, other):
+        return self << other
+    
+    def leaveWhitespace( self ):
+        self.skipWhitespace = False
+        return self
+
+    def streamline( self ):
+        if not self.streamlined:
+            self.streamlined = True
+            if self.expr is not None:
+                self.expr.streamline()
+        return self
+
+    def validate( self, validateTrace=[] ):
+        if self not in validateTrace:
+            tmp = validateTrace[:]+[self]
+            if self.expr is not None:
+                self.expr.validate(tmp)
+        self.checkRecursion([])
+
+    def __str__( self ):
+        if hasattr(self,"name"):
+            return self.name
+        return self.__class__.__name__ + ": ..."
+
+        # stubbed out for now - creates awful memory and perf issues
+        self._revertClass = self.__class__
+        self.__class__ = _ForwardNoRecurse
+        try:
+            if self.expr is not None:
+                retString = _ustr(self.expr)
+            else:
+                retString = "None"
+        finally:
+            self.__class__ = self._revertClass
+        return self.__class__.__name__ + ": " + retString
+
+    def copy(self):
+        if self.expr is not None:
+            return super(Forward,self).copy()
+        else:
+            ret = Forward()
+            ret <<= self
+            return ret
+
+class _ForwardNoRecurse(Forward):
+    def __str__( self ):
+        return "..."
+
+class TokenConverter(ParseElementEnhance):
+    """
+    Abstract subclass of C{ParseExpression}, for converting parsed results.
+    """
+    def __init__( self, expr, savelist=False ):
+        super(TokenConverter,self).__init__( expr )#, savelist )
+        self.saveAsList = False
+
+class Combine(TokenConverter):
+    """
+    Converter to concatenate all matching tokens to a single string.
+    By default, the matching patterns must also be contiguous in the input string;
+    this can be disabled by specifying C{'adjacent=False'} in the constructor.
+
+    Example::
+        real = Word(nums) + '.' + Word(nums)
+        print(real.parseString('3.1416')) # -> ['3', '.', '1416']
+        # will also erroneously match the following
+        print(real.parseString('3. 1416')) # -> ['3', '.', '1416']
+
+        real = Combine(Word(nums) + '.' + Word(nums))
+        print(real.parseString('3.1416')) # -> ['3.1416']
+        # no match when there are internal spaces
+        print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...)
+    """
+    def __init__( self, expr, joinString="", adjacent=True ):
+        super(Combine,self).__init__( expr )
+        # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself
+        if adjacent:
+            self.leaveWhitespace()
+        self.adjacent = adjacent
+        self.skipWhitespace = True
+        self.joinString = joinString
+        self.callPreparse = True
+
+    def ignore( self, other ):
+        if self.adjacent:
+            ParserElement.ignore(self, other)
+        else:
+            super( Combine, self).ignore( other )
+        return self
+
+    def postParse( self, instring, loc, tokenlist ):
+        retToks = tokenlist.copy()
+        del retToks[:]
+        retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults)
+
+        if self.resultsName and retToks.haskeys():
+            return [ retToks ]
+        else:
+            return retToks
+
+class Group(TokenConverter):
+    """
+    Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions.
+
+    Example::
+        ident = Word(alphas)
+        num = Word(nums)
+        term = ident | num
+        func = ident + Optional(delimitedList(term))
+        print(func.parseString("fn a,b,100"))  # -> ['fn', 'a', 'b', '100']
+
+        func = ident + Group(Optional(delimitedList(term)))
+        print(func.parseString("fn a,b,100"))  # -> ['fn', ['a', 'b', '100']]
+    """
+    def __init__( self, expr ):
+        super(Group,self).__init__( expr )
+        self.saveAsList = True
+
+    def postParse( self, instring, loc, tokenlist ):
+        return [ tokenlist ]
+
+class Dict(TokenConverter):
+    """
+    Converter to return a repetitive expression as a list, but also as a dictionary.
+    Each element can also be referenced using the first token in the expression as its key.
+    Useful for tabular report scraping when the first column can be used as a item key.
+
+    Example::
+        data_word = Word(alphas)
+        label = data_word + FollowedBy(':')
+        attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join))
+
+        text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
+        attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        
+        # print attributes as plain groups
+        print(OneOrMore(attr_expr).parseString(text).dump())
+        
+        # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names
+        result = Dict(OneOrMore(Group(attr_expr))).parseString(text)
+        print(result.dump())
+        
+        # access named fields as dict entries, or output as dict
+        print(result['shape'])        
+        print(result.asDict())
+    prints::
+        ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap']
+
+        [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
+        - color: light blue
+        - posn: upper left
+        - shape: SQUARE
+        - texture: burlap
+        SQUARE
+        {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'}
+    See more examples at L{ParseResults} of accessing fields by results name.
+    """
+    def __init__( self, expr ):
+        super(Dict,self).__init__( expr )
+        self.saveAsList = True
+
+    def postParse( self, instring, loc, tokenlist ):
+        for i,tok in enumerate(tokenlist):
+            if len(tok) == 0:
+                continue
+            ikey = tok[0]
+            if isinstance(ikey,int):
+                ikey = _ustr(tok[0]).strip()
+            if len(tok)==1:
+                tokenlist[ikey] = _ParseResultsWithOffset("",i)
+            elif len(tok)==2 and not isinstance(tok[1],ParseResults):
+                tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i)
+            else:
+                dictvalue = tok.copy() #ParseResults(i)
+                del dictvalue[0]
+                if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()):
+                    tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i)
+                else:
+                    tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i)
+
+        if self.resultsName:
+            return [ tokenlist ]
+        else:
+            return tokenlist
+
+
+class Suppress(TokenConverter):
+    """
+    Converter for ignoring the results of a parsed expression.
+
+    Example::
+        source = "a, b, c,d"
+        wd = Word(alphas)
+        wd_list1 = wd + ZeroOrMore(',' + wd)
+        print(wd_list1.parseString(source))
+
+        # often, delimiters that are useful during parsing are just in the
+        # way afterward - use Suppress to keep them out of the parsed output
+        wd_list2 = wd + ZeroOrMore(Suppress(',') + wd)
+        print(wd_list2.parseString(source))
+    prints::
+        ['a', ',', 'b', ',', 'c', ',', 'd']
+        ['a', 'b', 'c', 'd']
+    (See also L{delimitedList}.)
+    """
+    def postParse( self, instring, loc, tokenlist ):
+        return []
+
+    def suppress( self ):
+        return self
+
+
+class OnlyOnce(object):
+    """
+    Wrapper for parse actions, to ensure they are only called once.
+    """
+    def __init__(self, methodCall):
+        self.callable = _trim_arity(methodCall)
+        self.called = False
+    def __call__(self,s,l,t):
+        if not self.called:
+            results = self.callable(s,l,t)
+            self.called = True
+            return results
+        raise ParseException(s,l,"")
+    def reset(self):
+        self.called = False
+
+def traceParseAction(f):
+    """
+    Decorator for debugging parse actions. 
+    
+    When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".}
+    When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised.
+
+    Example::
+        wd = Word(alphas)
+
+        @traceParseAction
+        def remove_duplicate_chars(tokens):
+            return ''.join(sorted(set(''.join(tokens)))
+
+        wds = OneOrMore(wd).setParseAction(remove_duplicate_chars)
+        print(wds.parseString("slkdjs sld sldd sdlf sdljf"))
+    prints::
+        >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {}))
+        <<leaving remove_duplicate_chars (ret: 'dfjkls')
+        ['dfjkls']
+    """
+    f = _trim_arity(f)
+    def z(*paArgs):
+        thisFunc = f.__name__
+        s,l,t = paArgs[-3:]
+        if len(paArgs)>3:
+            thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc
+        sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) )
+        try:
+            ret = f(*paArgs)
+        except Exception as exc:
+            sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) )
+            raise
+        sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) )
+        return ret
+    try:
+        z.__name__ = f.__name__
+    except AttributeError:
+        pass
+    return z
+
+#
+# global helpers
+#
+def delimitedList( expr, delim=",", combine=False ):
+    """
+    Helper to define a delimited list of expressions - the delimiter defaults to ','.
+    By default, the list elements and delimiters can have intervening whitespace, and
+    comments, but this can be overridden by passing C{combine=True} in the constructor.
+    If C{combine} is set to C{True}, the matching tokens are returned as a single token
+    string, with the delimiters included; otherwise, the matching tokens are returned
+    as a list of tokens, with the delimiters suppressed.
+
+    Example::
+        delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc']
+        delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE']
+    """
+    dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..."
+    if combine:
+        return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName)
+    else:
+        return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName)
+
+def countedArray( expr, intExpr=None ):
+    """
+    Helper to define a counted list of expressions.
+    This helper defines a pattern of the form::
+        integer expr expr expr...
+    where the leading integer tells how many expr expressions follow.
+    The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed.
+    
+    If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value.
+
+    Example::
+        countedArray(Word(alphas)).parseString('2 ab cd ef')  # -> ['ab', 'cd']
+
+        # in this parser, the leading integer value is given in binary,
+        # '10' indicating that 2 values are in the array
+        binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2))
+        countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef')  # -> ['ab', 'cd']
+    """
+    arrayExpr = Forward()
+    def countFieldParseAction(s,l,t):
+        n = t[0]
+        arrayExpr << (n and Group(And([expr]*n)) or Group(empty))
+        return []
+    if intExpr is None:
+        intExpr = Word(nums).setParseAction(lambda t:int(t[0]))
+    else:
+        intExpr = intExpr.copy()
+    intExpr.setName("arrayLen")
+    intExpr.addParseAction(countFieldParseAction, callDuringTry=True)
+    return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...')
+
+def _flatten(L):
+    ret = []
+    for i in L:
+        if isinstance(i,list):
+            ret.extend(_flatten(i))
+        else:
+            ret.append(i)
+    return ret
+
+def matchPreviousLiteral(expr):
+    """
+    Helper to define an expression that is indirectly defined from
+    the tokens matched in a previous expression, that is, it looks
+    for a 'repeat' of a previous expression.  For example::
+        first = Word(nums)
+        second = matchPreviousLiteral(first)
+        matchExpr = first + ":" + second
+    will match C{"1:1"}, but not C{"1:2"}.  Because this matches a
+    previous literal, will also match the leading C{"1:1"} in C{"1:10"}.
+    If this is not desired, use C{matchPreviousExpr}.
+    Do I{not} use with packrat parsing enabled.
+    """
+    rep = Forward()
+    def copyTokenToRepeater(s,l,t):
+        if t:
+            if len(t) == 1:
+                rep << t[0]
+            else:
+                # flatten t tokens
+                tflat = _flatten(t.asList())
+                rep << And(Literal(tt) for tt in tflat)
+        else:
+            rep << Empty()
+    expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
+    rep.setName('(prev) ' + _ustr(expr))
+    return rep
+
+def matchPreviousExpr(expr):
+    """
+    Helper to define an expression that is indirectly defined from
+    the tokens matched in a previous expression, that is, it looks
+    for a 'repeat' of a previous expression.  For example::
+        first = Word(nums)
+        second = matchPreviousExpr(first)
+        matchExpr = first + ":" + second
+    will match C{"1:1"}, but not C{"1:2"}.  Because this matches by
+    expressions, will I{not} match the leading C{"1:1"} in C{"1:10"};
+    the expressions are evaluated first, and then compared, so
+    C{"1"} is compared with C{"10"}.
+    Do I{not} use with packrat parsing enabled.
+    """
+    rep = Forward()
+    e2 = expr.copy()
+    rep <<= e2
+    def copyTokenToRepeater(s,l,t):
+        matchTokens = _flatten(t.asList())
+        def mustMatchTheseTokens(s,l,t):
+            theseTokens = _flatten(t.asList())
+            if  theseTokens != matchTokens:
+                raise ParseException("",0,"")
+        rep.setParseAction( mustMatchTheseTokens, callDuringTry=True )
+    expr.addParseAction(copyTokenToRepeater, callDuringTry=True)
+    rep.setName('(prev) ' + _ustr(expr))
+    return rep
+
+def _escapeRegexRangeChars(s):
+    #~  escape these chars: ^-]
+    for c in r"\^-]":
+        s = s.replace(c,_bslash+c)
+    s = s.replace("\n",r"\n")
+    s = s.replace("\t",r"\t")
+    return _ustr(s)
+
+def oneOf( strs, caseless=False, useRegex=True ):
+    """
+    Helper to quickly define a set of alternative Literals, and makes sure to do
+    longest-first testing when there is a conflict, regardless of the input order,
+    but returns a C{L{MatchFirst}} for best performance.
+
+    Parameters:
+     - strs - a string of space-delimited literals, or a collection of string literals
+     - caseless - (default=C{False}) - treat all literals as caseless
+     - useRegex - (default=C{True}) - as an optimization, will generate a Regex
+          object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or
+          if creating a C{Regex} raises an exception)
+
+    Example::
+        comp_oper = oneOf("< = > <= >= !=")
+        var = Word(alphas)
+        number = Word(nums)
+        term = var | number
+        comparison_expr = term + comp_oper + term
+        print(comparison_expr.searchString("B = 12  AA=23 B<=AA AA>12"))
+    prints::
+        [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']]
+    """
+    if caseless:
+        isequal = ( lambda a,b: a.upper() == b.upper() )
+        masks = ( lambda a,b: b.upper().startswith(a.upper()) )
+        parseElementClass = CaselessLiteral
+    else:
+        isequal = ( lambda a,b: a == b )
+        masks = ( lambda a,b: b.startswith(a) )
+        parseElementClass = Literal
+
+    symbols = []
+    if isinstance(strs,basestring):
+        symbols = strs.split()
+    elif isinstance(strs, collections.Iterable):
+        symbols = list(strs)
+    else:
+        warnings.warn("Invalid argument to oneOf, expected string or iterable",
+                SyntaxWarning, stacklevel=2)
+    if not symbols:
+        return NoMatch()
+
+    i = 0
+    while i < len(symbols)-1:
+        cur = symbols[i]
+        for j,other in enumerate(symbols[i+1:]):
+            if ( isequal(other, cur) ):
+                del symbols[i+j+1]
+                break
+            elif ( masks(cur, other) ):
+                del symbols[i+j+1]
+                symbols.insert(i,other)
+                cur = other
+                break
+        else:
+            i += 1
+
+    if not caseless and useRegex:
+        #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] ))
+        try:
+            if len(symbols)==len("".join(symbols)):
+                return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols))
+            else:
+                return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols))
+        except Exception:
+            warnings.warn("Exception creating Regex for oneOf, building MatchFirst",
+                    SyntaxWarning, stacklevel=2)
+
+
+    # last resort, just use MatchFirst
+    return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols))
+
+def dictOf( key, value ):
+    """
+    Helper to easily and clearly define a dictionary by specifying the respective patterns
+    for the key and value.  Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens
+    in the proper order.  The key pattern can include delimiting markers or punctuation,
+    as long as they are suppressed, thereby leaving the significant key text.  The value
+    pattern can include named results, so that the C{Dict} results can include named token
+    fields.
+
+    Example::
+        text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
+        attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join))
+        print(OneOrMore(attr_expr).parseString(text).dump())
+        
+        attr_label = label
+        attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)
+
+        # similar to Dict, but simpler call format
+        result = dictOf(attr_label, attr_value).parseString(text)
+        print(result.dump())
+        print(result['shape'])
+        print(result.shape)  # object attribute access works too
+        print(result.asDict())
+    prints::
+        [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
+        - color: light blue
+        - posn: upper left
+        - shape: SQUARE
+        - texture: burlap
+        SQUARE
+        SQUARE
+        {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'}
+    """
+    return Dict( ZeroOrMore( Group ( key + value ) ) )
+
+def originalTextFor(expr, asString=True):
+    """
+    Helper to return the original, untokenized text for a given expression.  Useful to
+    restore the parsed fields of an HTML start tag into the raw tag text itself, or to
+    revert separate tokens with intervening whitespace back to the original matching
+    input text. By default, returns astring containing the original parsed text.  
+       
+    If the optional C{asString} argument is passed as C{False}, then the return value is a 
+    C{L{ParseResults}} containing any results names that were originally matched, and a 
+    single token containing the original matched text from the input string.  So if 
+    the expression passed to C{L{originalTextFor}} contains expressions with defined
+    results names, you must set C{asString} to C{False} if you want to preserve those
+    results name values.
+
+    Example::
+        src = "this is test <b> bold <i>text</i> </b> normal text "
+        for tag in ("b","i"):
+            opener,closer = makeHTMLTags(tag)
+            patt = originalTextFor(opener + SkipTo(closer) + closer)
+            print(patt.searchString(src)[0])
+    prints::
+        ['<b> bold <i>text</i> </b>']
+        ['<i>text</i>']
+    """
+    locMarker = Empty().setParseAction(lambda s,loc,t: loc)
+    endlocMarker = locMarker.copy()
+    endlocMarker.callPreparse = False
+    matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end")
+    if asString:
+        extractText = lambda s,l,t: s[t._original_start:t._original_end]
+    else:
+        def extractText(s,l,t):
+            t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]]
+    matchExpr.setParseAction(extractText)
+    matchExpr.ignoreExprs = expr.ignoreExprs
+    return matchExpr
+
+def ungroup(expr): 
+    """
+    Helper to undo pyparsing's default grouping of And expressions, even
+    if all but one are non-empty.
+    """
+    return TokenConverter(expr).setParseAction(lambda t:t[0])
+
+def locatedExpr(expr):
+    """
+    Helper to decorate a returned token with its starting and ending locations in the input string.
+    This helper adds the following results names:
+     - locn_start = location where matched expression begins
+     - locn_end = location where matched expression ends
+     - value = the actual parsed results
+
+    Be careful if the input text contains C{<TAB>} characters, you may want to call
+    C{L{ParserElement.parseWithTabs}}
+
+    Example::
+        wd = Word(alphas)
+        for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"):
+            print(match)
+    prints::
+        [[0, 'ljsdf', 5]]
+        [[8, 'lksdjjf', 15]]
+        [[18, 'lkkjj', 23]]
+    """
+    locator = Empty().setParseAction(lambda s,l,t: l)
+    return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end"))
+
+
+# convenience constants for positional expressions
+empty       = Empty().setName("empty")
+lineStart   = LineStart().setName("lineStart")
+lineEnd     = LineEnd().setName("lineEnd")
+stringStart = StringStart().setName("stringStart")
+stringEnd   = StringEnd().setName("stringEnd")
+
+_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1])
+_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16)))
+_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8)))
+_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(printables, excludeChars=r'\]', exact=1) | Regex(r"\w", re.UNICODE)
+_charRange = Group(_singleChar + Suppress("-") + _singleChar)
+_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]"
+
+def srange(s):
+    r"""
+    Helper to easily define string ranges for use in Word construction.  Borrows
+    syntax from regexp '[]' string range definitions::
+        srange("[0-9]")   -> "0123456789"
+        srange("[a-z]")   -> "abcdefghijklmnopqrstuvwxyz"
+        srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_"
+    The input string must be enclosed in []'s, and the returned string is the expanded
+    character set joined into a single string.
+    The values enclosed in the []'s may be:
+     - a single character
+     - an escaped character with a leading backslash (such as C{\-} or C{\]})
+     - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) 
+         (C{\0x##} is also supported for backwards compatibility) 
+     - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character)
+     - a range of any of the above, separated by a dash (C{'a-z'}, etc.)
+     - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.)
+    """
+    _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1))
+    try:
+        return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body)
+    except Exception:
+        return ""
+
+def matchOnlyAtCol(n):
+    """
+    Helper method for defining parse actions that require matching at a specific
+    column in the input text.
+    """
+    def verifyCol(strg,locn,toks):
+        if col(locn,strg) != n:
+            raise ParseException(strg,locn,"matched token not at column %d" % n)
+    return verifyCol
+
+def replaceWith(replStr):
+    """
+    Helper method for common parse actions that simply return a literal value.  Especially
+    useful when used with C{L{transformString<ParserElement.transformString>}()}.
+
+    Example::
+        num = Word(nums).setParseAction(lambda toks: int(toks[0]))
+        na = oneOf("N/A NA").setParseAction(replaceWith(math.nan))
+        term = na | num
+        
+        OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234]
+    """
+    return lambda s,l,t: [replStr]
+
+def removeQuotes(s,l,t):
+    """
+    Helper parse action for removing quotation marks from parsed quoted strings.
+
+    Example::
+        # by default, quotation marks are included in parsed results
+        quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"]
+
+        # use removeQuotes to strip quotation marks from parsed results
+        quotedString.setParseAction(removeQuotes)
+        quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"]
+    """
+    return t[0][1:-1]
+
+def tokenMap(func, *args):
+    """
+    Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional 
+    args are passed, they are forwarded to the given function as additional arguments after
+    the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the
+    parsed data to an integer using base 16.
+
+    Example (compare the last to example in L{ParserElement.transformString}::
+        hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16))
+        hex_ints.runTests('''
+            00 11 22 aa FF 0a 0d 1a
+            ''')
+        
+        upperword = Word(alphas).setParseAction(tokenMap(str.upper))
+        OneOrMore(upperword).runTests('''
+            my kingdom for a horse
+            ''')
+
+        wd = Word(alphas).setParseAction(tokenMap(str.title))
+        OneOrMore(wd).setParseAction(' '.join).runTests('''
+            now is the winter of our discontent made glorious summer by this sun of york
+            ''')
+    prints::
+        00 11 22 aa FF 0a 0d 1a
+        [0, 17, 34, 170, 255, 10, 13, 26]
+
+        my kingdom for a horse
+        ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE']
+
+        now is the winter of our discontent made glorious summer by this sun of york
+        ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York']
+    """
+    def pa(s,l,t):
+        return [func(tokn, *args) for tokn in t]
+
+    try:
+        func_name = getattr(func, '__name__', 
+                            getattr(func, '__class__').__name__)
+    except Exception:
+        func_name = str(func)
+    pa.__name__ = func_name
+
+    return pa
+
+upcaseTokens = tokenMap(lambda t: _ustr(t).upper())
+"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}"""
+
+downcaseTokens = tokenMap(lambda t: _ustr(t).lower())
+"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}"""
+    
+def _makeTags(tagStr, xml):
+    """Internal helper to construct opening and closing tag expressions, given a tag name"""
+    if isinstance(tagStr,basestring):
+        resname = tagStr
+        tagStr = Keyword(tagStr, caseless=not xml)
+    else:
+        resname = tagStr.name
+
+    tagAttrName = Word(alphas,alphanums+"_-:")
+    if (xml):
+        tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes )
+        openTag = Suppress("<") + tagStr("tag") + \
+                Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \
+                Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
+    else:
+        printablesLessRAbrack = "".join(c for c in printables if c not in ">")
+        tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack)
+        openTag = Suppress("<") + tagStr("tag") + \
+                Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \
+                Optional( Suppress("=") + tagAttrValue ) ))) + \
+                Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
+    closeTag = Combine(_L("</") + tagStr + ">")
+
+    openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname)
+    closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname)
+    openTag.tag = resname
+    closeTag.tag = resname
+    return openTag, closeTag
+
+def makeHTMLTags(tagStr):
+    """
+    Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches
+    tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values.
+
+    Example::
+        text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>'
+        # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple
+        a,a_end = makeHTMLTags("A")
+        link_expr = a + SkipTo(a_end)("link_text") + a_end
+        
+        for link in link_expr.searchString(text):
+            # attributes in the <A> tag (like "href" shown here) are also accessible as named results
+            print(link.link_text, '->', link.href)
+    prints::
+        pyparsing -> http://pyparsing.wikispaces.com
+    """
+    return _makeTags( tagStr, False )
+
+def makeXMLTags(tagStr):
+    """
+    Helper to construct opening and closing tag expressions for XML, given a tag name. Matches
+    tags only in the given upper/lower case.
+
+    Example: similar to L{makeHTMLTags}
+    """
+    return _makeTags( tagStr, True )
+
+def withAttribute(*args,**attrDict):
+    """
+    Helper to create a validating parse action to be used with start tags created
+    with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag
+    with a required attribute value, to avoid false matches on common tags such as
+    C{<TD>} or C{<DIV>}.
+
+    Call C{withAttribute} with a series of attribute names and values. Specify the list
+    of filter attributes names and values as:
+     - keyword arguments, as in C{(align="right")}, or
+     - as an explicit dict with C{**} operator, when an attribute name is also a Python
+          reserved word, as in C{**{"class":"Customer", "align":"right"}}
+     - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") )
+    For attribute names with a namespace prefix, you must use the second form.  Attribute
+    names are matched insensitive to upper/lower case.
+       
+    If just testing for C{class} (with or without a namespace), use C{L{withClass}}.
+
+    To verify that the attribute exists, but without specifying a value, pass
+    C{withAttribute.ANY_VALUE} as the value.
+
+    Example::
+        html = '''
+            <div>
+            Some text
+            <div type="grid">1 4 0 1 0</div>
+            <div type="graph">1,3 2,3 1,1</div>
+            <div>this has no type</div>
+            </div>
+                
+        '''
+        div,div_end = makeHTMLTags("div")
+
+        # only match div tag having a type attribute with value "grid"
+        div_grid = div().setParseAction(withAttribute(type="grid"))
+        grid_expr = div_grid + SkipTo(div | div_end)("body")
+        for grid_header in grid_expr.searchString(html):
+            print(grid_header.body)
+        
+        # construct a match with any div tag having a type attribute, regardless of the value
+        div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE))
+        div_expr = div_any_type + SkipTo(div | div_end)("body")
+        for div_header in div_expr.searchString(html):
+            print(div_header.body)
+    prints::
+        1 4 0 1 0
+
+        1 4 0 1 0
+        1,3 2,3 1,1
+    """
+    if args:
+        attrs = args[:]
+    else:
+        attrs = attrDict.items()
+    attrs = [(k,v) for k,v in attrs]
+    def pa(s,l,tokens):
+        for attrName,attrValue in attrs:
+            if attrName not in tokens:
+                raise ParseException(s,l,"no matching attribute " + attrName)
+            if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue:
+                raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" %
+                                            (attrName, tokens[attrName], attrValue))
+    return pa
+withAttribute.ANY_VALUE = object()
+
+def withClass(classname, namespace=''):
+    """
+    Simplified version of C{L{withAttribute}} when matching on a div class - made
+    difficult because C{class} is a reserved word in Python.
+
+    Example::
+        html = '''
+            <div>
+            Some text
+            <div class="grid">1 4 0 1 0</div>
+            <div class="graph">1,3 2,3 1,1</div>
+            <div>this &lt;div&gt; has no class</div>
+            </div>
+                
+        '''
+        div,div_end = makeHTMLTags("div")
+        div_grid = div().setParseAction(withClass("grid"))
+        
+        grid_expr = div_grid + SkipTo(div | div_end)("body")
+        for grid_header in grid_expr.searchString(html):
+            print(grid_header.body)
+        
+        div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE))
+        div_expr = div_any_type + SkipTo(div | div_end)("body")
+        for div_header in div_expr.searchString(html):
+            print(div_header.body)
+    prints::
+        1 4 0 1 0
+
+        1 4 0 1 0
+        1,3 2,3 1,1
+    """
+    classattr = "%s:class" % namespace if namespace else "class"
+    return withAttribute(**{classattr : classname})        
+
+opAssoc = _Constants()
+opAssoc.LEFT = object()
+opAssoc.RIGHT = object()
+
+def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ):
+    """
+    Helper method for constructing grammars of expressions made up of
+    operators working in a precedence hierarchy.  Operators may be unary or
+    binary, left- or right-associative.  Parse actions can also be attached
+    to operator expressions. The generated parser will also recognize the use 
+    of parentheses to override operator precedences (see example below).
+    
+    Note: if you define a deep operator list, you may see performance issues
+    when using infixNotation. See L{ParserElement.enablePackrat} for a
+    mechanism to potentially improve your parser performance.
+
+    Parameters:
+     - baseExpr - expression representing the most basic element for the nested
+     - opList - list of tuples, one for each operator precedence level in the
+      expression grammar; each tuple is of the form
+      (opExpr, numTerms, rightLeftAssoc, parseAction), where:
+       - opExpr is the pyparsing expression for the operator;
+          may also be a string, which will be converted to a Literal;
+          if numTerms is 3, opExpr is a tuple of two expressions, for the
+          two operators separating the 3 terms
+       - numTerms is the number of terms for this operator (must
+          be 1, 2, or 3)
+       - rightLeftAssoc is the indicator whether the operator is
+          right or left associative, using the pyparsing-defined
+          constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}.
+       - parseAction is the parse action to be associated with
+          expressions matching this operator expression (the
+          parse action tuple member may be omitted)
+     - lpar - expression for matching left-parentheses (default=C{Suppress('(')})
+     - rpar - expression for matching right-parentheses (default=C{Suppress(')')})
+
+    Example::
+        # simple example of four-function arithmetic with ints and variable names
+        integer = pyparsing_common.signed_integer
+        varname = pyparsing_common.identifier 
+        
+        arith_expr = infixNotation(integer | varname,
+            [
+            ('-', 1, opAssoc.RIGHT),
+            (oneOf('* /'), 2, opAssoc.LEFT),
+            (oneOf('+ -'), 2, opAssoc.LEFT),
+            ])
+        
+        arith_expr.runTests('''
+            5+3*6
+            (5+3)*6
+            -2--11
+            ''', fullDump=False)
+    prints::
+        5+3*6
+        [[5, '+', [3, '*', 6]]]
+
+        (5+3)*6
+        [[[5, '+', 3], '*', 6]]
+
+        -2--11
+        [[['-', 2], '-', ['-', 11]]]
+    """
+    ret = Forward()
+    lastExpr = baseExpr | ( lpar + ret + rpar )
+    for i,operDef in enumerate(opList):
+        opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4]
+        termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr
+        if arity == 3:
+            if opExpr is None or len(opExpr) != 2:
+                raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions")
+            opExpr1, opExpr2 = opExpr
+        thisExpr = Forward().setName(termName)
+        if rightLeftAssoc == opAssoc.LEFT:
+            if arity == 1:
+                matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) )
+            elif arity == 2:
+                if opExpr is not None:
+                    matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) )
+                else:
+                    matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) )
+            elif arity == 3:
+                matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \
+                            Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr )
+            else:
+                raise ValueError("operator must be unary (1), binary (2), or ternary (3)")
+        elif rightLeftAssoc == opAssoc.RIGHT:
+            if arity == 1:
+                # try to avoid LR with this extra test
+                if not isinstance(opExpr, Optional):
+                    opExpr = Optional(opExpr)
+                matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr )
+            elif arity == 2:
+                if opExpr is not None:
+                    matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) )
+                else:
+                    matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) )
+            elif arity == 3:
+                matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \
+                            Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr )
+            else:
+                raise ValueError("operator must be unary (1), binary (2), or ternary (3)")
+        else:
+            raise ValueError("operator must indicate right or left associativity")
+        if pa:
+            matchExpr.setParseAction( pa )
+        thisExpr <<= ( matchExpr.setName(termName) | lastExpr )
+        lastExpr = thisExpr
+    ret <<= lastExpr
+    return ret
+
+operatorPrecedence = infixNotation
+"""(Deprecated) Former name of C{L{infixNotation}}, will be dropped in a future release."""
+
+dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes")
+sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes")
+quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'|
+                       Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes")
+unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal")
+
+def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()):
+    """
+    Helper method for defining nested lists enclosed in opening and closing
+    delimiters ("(" and ")" are the default).
+
+    Parameters:
+     - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression
+     - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression
+     - content - expression for items within the nested lists (default=C{None})
+     - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString})
+
+    If an expression is not provided for the content argument, the nested
+    expression will capture all whitespace-delimited content between delimiters
+    as a list of separate values.
+
+    Use the C{ignoreExpr} argument to define expressions that may contain
+    opening or closing characters that should not be treated as opening
+    or closing characters for nesting, such as quotedString or a comment
+    expression.  Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}.
+    The default is L{quotedString}, but if no expressions are to be ignored,
+    then pass C{None} for this argument.
+
+    Example::
+        data_type = oneOf("void int short long char float double")
+        decl_data_type = Combine(data_type + Optional(Word('*')))
+        ident = Word(alphas+'_', alphanums+'_')
+        number = pyparsing_common.number
+        arg = Group(decl_data_type + ident)
+        LPAR,RPAR = map(Suppress, "()")
+
+        code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment))
+
+        c_function = (decl_data_type("type") 
+                      + ident("name")
+                      + LPAR + Optional(delimitedList(arg), [])("args") + RPAR 
+                      + code_body("body"))
+        c_function.ignore(cStyleComment)
+        
+        source_code = '''
+            int is_odd(int x) { 
+                return (x%2); 
+            }
+                
+            int dec_to_hex(char hchar) { 
+                if (hchar >= '0' && hchar <= '9') { 
+                    return (ord(hchar)-ord('0')); 
+                } else { 
+                    return (10+ord(hchar)-ord('A'));
+                } 
+            }
+        '''
+        for func in c_function.searchString(source_code):
+            print("%(name)s (%(type)s) args: %(args)s" % func)
+
+    prints::
+        is_odd (int) args: [['int', 'x']]
+        dec_to_hex (int) args: [['char', 'hchar']]
+    """
+    if opener == closer:
+        raise ValueError("opening and closing strings cannot be the same")
+    if content is None:
+        if isinstance(opener,basestring) and isinstance(closer,basestring):
+            if len(opener) == 1 and len(closer)==1:
+                if ignoreExpr is not None:
+                    content = (Combine(OneOrMore(~ignoreExpr +
+                                    CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1))
+                                ).setParseAction(lambda t:t[0].strip()))
+                else:
+                    content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS
+                                ).setParseAction(lambda t:t[0].strip()))
+            else:
+                if ignoreExpr is not None:
+                    content = (Combine(OneOrMore(~ignoreExpr + 
+                                    ~Literal(opener) + ~Literal(closer) +
+                                    CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1))
+                                ).setParseAction(lambda t:t[0].strip()))
+                else:
+                    content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) +
+                                    CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1))
+                                ).setParseAction(lambda t:t[0].strip()))
+        else:
+            raise ValueError("opening and closing arguments must be strings if no content expression is given")
+    ret = Forward()
+    if ignoreExpr is not None:
+        ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) )
+    else:
+        ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content )  + Suppress(closer) )
+    ret.setName('nested %s%s expression' % (opener,closer))
+    return ret
+
+def indentedBlock(blockStatementExpr, indentStack, indent=True):
+    """
+    Helper method for defining space-delimited indentation blocks, such as
+    those used to define block statements in Python source code.
+
+    Parameters:
+     - blockStatementExpr - expression defining syntax of statement that
+            is repeated within the indented block
+     - indentStack - list created by caller to manage indentation stack
+            (multiple statementWithIndentedBlock expressions within a single grammar
+            should share a common indentStack)
+     - indent - boolean indicating whether block must be indented beyond the
+            the current level; set to False for block of left-most statements
+            (default=C{True})
+
+    A valid block must contain at least one C{blockStatement}.
+
+    Example::
+        data = '''
+        def A(z):
+          A1
+          B = 100
+          G = A2
+          A2
+          A3
+        B
+        def BB(a,b,c):
+          BB1
+          def BBA():
+            bba1
+            bba2
+            bba3
+        C
+        D
+        def spam(x,y):
+             def eggs(z):
+                 pass
+        '''
+
+
+        indentStack = [1]
+        stmt = Forward()
+
+        identifier = Word(alphas, alphanums)
+        funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":")
+        func_body = indentedBlock(stmt, indentStack)
+        funcDef = Group( funcDecl + func_body )
+
+        rvalue = Forward()
+        funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")")
+        rvalue << (funcCall | identifier | Word(nums))
+        assignment = Group(identifier + "=" + rvalue)
+        stmt << ( funcDef | assignment | identifier )
+
+        module_body = OneOrMore(stmt)
+
+        parseTree = module_body.parseString(data)
+        parseTree.pprint()
+    prints::
+        [['def',
+          'A',
+          ['(', 'z', ')'],
+          ':',
+          [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]],
+         'B',
+         ['def',
+          'BB',
+          ['(', 'a', 'b', 'c', ')'],
+          ':',
+          [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]],
+         'C',
+         'D',
+         ['def',
+          'spam',
+          ['(', 'x', 'y', ')'],
+          ':',
+          [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] 
+    """
+    def checkPeerIndent(s,l,t):
+        if l >= len(s): return
+        curCol = col(l,s)
+        if curCol != indentStack[-1]:
+            if curCol > indentStack[-1]:
+                raise ParseFatalException(s,l,"illegal nesting")
+            raise ParseException(s,l,"not a peer entry")
+
+    def checkSubIndent(s,l,t):
+        curCol = col(l,s)
+        if curCol > indentStack[-1]:
+            indentStack.append( curCol )
+        else:
+            raise ParseException(s,l,"not a subentry")
+
+    def checkUnindent(s,l,t):
+        if l >= len(s): return
+        curCol = col(l,s)
+        if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]):
+            raise ParseException(s,l,"not an unindent")
+        indentStack.pop()
+
+    NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress())
+    INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT')
+    PEER   = Empty().setParseAction(checkPeerIndent).setName('')
+    UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT')
+    if indent:
+        smExpr = Group( Optional(NL) +
+            #~ FollowedBy(blockStatementExpr) +
+            INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT)
+    else:
+        smExpr = Group( Optional(NL) +
+            (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) )
+    blockStatementExpr.ignore(_bslash + LineEnd())
+    return smExpr.setName('indented block')
+
+alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]")
+punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]")
+
+anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag'))
+_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\''))
+commonHTMLEntity = Regex('&(?P<entity>' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity")
+def replaceHTMLEntity(t):
+    """Helper parser action to replace common HTML entities with their special characters"""
+    return _htmlEntityMap.get(t.entity)
+
+# it's easy to get these comment structures wrong - they're very common, so may as well make them available
+cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment")
+"Comment of the form C{/* ... */}"
+
+htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment")
+"Comment of the form C{<!-- ... -->}"
+
+restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line")
+dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment")
+"Comment of the form C{// ... (to end of line)}"
+
+cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment")
+"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}"
+
+javaStyleComment = cppStyleComment
+"Same as C{L{cppStyleComment}}"
+
+pythonStyleComment = Regex(r"#.*").setName("Python style comment")
+"Comment of the form C{# ... (to end of line)}"
+
+_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') +
+                                  Optional( Word(" \t") +
+                                            ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem")
+commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList")
+"""(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas.
+   This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}."""
+
+# some other useful expressions - using lower-case class name since we are really using this as a namespace
+class pyparsing_common:
+    """
+    Here are some common low-level expressions that may be useful in jump-starting parser development:
+     - numeric forms (L{integers<integer>}, L{reals<real>}, L{scientific notation<sci_real>})
+     - common L{programming identifiers<identifier>}
+     - network addresses (L{MAC<mac_address>}, L{IPv4<ipv4_address>}, L{IPv6<ipv6_address>})
+     - ISO8601 L{dates<iso8601_date>} and L{datetime<iso8601_datetime>}
+     - L{UUID<uuid>}
+     - L{comma-separated list<comma_separated_list>}
+    Parse actions:
+     - C{L{convertToInteger}}
+     - C{L{convertToFloat}}
+     - C{L{convertToDate}}
+     - C{L{convertToDatetime}}
+     - C{L{stripHTMLTags}}
+     - C{L{upcaseTokens}}
+     - C{L{downcaseTokens}}
+
+    Example::
+        pyparsing_common.number.runTests('''
+            # any int or real number, returned as the appropriate type
+            100
+            -100
+            +100
+            3.14159
+            6.02e23
+            1e-12
+            ''')
+
+        pyparsing_common.fnumber.runTests('''
+            # any int or real number, returned as float
+            100
+            -100
+            +100
+            3.14159
+            6.02e23
+            1e-12
+            ''')
+
+        pyparsing_common.hex_integer.runTests('''
+            # hex numbers
+            100
+            FF
+            ''')
+
+        pyparsing_common.fraction.runTests('''
+            # fractions
+            1/2
+            -3/4
+            ''')
+
+        pyparsing_common.mixed_integer.runTests('''
+            # mixed fractions
+            1
+            1/2
+            -3/4
+            1-3/4
+            ''')
+
+        import uuid
+        pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID))
+        pyparsing_common.uuid.runTests('''
+            # uuid
+            12345678-1234-5678-1234-567812345678
+            ''')
+    prints::
+        # any int or real number, returned as the appropriate type
+        100
+        [100]
+
+        -100
+        [-100]
+
+        +100
+        [100]
+
+        3.14159
+        [3.14159]
+
+        6.02e23
+        [6.02e+23]
+
+        1e-12
+        [1e-12]
+
+        # any int or real number, returned as float
+        100
+        [100.0]
+
+        -100
+        [-100.0]
+
+        +100
+        [100.0]
+
+        3.14159
+        [3.14159]
+
+        6.02e23
+        [6.02e+23]
+
+        1e-12
+        [1e-12]
+
+        # hex numbers
+        100
+        [256]
+
+        FF
+        [255]
+
+        # fractions
+        1/2
+        [0.5]
+
+        -3/4
+        [-0.75]
+
+        # mixed fractions
+        1
+        [1]
+
+        1/2
+        [0.5]
+
+        -3/4
+        [-0.75]
+
+        1-3/4
+        [1.75]
+
+        # uuid
+        12345678-1234-5678-1234-567812345678
+        [UUID('12345678-1234-5678-1234-567812345678')]
+    """
+
+    convertToInteger = tokenMap(int)
+    """
+    Parse action for converting parsed integers to Python int
+    """
+
+    convertToFloat = tokenMap(float)
+    """
+    Parse action for converting parsed numbers to Python float
+    """
+
+    integer = Word(nums).setName("integer").setParseAction(convertToInteger)
+    """expression that parses an unsigned integer, returns an int"""
+
+    hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16))
+    """expression that parses a hexadecimal integer, returns an int"""
+
+    signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger)
+    """expression that parses an integer with optional leading sign, returns an int"""
+
+    fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction")
+    """fractional expression of an integer divided by an integer, returns a float"""
+    fraction.addParseAction(lambda t: t[0]/t[-1])
+
+    mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction")
+    """mixed integer of the form 'integer - fraction', with optional leading integer, returns float"""
+    mixed_integer.addParseAction(sum)
+
+    real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat)
+    """expression that parses a floating point number and returns a float"""
+
+    sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat)
+    """expression that parses a floating point number with optional scientific notation and returns a float"""
+
+    # streamlining this expression makes the docs nicer-looking
+    number = (sci_real | real | signed_integer).streamline()
+    """any numeric expression, returns the corresponding Python type"""
+
+    fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat)
+    """any int or real number, returned as float"""
+    
+    identifier = Word(alphas+'_', alphanums+'_').setName("identifier")
+    """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')"""
+    
+    ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address")
+    "IPv4 address (C{0.0.0.0 - 255.255.255.255})"
+
+    _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer")
+    _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address")
+    _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address")
+    _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8)
+    _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address")
+    ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address")
+    "IPv6 address (long, short, or mixed form)"
+    
+    mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address")
+    "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)"
+
+    @staticmethod
+    def convertToDate(fmt="%Y-%m-%d"):
+        """
+        Helper to create a parse action for converting parsed date string to Python datetime.date
+
+        Params -
+         - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"})
+
+        Example::
+            date_expr = pyparsing_common.iso8601_date.copy()
+            date_expr.setParseAction(pyparsing_common.convertToDate())
+            print(date_expr.parseString("1999-12-31"))
+        prints::
+            [datetime.date(1999, 12, 31)]
+        """
+        def cvt_fn(s,l,t):
+            try:
+                return datetime.strptime(t[0], fmt).date()
+            except ValueError as ve:
+                raise ParseException(s, l, str(ve))
+        return cvt_fn
+
+    @staticmethod
+    def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"):
+        """
+        Helper to create a parse action for converting parsed datetime string to Python datetime.datetime
+
+        Params -
+         - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"})
+
+        Example::
+            dt_expr = pyparsing_common.iso8601_datetime.copy()
+            dt_expr.setParseAction(pyparsing_common.convertToDatetime())
+            print(dt_expr.parseString("1999-12-31T23:59:59.999"))
+        prints::
+            [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)]
+        """
+        def cvt_fn(s,l,t):
+            try:
+                return datetime.strptime(t[0], fmt)
+            except ValueError as ve:
+                raise ParseException(s, l, str(ve))
+        return cvt_fn
+
+    iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date")
+    "ISO8601 date (C{yyyy-mm-dd})"
+
+    iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime")
+    "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}"
+
+    uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID")
+    "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})"
+
+    _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress()
+    @staticmethod
+    def stripHTMLTags(s, l, tokens):
+        """
+        Parse action to remove HTML tags from web page HTML source
+
+        Example::
+            # strip HTML links from normal text 
+            text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>'
+            td,td_end = makeHTMLTags("TD")
+            table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end
+            
+            print(table_text.parseString(text).body) # -> 'More info at the pyparsing wiki page'
+        """
+        return pyparsing_common._html_stripper.transformString(tokens[0])
+
+    _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') 
+                                        + Optional( White(" \t") ) ) ).streamline().setName("commaItem")
+    comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list")
+    """Predefined expression of 1 or more printable words or quoted strings, separated by commas."""
+
+    upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper()))
+    """Parse action to convert tokens to upper case."""
+
+    downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower()))
+    """Parse action to convert tokens to lower case."""
+
+
+if __name__ == "__main__":
+
+    selectToken    = CaselessLiteral("select")
+    fromToken      = CaselessLiteral("from")
+
+    ident          = Word(alphas, alphanums + "_$")
+
+    columnName     = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens)
+    columnNameList = Group(delimitedList(columnName)).setName("columns")
+    columnSpec     = ('*' | columnNameList)
+
+    tableName      = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens)
+    tableNameList  = Group(delimitedList(tableName)).setName("tables")
+    
+    simpleSQL      = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables")
+
+    # demo runTests method, including embedded comments in test string
+    simpleSQL.runTests("""
+        # '*' as column list and dotted table name
+        select * from SYS.XYZZY
+
+        # caseless match on "SELECT", and casts back to "select"
+        SELECT * from XYZZY, ABC
+
+        # list of column names, and mixed case SELECT keyword
+        Select AA,BB,CC from Sys.dual
+
+        # multiple tables
+        Select A, B, C from Sys.dual, Table2
+
+        # invalid SELECT keyword - should fail
+        Xelect A, B, C from Sys.dual
+
+        # incomplete command - should fail
+        Select
+
+        # invalid column name - should fail
+        Select ^^^ frox Sys.dual
+
+        """)
+
+    pyparsing_common.number.runTests("""
+        100
+        -100
+        +100
+        3.14159
+        6.02e23
+        1e-12
+        """)
+
+    # any int or real number, returned as float
+    pyparsing_common.fnumber.runTests("""
+        100
+        -100
+        +100
+        3.14159
+        6.02e23
+        1e-12
+        """)
+
+    pyparsing_common.hex_integer.runTests("""
+        100
+        FF
+        """)
+
+    import uuid
+    pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID))
+    pyparsing_common.uuid.runTests("""
+        12345678-1234-5678-1234-567812345678
+        """)
diff --git a/vendor/setuptools-39.0.1/setuptools/_vendor/six.py b/vendor/setuptools-39.0.1/setuptools/_vendor/six.py
new file mode 100644
index 00000000..190c0239
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/_vendor/six.py
@@ -0,0 +1,868 @@
+"""Utilities for writing code that runs on Python 2 and 3"""
+
+# Copyright (c) 2010-2015 Benjamin Peterson
+#
+# 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 __future__ import absolute_import
+
+import functools
+import itertools
+import operator
+import sys
+import types
+
+__author__ = "Benjamin Peterson <benjamin@python.org>"
+__version__ = "1.10.0"
+
+
+# Useful for very coarse version differentiation.
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
+PY34 = sys.version_info[0:2] >= (3, 4)
+
+if PY3:
+    string_types = str,
+    integer_types = int,
+    class_types = type,
+    text_type = str
+    binary_type = bytes
+
+    MAXSIZE = sys.maxsize
+else:
+    string_types = basestring,
+    integer_types = (int, long)
+    class_types = (type, types.ClassType)
+    text_type = unicode
+    binary_type = str
+
+    if sys.platform.startswith("java"):
+        # Jython always uses 32 bits.
+        MAXSIZE = int((1 << 31) - 1)
+    else:
+        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
+        class X(object):
+
+            def __len__(self):
+                return 1 << 31
+        try:
+            len(X())
+        except OverflowError:
+            # 32-bit
+            MAXSIZE = int((1 << 31) - 1)
+        else:
+            # 64-bit
+            MAXSIZE = int((1 << 63) - 1)
+        del X
+
+
+def _add_doc(func, doc):
+    """Add documentation to a function."""
+    func.__doc__ = doc
+
+
+def _import_module(name):
+    """Import module, returning the module after the last dot."""
+    __import__(name)
+    return sys.modules[name]
+
+
+class _LazyDescr(object):
+
+    def __init__(self, name):
+        self.name = name
+
+    def __get__(self, obj, tp):
+        result = self._resolve()
+        setattr(obj, self.name, result)  # Invokes __set__.
+        try:
+            # This is a bit ugly, but it avoids running this again by
+            # removing this descriptor.
+            delattr(obj.__class__, self.name)
+        except AttributeError:
+            pass
+        return result
+
+
+class MovedModule(_LazyDescr):
+
+    def __init__(self, name, old, new=None):
+        super(MovedModule, self).__init__(name)
+        if PY3:
+            if new is None:
+                new = name
+            self.mod = new
+        else:
+            self.mod = old
+
+    def _resolve(self):
+        return _import_module(self.mod)
+
+    def __getattr__(self, attr):
+        _module = self._resolve()
+        value = getattr(_module, attr)
+        setattr(self, attr, value)
+        return value
+
+
+class _LazyModule(types.ModuleType):
+
+    def __init__(self, name):
+        super(_LazyModule, self).__init__(name)
+        self.__doc__ = self.__class__.__doc__
+
+    def __dir__(self):
+        attrs = ["__doc__", "__name__"]
+        attrs += [attr.name for attr in self._moved_attributes]
+        return attrs
+
+    # Subclasses should override this
+    _moved_attributes = []
+
+
+class MovedAttribute(_LazyDescr):
+
+    def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
+        super(MovedAttribute, self).__init__(name)
+        if PY3:
+            if new_mod is None:
+                new_mod = name
+            self.mod = new_mod
+            if new_attr is None:
+                if old_attr is None:
+                    new_attr = name
+                else:
+                    new_attr = old_attr
+            self.attr = new_attr
+        else:
+            self.mod = old_mod
+            if old_attr is None:
+                old_attr = name
+            self.attr = old_attr
+
+    def _resolve(self):
+        module = _import_module(self.mod)
+        return getattr(module, self.attr)
+
+
+class _SixMetaPathImporter(object):
+
+    """
+    A meta path importer to import six.moves and its submodules.
+
+    This class implements a PEP302 finder and loader. It should be compatible
+    with Python 2.5 and all existing versions of Python3
+    """
+
+    def __init__(self, six_module_name):
+        self.name = six_module_name
+        self.known_modules = {}
+
+    def _add_module(self, mod, *fullnames):
+        for fullname in fullnames:
+            self.known_modules[self.name + "." + fullname] = mod
+
+    def _get_module(self, fullname):
+        return self.known_modules[self.name + "." + fullname]
+
+    def find_module(self, fullname, path=None):
+        if fullname in self.known_modules:
+            return self
+        return None
+
+    def __get_module(self, fullname):
+        try:
+            return self.known_modules[fullname]
+        except KeyError:
+            raise ImportError("This loader does not know module " + fullname)
+
+    def load_module(self, fullname):
+        try:
+            # in case of a reload
+            return sys.modules[fullname]
+        except KeyError:
+            pass
+        mod = self.__get_module(fullname)
+        if isinstance(mod, MovedModule):
+            mod = mod._resolve()
+        else:
+            mod.__loader__ = self
+        sys.modules[fullname] = mod
+        return mod
+
+    def is_package(self, fullname):
+        """
+        Return true, if the named module is a package.
+
+        We need this method to get correct spec objects with
+        Python 3.4 (see PEP451)
+        """
+        return hasattr(self.__get_module(fullname), "__path__")
+
+    def get_code(self, fullname):
+        """Return None
+
+        Required, if is_package is implemented"""
+        self.__get_module(fullname)  # eventually raises ImportError
+        return None
+    get_source = get_code  # same as get_code
+
+_importer = _SixMetaPathImporter(__name__)
+
+
+class _MovedItems(_LazyModule):
+
+    """Lazy loading of moved objects"""
+    __path__ = []  # mark as package
+
+
+_moved_attributes = [
+    MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
+    MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
+    MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
+    MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
+    MovedAttribute("intern", "__builtin__", "sys"),
+    MovedAttribute("map", "itertools", "builtins", "imap", "map"),
+    MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
+    MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
+    MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
+    MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
+    MovedAttribute("reduce", "__builtin__", "functools"),
+    MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
+    MovedAttribute("StringIO", "StringIO", "io"),
+    MovedAttribute("UserDict", "UserDict", "collections"),
+    MovedAttribute("UserList", "UserList", "collections"),
+    MovedAttribute("UserString", "UserString", "collections"),
+    MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
+    MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
+    MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
+    MovedModule("builtins", "__builtin__"),
+    MovedModule("configparser", "ConfigParser"),
+    MovedModule("copyreg", "copy_reg"),
+    MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
+    MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
+    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
+    MovedModule("http_cookies", "Cookie", "http.cookies"),
+    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
+    MovedModule("html_parser", "HTMLParser", "html.parser"),
+    MovedModule("http_client", "httplib", "http.client"),
+    MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
+    MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
+    MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
+    MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
+    MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
+    MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
+    MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
+    MovedModule("cPickle", "cPickle", "pickle"),
+    MovedModule("queue", "Queue"),
+    MovedModule("reprlib", "repr"),
+    MovedModule("socketserver", "SocketServer"),
+    MovedModule("_thread", "thread", "_thread"),
+    MovedModule("tkinter", "Tkinter"),
+    MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
+    MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
+    MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
+    MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
+    MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
+    MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
+    MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
+    MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
+    MovedModule("tkinter_colorchooser", "tkColorChooser",
+                "tkinter.colorchooser"),
+    MovedModule("tkinter_commondialog", "tkCommonDialog",
+                "tkinter.commondialog"),
+    MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
+    MovedModule("tkinter_font", "tkFont", "tkinter.font"),
+    MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
+    MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
+                "tkinter.simpledialog"),
+    MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
+    MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
+    MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
+    MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
+    MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
+    MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
+]
+# Add windows specific modules.
+if sys.platform == "win32":
+    _moved_attributes += [
+        MovedModule("winreg", "_winreg"),
+    ]
+
+for attr in _moved_attributes:
+    setattr(_MovedItems, attr.name, attr)
+    if isinstance(attr, MovedModule):
+        _importer._add_module(attr, "moves." + attr.name)
+del attr
+
+_MovedItems._moved_attributes = _moved_attributes
+
+moves = _MovedItems(__name__ + ".moves")
+_importer._add_module(moves, "moves")
+
+
+class Module_six_moves_urllib_parse(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_parse"""
+
+
+_urllib_parse_moved_attributes = [
+    MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
+    MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
+    MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
+    MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
+    MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
+    MovedAttribute("urljoin", "urlparse", "urllib.parse"),
+    MovedAttribute("urlparse", "urlparse", "urllib.parse"),
+    MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
+    MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
+    MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
+    MovedAttribute("quote", "urllib", "urllib.parse"),
+    MovedAttribute("quote_plus", "urllib", "urllib.parse"),
+    MovedAttribute("unquote", "urllib", "urllib.parse"),
+    MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
+    MovedAttribute("urlencode", "urllib", "urllib.parse"),
+    MovedAttribute("splitquery", "urllib", "urllib.parse"),
+    MovedAttribute("splittag", "urllib", "urllib.parse"),
+    MovedAttribute("splituser", "urllib", "urllib.parse"),
+    MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_params", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_query", "urlparse", "urllib.parse"),
+    MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
+]
+for attr in _urllib_parse_moved_attributes:
+    setattr(Module_six_moves_urllib_parse, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
+                      "moves.urllib_parse", "moves.urllib.parse")
+
+
+class Module_six_moves_urllib_error(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_error"""
+
+
+_urllib_error_moved_attributes = [
+    MovedAttribute("URLError", "urllib2", "urllib.error"),
+    MovedAttribute("HTTPError", "urllib2", "urllib.error"),
+    MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
+]
+for attr in _urllib_error_moved_attributes:
+    setattr(Module_six_moves_urllib_error, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
+                      "moves.urllib_error", "moves.urllib.error")
+
+
+class Module_six_moves_urllib_request(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_request"""
+
+
+_urllib_request_moved_attributes = [
+    MovedAttribute("urlopen", "urllib2", "urllib.request"),
+    MovedAttribute("install_opener", "urllib2", "urllib.request"),
+    MovedAttribute("build_opener", "urllib2", "urllib.request"),
+    MovedAttribute("pathname2url", "urllib", "urllib.request"),
+    MovedAttribute("url2pathname", "urllib", "urllib.request"),
+    MovedAttribute("getproxies", "urllib", "urllib.request"),
+    MovedAttribute("Request", "urllib2", "urllib.request"),
+    MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
+    MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
+    MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
+    MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
+    MovedAttribute("FileHandler", "urllib2", "urllib.request"),
+    MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
+    MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
+    MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
+    MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
+    MovedAttribute("urlretrieve", "urllib", "urllib.request"),
+    MovedAttribute("urlcleanup", "urllib", "urllib.request"),
+    MovedAttribute("URLopener", "urllib", "urllib.request"),
+    MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
+    MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
+]
+for attr in _urllib_request_moved_attributes:
+    setattr(Module_six_moves_urllib_request, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
+                      "moves.urllib_request", "moves.urllib.request")
+
+
+class Module_six_moves_urllib_response(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_response"""
+
+
+_urllib_response_moved_attributes = [
+    MovedAttribute("addbase", "urllib", "urllib.response"),
+    MovedAttribute("addclosehook", "urllib", "urllib.response"),
+    MovedAttribute("addinfo", "urllib", "urllib.response"),
+    MovedAttribute("addinfourl", "urllib", "urllib.response"),
+]
+for attr in _urllib_response_moved_attributes:
+    setattr(Module_six_moves_urllib_response, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
+                      "moves.urllib_response", "moves.urllib.response")
+
+
+class Module_six_moves_urllib_robotparser(_LazyModule):
+
+    """Lazy loading of moved objects in six.moves.urllib_robotparser"""
+
+
+_urllib_robotparser_moved_attributes = [
+    MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
+]
+for attr in _urllib_robotparser_moved_attributes:
+    setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
+                      "moves.urllib_robotparser", "moves.urllib.robotparser")
+
+
+class Module_six_moves_urllib(types.ModuleType):
+
+    """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
+    __path__ = []  # mark as package
+    parse = _importer._get_module("moves.urllib_parse")
+    error = _importer._get_module("moves.urllib_error")
+    request = _importer._get_module("moves.urllib_request")
+    response = _importer._get_module("moves.urllib_response")
+    robotparser = _importer._get_module("moves.urllib_robotparser")
+
+    def __dir__(self):
+        return ['parse', 'error', 'request', 'response', 'robotparser']
+
+_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
+                      "moves.urllib")
+
+
+def add_move(move):
+    """Add an item to six.moves."""
+    setattr(_MovedItems, move.name, move)
+
+
+def remove_move(name):
+    """Remove item from six.moves."""
+    try:
+        delattr(_MovedItems, name)
+    except AttributeError:
+        try:
+            del moves.__dict__[name]
+        except KeyError:
+            raise AttributeError("no such move, %r" % (name,))
+
+
+if PY3:
+    _meth_func = "__func__"
+    _meth_self = "__self__"
+
+    _func_closure = "__closure__"
+    _func_code = "__code__"
+    _func_defaults = "__defaults__"
+    _func_globals = "__globals__"
+else:
+    _meth_func = "im_func"
+    _meth_self = "im_self"
+
+    _func_closure = "func_closure"
+    _func_code = "func_code"
+    _func_defaults = "func_defaults"
+    _func_globals = "func_globals"
+
+
+try:
+    advance_iterator = next
+except NameError:
+    def advance_iterator(it):
+        return it.next()
+next = advance_iterator
+
+
+try:
+    callable = callable
+except NameError:
+    def callable(obj):
+        return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
+
+
+if PY3:
+    def get_unbound_function(unbound):
+        return unbound
+
+    create_bound_method = types.MethodType
+
+    def create_unbound_method(func, cls):
+        return func
+
+    Iterator = object
+else:
+    def get_unbound_function(unbound):
+        return unbound.im_func
+
+    def create_bound_method(func, obj):
+        return types.MethodType(func, obj, obj.__class__)
+
+    def create_unbound_method(func, cls):
+        return types.MethodType(func, None, cls)
+
+    class Iterator(object):
+
+        def next(self):
+            return type(self).__next__(self)
+
+    callable = callable
+_add_doc(get_unbound_function,
+         """Get the function out of a possibly unbound function""")
+
+
+get_method_function = operator.attrgetter(_meth_func)
+get_method_self = operator.attrgetter(_meth_self)
+get_function_closure = operator.attrgetter(_func_closure)
+get_function_code = operator.attrgetter(_func_code)
+get_function_defaults = operator.attrgetter(_func_defaults)
+get_function_globals = operator.attrgetter(_func_globals)
+
+
+if PY3:
+    def iterkeys(d, **kw):
+        return iter(d.keys(**kw))
+
+    def itervalues(d, **kw):
+        return iter(d.values(**kw))
+
+    def iteritems(d, **kw):
+        return iter(d.items(**kw))
+
+    def iterlists(d, **kw):
+        return iter(d.lists(**kw))
+
+    viewkeys = operator.methodcaller("keys")
+
+    viewvalues = operator.methodcaller("values")
+
+    viewitems = operator.methodcaller("items")
+else:
+    def iterkeys(d, **kw):
+        return d.iterkeys(**kw)
+
+    def itervalues(d, **kw):
+        return d.itervalues(**kw)
+
+    def iteritems(d, **kw):
+        return d.iteritems(**kw)
+
+    def iterlists(d, **kw):
+        return d.iterlists(**kw)
+
+    viewkeys = operator.methodcaller("viewkeys")
+
+    viewvalues = operator.methodcaller("viewvalues")
+
+    viewitems = operator.methodcaller("viewitems")
+
+_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
+_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
+_add_doc(iteritems,
+         "Return an iterator over the (key, value) pairs of a dictionary.")
+_add_doc(iterlists,
+         "Return an iterator over the (key, [values]) pairs of a dictionary.")
+
+
+if PY3:
+    def b(s):
+        return s.encode("latin-1")
+
+    def u(s):
+        return s
+    unichr = chr
+    import struct
+    int2byte = struct.Struct(">B").pack
+    del struct
+    byte2int = operator.itemgetter(0)
+    indexbytes = operator.getitem
+    iterbytes = iter
+    import io
+    StringIO = io.StringIO
+    BytesIO = io.BytesIO
+    _assertCountEqual = "assertCountEqual"
+    if sys.version_info[1] <= 1:
+        _assertRaisesRegex = "assertRaisesRegexp"
+        _assertRegex = "assertRegexpMatches"
+    else:
+        _assertRaisesRegex = "assertRaisesRegex"
+        _assertRegex = "assertRegex"
+else:
+    def b(s):
+        return s
+    # Workaround for standalone backslash
+
+    def u(s):
+        return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
+    unichr = unichr
+    int2byte = chr
+
+    def byte2int(bs):
+        return ord(bs[0])
+
+    def indexbytes(buf, i):
+        return ord(buf[i])
+    iterbytes = functools.partial(itertools.imap, ord)
+    import StringIO
+    StringIO = BytesIO = StringIO.StringIO
+    _assertCountEqual = "assertItemsEqual"
+    _assertRaisesRegex = "assertRaisesRegexp"
+    _assertRegex = "assertRegexpMatches"
+_add_doc(b, """Byte literal""")
+_add_doc(u, """Text literal""")
+
+
+def assertCountEqual(self, *args, **kwargs):
+    return getattr(self, _assertCountEqual)(*args, **kwargs)
+
+
+def assertRaisesRegex(self, *args, **kwargs):
+    return getattr(self, _assertRaisesRegex)(*args, **kwargs)
+
+
+def assertRegex(self, *args, **kwargs):
+    return getattr(self, _assertRegex)(*args, **kwargs)
+
+
+if PY3:
+    exec_ = getattr(moves.builtins, "exec")
+
+    def reraise(tp, value, tb=None):
+        if value is None:
+            value = tp()
+        if value.__traceback__ is not tb:
+            raise value.with_traceback(tb)
+        raise value
+
+else:
+    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 reraise(tp, value, tb=None):
+    raise tp, value, tb
+""")
+
+
+if sys.version_info[:2] == (3, 2):
+    exec_("""def raise_from(value, from_value):
+    if from_value is None:
+        raise value
+    raise value from from_value
+""")
+elif sys.version_info[:2] > (3, 2):
+    exec_("""def raise_from(value, from_value):
+    raise value from from_value
+""")
+else:
+    def raise_from(value, from_value):
+        raise value
+
+
+print_ = getattr(moves.builtins, "print", None)
+if print_ is None:
+    def print_(*args, **kwargs):
+        """The new-style print function for Python 2.4 and 2.5."""
+        fp = kwargs.pop("file", sys.stdout)
+        if fp is None:
+            return
+
+        def write(data):
+            if not isinstance(data, basestring):
+                data = str(data)
+            # If the file has an encoding, encode unicode with it.
+            if (isinstance(fp, file) and
+                    isinstance(data, unicode) and
+                    fp.encoding is not None):
+                errors = getattr(fp, "errors", None)
+                if errors is None:
+                    errors = "strict"
+                data = data.encode(fp.encoding, errors)
+            fp.write(data)
+        want_unicode = False
+        sep = kwargs.pop("sep", None)
+        if sep is not None:
+            if isinstance(sep, unicode):
+                want_unicode = True
+            elif not isinstance(sep, str):
+                raise TypeError("sep must be None or a string")
+        end = kwargs.pop("end", None)
+        if end is not None:
+            if isinstance(end, unicode):
+                want_unicode = True
+            elif not isinstance(end, str):
+                raise TypeError("end must be None or a string")
+        if kwargs:
+            raise TypeError("invalid keyword arguments to print()")
+        if not want_unicode:
+            for arg in args:
+                if isinstance(arg, unicode):
+                    want_unicode = True
+                    break
+        if want_unicode:
+            newline = unicode("\n")
+            space = unicode(" ")
+        else:
+            newline = "\n"
+            space = " "
+        if sep is None:
+            sep = space
+        if end is None:
+            end = newline
+        for i, arg in enumerate(args):
+            if i:
+                write(sep)
+            write(arg)
+        write(end)
+if sys.version_info[:2] < (3, 3):
+    _print = print_
+
+    def print_(*args, **kwargs):
+        fp = kwargs.get("file", sys.stdout)
+        flush = kwargs.pop("flush", False)
+        _print(*args, **kwargs)
+        if flush and fp is not None:
+            fp.flush()
+
+_add_doc(reraise, """Reraise an exception.""")
+
+if sys.version_info[0:2] < (3, 4):
+    def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
+              updated=functools.WRAPPER_UPDATES):
+        def wrapper(f):
+            f = functools.wraps(wrapped, assigned, updated)(f)
+            f.__wrapped__ = wrapped
+            return f
+        return wrapper
+else:
+    wraps = functools.wraps
+
+
+def with_metaclass(meta, *bases):
+    """Create a base class with a metaclass."""
+    # This requires a bit of explanation: the basic idea is to make a dummy
+    # metaclass for one level of class instantiation that replaces itself with
+    # the actual metaclass.
+    class metaclass(meta):
+
+        def __new__(cls, name, this_bases, d):
+            return meta(name, bases, d)
+    return type.__new__(metaclass, 'temporary_class', (), {})
+
+
+def add_metaclass(metaclass):
+    """Class decorator for creating a class with a metaclass."""
+    def wrapper(cls):
+        orig_vars = cls.__dict__.copy()
+        slots = orig_vars.get('__slots__')
+        if slots is not None:
+            if isinstance(slots, str):
+                slots = [slots]
+            for slots_var in slots:
+                orig_vars.pop(slots_var)
+        orig_vars.pop('__dict__', None)
+        orig_vars.pop('__weakref__', None)
+        return metaclass(cls.__name__, cls.__bases__, orig_vars)
+    return wrapper
+
+
+def python_2_unicode_compatible(klass):
+    """
+    A decorator that defines __unicode__ and __str__ methods under Python 2.
+    Under Python 3 it does nothing.
+
+    To support Python 2 and 3 with a single code base, define a __str__ method
+    returning text and apply this decorator to the class.
+    """
+    if PY2:
+        if '__str__' not in klass.__dict__:
+            raise ValueError("@python_2_unicode_compatible cannot be applied "
+                             "to %s because it doesn't define __str__()." %
+                             klass.__name__)
+        klass.__unicode__ = klass.__str__
+        klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
+    return klass
+
+
+# Complete the moves implementation.
+# This code is at the end of this module to speed up module loading.
+# Turn this module into a package.
+__path__ = []  # required for PEP 302 and PEP 451
+__package__ = __name__  # see PEP 366 @ReservedAssignment
+if globals().get("__spec__") is not None:
+    __spec__.submodule_search_locations = []  # PEP 451 @UndefinedVariable
+# Remove other six meta path importers, since they cause problems. This can
+# happen if six is removed from sys.modules and then reloaded. (Setuptools does
+# this for some reason.)
+if sys.meta_path:
+    for i, importer in enumerate(sys.meta_path):
+        # Here's some real nastiness: Another "instance" of the six module might
+        # be floating around. Therefore, we can't use isinstance() to check for
+        # the six meta path importer, since the other six instance will have
+        # inserted an importer with different class.
+        if (type(importer).__name__ == "_SixMetaPathImporter" and
+                importer.name == __name__):
+            del sys.meta_path[i]
+            break
+    del i, importer
+# Finally, add the importer to the meta path import hook.
+sys.meta_path.append(_importer)
diff --git a/vendor/setuptools-39.0.1/setuptools/_vendor/vendored.txt b/vendor/setuptools-39.0.1/setuptools/_vendor/vendored.txt
new file mode 100644
index 00000000..be3e72eb
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/_vendor/vendored.txt
@@ -0,0 +1,3 @@
+packaging==16.8
+pyparsing==2.1.10
+six==1.10.0
diff --git a/vendor/setuptools-39.0.1/setuptools/archive_util.py b/vendor/setuptools-39.0.1/setuptools/archive_util.py
new file mode 100755
index 00000000..81436044
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/archive_util.py
@@ -0,0 +1,173 @@
+"""Utilities for extracting common archive formats"""
+
+import zipfile
+import tarfile
+import os
+import shutil
+import posixpath
+import contextlib
+from distutils.errors import DistutilsError
+
+from pkg_resources import ensure_directory
+
+__all__ = [
+    "unpack_archive", "unpack_zipfile", "unpack_tarfile", "default_filter",
+    "UnrecognizedFormat", "extraction_drivers", "unpack_directory",
+]
+
+
+class UnrecognizedFormat(DistutilsError):
+    """Couldn't recognize the archive type"""
+
+
+def default_filter(src, dst):
+    """The default progress/filter callback; returns True for all files"""
+    return dst
+
+
+def unpack_archive(filename, extract_dir, progress_filter=default_filter,
+        drivers=None):
+    """Unpack `filename` to `extract_dir`, or raise ``UnrecognizedFormat``
+
+    `progress_filter` is a function taking two arguments: a source path
+    internal to the archive ('/'-separated), and a filesystem path where it
+    will be extracted.  The callback must return the desired extract path
+    (which may be the same as the one passed in), or else ``None`` to skip
+    that file or directory.  The callback can thus be used to report on the
+    progress of the extraction, as well as to filter the items extracted or
+    alter their extraction paths.
+
+    `drivers`, if supplied, must be a non-empty sequence of functions with the
+    same signature as this function (minus the `drivers` argument), that raise
+    ``UnrecognizedFormat`` if they do not support extracting the designated
+    archive type.  The `drivers` are tried in sequence until one is found that
+    does not raise an error, or until all are exhausted (in which case
+    ``UnrecognizedFormat`` is raised).  If you do not supply a sequence of
+    drivers, the module's ``extraction_drivers`` constant will be used, which
+    means that ``unpack_zipfile`` and ``unpack_tarfile`` will be tried, in that
+    order.
+    """
+    for driver in drivers or extraction_drivers:
+        try:
+            driver(filename, extract_dir, progress_filter)
+        except UnrecognizedFormat:
+            continue
+        else:
+            return
+    else:
+        raise UnrecognizedFormat(
+            "Not a recognized archive type: %s" % filename
+        )
+
+
+def unpack_directory(filename, extract_dir, progress_filter=default_filter):
+    """"Unpack" a directory, using the same interface as for archives
+
+    Raises ``UnrecognizedFormat`` if `filename` is not a directory
+    """
+    if not os.path.isdir(filename):
+        raise UnrecognizedFormat("%s is not a directory" % filename)
+
+    paths = {
+        filename: ('', extract_dir),
+    }
+    for base, dirs, files in os.walk(filename):
+        src, dst = paths[base]
+        for d in dirs:
+            paths[os.path.join(base, d)] = src + d + '/', os.path.join(dst, d)
+        for f in files:
+            target = os.path.join(dst, f)
+            target = progress_filter(src + f, target)
+            if not target:
+                # skip non-files
+                continue
+            ensure_directory(target)
+            f = os.path.join(base, f)
+            shutil.copyfile(f, target)
+            shutil.copystat(f, target)
+
+
+def unpack_zipfile(filename, extract_dir, progress_filter=default_filter):
+    """Unpack zip `filename` to `extract_dir`
+
+    Raises ``UnrecognizedFormat`` if `filename` is not a zipfile (as determined
+    by ``zipfile.is_zipfile()``).  See ``unpack_archive()`` for an explanation
+    of the `progress_filter` argument.
+    """
+
+    if not zipfile.is_zipfile(filename):
+        raise UnrecognizedFormat("%s is not a zip file" % (filename,))
+
+    with zipfile.ZipFile(filename) as z:
+        for info in z.infolist():
+            name = info.filename
+
+            # don't extract absolute paths or ones with .. in them
+            if name.startswith('/') or '..' in name.split('/'):
+                continue
+
+            target = os.path.join(extract_dir, *name.split('/'))
+            target = progress_filter(name, target)
+            if not target:
+                continue
+            if name.endswith('/'):
+                # directory
+                ensure_directory(target)
+            else:
+                # file
+                ensure_directory(target)
+                data = z.read(info.filename)
+                with open(target, 'wb') as f:
+                    f.write(data)
+            unix_attributes = info.external_attr >> 16
+            if unix_attributes:
+                os.chmod(target, unix_attributes)
+
+
+def unpack_tarfile(filename, extract_dir, progress_filter=default_filter):
+    """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir`
+
+    Raises ``UnrecognizedFormat`` if `filename` is not a tarfile (as determined
+    by ``tarfile.open()``).  See ``unpack_archive()`` for an explanation
+    of the `progress_filter` argument.
+    """
+    try:
+        tarobj = tarfile.open(filename)
+    except tarfile.TarError:
+        raise UnrecognizedFormat(
+            "%s is not a compressed or uncompressed tar file" % (filename,)
+        )
+    with contextlib.closing(tarobj):
+        # don't do any chowning!
+        tarobj.chown = lambda *args: None
+        for member in tarobj:
+            name = member.name
+            # don't extract absolute paths or ones with .. in them
+            if not name.startswith('/') and '..' not in name.split('/'):
+                prelim_dst = os.path.join(extract_dir, *name.split('/'))
+
+                # resolve any links and to extract the link targets as normal
+                # files
+                while member is not None and (member.islnk() or member.issym()):
+                    linkpath = member.linkname
+                    if member.issym():
+                        base = posixpath.dirname(member.name)
+                        linkpath = posixpath.join(base, linkpath)
+                        linkpath = posixpath.normpath(linkpath)
+                    member = tarobj._getmember(linkpath)
+
+                if member is not None and (member.isfile() or member.isdir()):
+                    final_dst = progress_filter(name, prelim_dst)
+                    if final_dst:
+                        if final_dst.endswith(os.sep):
+                            final_dst = final_dst[:-1]
+                        try:
+                            # XXX Ugh
+                            tarobj._extract_member(member, final_dst)
+                        except tarfile.ExtractError:
+                            # chown/chmod/mkfifo/mknode/makedev failed
+                            pass
+        return True
+
+
+extraction_drivers = unpack_directory, unpack_zipfile, unpack_tarfile
diff --git a/vendor/setuptools-39.0.1/setuptools/build_meta.py b/vendor/setuptools-39.0.1/setuptools/build_meta.py
new file mode 100644
index 00000000..609ea1e5
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/build_meta.py
@@ -0,0 +1,172 @@
+"""A PEP 517 interface to setuptools
+
+Previously, when a user or a command line tool (let's call it a "frontend")
+needed to make a request of setuptools to take a certain action, for
+example, generating a list of installation requirements, the frontend would
+would call "setup.py egg_info" or "setup.py bdist_wheel" on the command line.
+
+PEP 517 defines a different method of interfacing with setuptools. Rather
+than calling "setup.py" directly, the frontend should:
+
+  1. Set the current directory to the directory with a setup.py file
+  2. Import this module into a safe python interpreter (one in which
+     setuptools can potentially set global variables or crash hard).
+  3. Call one of the functions defined in PEP 517.
+
+What each function does is defined in PEP 517. However, here is a "casual"
+definition of the functions (this definition should not be relied on for
+bug reports or API stability):
+
+  - `build_wheel`: build a wheel in the folder and return the basename
+  - `get_requires_for_build_wheel`: get the `setup_requires` to build
+  - `prepare_metadata_for_build_wheel`: get the `install_requires`
+  - `build_sdist`: build an sdist in the folder and return the basename
+  - `get_requires_for_build_sdist`: get the `setup_requires` to build
+
+Again, this is not a formal definition! Just a "taste" of the module.
+"""
+
+import os
+import sys
+import tokenize
+import shutil
+import contextlib
+
+import setuptools
+import distutils
+
+
+class SetupRequirementsError(BaseException):
+    def __init__(self, specifiers):
+        self.specifiers = specifiers
+
+
+class Distribution(setuptools.dist.Distribution):
+    def fetch_build_eggs(self, specifiers):
+        raise SetupRequirementsError(specifiers)
+
+    @classmethod
+    @contextlib.contextmanager
+    def patch(cls):
+        """
+        Replace
+        distutils.dist.Distribution with this class
+        for the duration of this context.
+        """
+        orig = distutils.core.Distribution
+        distutils.core.Distribution = cls
+        try:
+            yield
+        finally:
+            distutils.core.Distribution = orig
+
+
+def _run_setup(setup_script='setup.py'):
+    # Note that we can reuse our build directory between calls
+    # Correctness comes first, then optimization later
+    __file__ = setup_script
+    __name__ = '__main__'
+    f = getattr(tokenize, 'open', open)(__file__)
+    code = f.read().replace('\\r\\n', '\\n')
+    f.close()
+    exec(compile(code, __file__, 'exec'), locals())
+
+
+def _fix_config(config_settings):
+    config_settings = config_settings or {}
+    config_settings.setdefault('--global-option', [])
+    return config_settings
+
+
+def _get_build_requires(config_settings):
+    config_settings = _fix_config(config_settings)
+    requirements = ['setuptools', 'wheel']
+
+    sys.argv = sys.argv[:1] + ['egg_info'] + \
+        config_settings["--global-option"]
+    try:
+        with Distribution.patch():
+            _run_setup()
+    except SetupRequirementsError as e:
+        requirements += e.specifiers
+
+    return requirements
+
+
+def _get_immediate_subdirectories(a_dir):
+    return [name for name in os.listdir(a_dir)
+            if os.path.isdir(os.path.join(a_dir, name))]
+
+
+def get_requires_for_build_wheel(config_settings=None):
+    config_settings = _fix_config(config_settings)
+    return _get_build_requires(config_settings)
+
+
+def get_requires_for_build_sdist(config_settings=None):
+    config_settings = _fix_config(config_settings)
+    return _get_build_requires(config_settings)
+
+
+def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
+    sys.argv = sys.argv[:1] + ['dist_info', '--egg-base', metadata_directory]
+    _run_setup()
+    
+    dist_info_directory = metadata_directory
+    while True:    
+        dist_infos = [f for f in os.listdir(dist_info_directory)
+                      if f.endswith('.dist-info')]
+
+        if len(dist_infos) == 0 and \
+                len(_get_immediate_subdirectories(dist_info_directory)) == 1:
+            dist_info_directory = os.path.join(
+                dist_info_directory, os.listdir(dist_info_directory)[0])
+            continue
+
+        assert len(dist_infos) == 1
+        break
+
+    # PEP 517 requires that the .dist-info directory be placed in the
+    # metadata_directory. To comply, we MUST copy the directory to the root
+    if dist_info_directory != metadata_directory:
+        shutil.move(
+            os.path.join(dist_info_directory, dist_infos[0]),
+            metadata_directory)
+        shutil.rmtree(dist_info_directory, ignore_errors=True)
+
+    return dist_infos[0]
+
+
+def build_wheel(wheel_directory, config_settings=None,
+                metadata_directory=None):
+    config_settings = _fix_config(config_settings)
+    wheel_directory = os.path.abspath(wheel_directory)
+    sys.argv = sys.argv[:1] + ['bdist_wheel'] + \
+        config_settings["--global-option"]
+    _run_setup()
+    if wheel_directory != 'dist':
+        shutil.rmtree(wheel_directory)
+        shutil.copytree('dist', wheel_directory)
+
+    wheels = [f for f in os.listdir(wheel_directory)
+              if f.endswith('.whl')]
+
+    assert len(wheels) == 1
+    return wheels[0]
+
+
+def build_sdist(sdist_directory, config_settings=None):
+    config_settings = _fix_config(config_settings)
+    sdist_directory = os.path.abspath(sdist_directory)
+    sys.argv = sys.argv[:1] + ['sdist'] + \
+        config_settings["--global-option"]
+    _run_setup()
+    if sdist_directory != 'dist':
+        shutil.rmtree(sdist_directory)
+        shutil.copytree('dist', sdist_directory)
+
+    sdists = [f for f in os.listdir(sdist_directory)
+              if f.endswith('.tar.gz')]
+
+    assert len(sdists) == 1
+    return sdists[0]
diff --git a/vendor/setuptools-39.0.1/setuptools/cli-32.exe b/vendor/setuptools-39.0.1/setuptools/cli-32.exe
new file mode 100644
index 0000000000000000000000000000000000000000..b1487b7819e7286577a043c7726fbe0ca1543083
GIT binary patch
literal 65536
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

literal 0
HcmV?d00001

diff --git a/vendor/setuptools-39.0.1/setuptools/cli-64.exe b/vendor/setuptools-39.0.1/setuptools/cli-64.exe
new file mode 100644
index 0000000000000000000000000000000000000000..675e6bf3743f3d3011c238657e7128ee9960ef7f
GIT binary patch
literal 74752
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

literal 0
HcmV?d00001

diff --git a/vendor/setuptools-39.0.1/setuptools/cli.exe b/vendor/setuptools-39.0.1/setuptools/cli.exe
new file mode 100644
index 0000000000000000000000000000000000000000..b1487b7819e7286577a043c7726fbe0ca1543083
GIT binary patch
literal 65536
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

literal 0
HcmV?d00001

diff --git a/vendor/setuptools-39.0.1/setuptools/command/__init__.py b/vendor/setuptools-39.0.1/setuptools/command/__init__.py
new file mode 100644
index 00000000..fe619e2e
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/__init__.py
@@ -0,0 +1,18 @@
+__all__ = [
+    'alias', 'bdist_egg', 'bdist_rpm', 'build_ext', 'build_py', 'develop',
+    'easy_install', 'egg_info', 'install', 'install_lib', 'rotate', 'saveopts',
+    'sdist', 'setopt', 'test', 'install_egg_info', 'install_scripts',
+    'register', 'bdist_wininst', 'upload_docs', 'upload', 'build_clib',
+    'dist_info',
+]
+
+from distutils.command.bdist import bdist
+import sys
+
+from setuptools.command import install_scripts
+
+if 'egg' not in bdist.format_commands:
+    bdist.format_command['egg'] = ('bdist_egg', "Python .egg file")
+    bdist.format_commands.append('egg')
+
+del bdist, sys
diff --git a/vendor/setuptools-39.0.1/setuptools/command/alias.py b/vendor/setuptools-39.0.1/setuptools/command/alias.py
new file mode 100755
index 00000000..4532b1cc
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/alias.py
@@ -0,0 +1,80 @@
+from distutils.errors import DistutilsOptionError
+
+from setuptools.extern.six.moves import map
+
+from setuptools.command.setopt import edit_config, option_base, config_file
+
+
+def shquote(arg):
+    """Quote an argument for later parsing by shlex.split()"""
+    for c in '"', "'", "\\", "#":
+        if c in arg:
+            return repr(arg)
+    if arg.split() != [arg]:
+        return repr(arg)
+    return arg
+
+
+class alias(option_base):
+    """Define a shortcut that invokes one or more commands"""
+
+    description = "define a shortcut to invoke one or more commands"
+    command_consumes_arguments = True
+
+    user_options = [
+        ('remove', 'r', 'remove (unset) the alias'),
+    ] + option_base.user_options
+
+    boolean_options = option_base.boolean_options + ['remove']
+
+    def initialize_options(self):
+        option_base.initialize_options(self)
+        self.args = None
+        self.remove = None
+
+    def finalize_options(self):
+        option_base.finalize_options(self)
+        if self.remove and len(self.args) != 1:
+            raise DistutilsOptionError(
+                "Must specify exactly one argument (the alias name) when "
+                "using --remove"
+            )
+
+    def run(self):
+        aliases = self.distribution.get_option_dict('aliases')
+
+        if not self.args:
+            print("Command Aliases")
+            print("---------------")
+            for alias in aliases:
+                print("setup.py alias", format_alias(alias, aliases))
+            return
+
+        elif len(self.args) == 1:
+            alias, = self.args
+            if self.remove:
+                command = None
+            elif alias in aliases:
+                print("setup.py alias", format_alias(alias, aliases))
+                return
+            else:
+                print("No alias definition found for %r" % alias)
+                return
+        else:
+            alias = self.args[0]
+            command = ' '.join(map(shquote, self.args[1:]))
+
+        edit_config(self.filename, {'aliases': {alias: command}}, self.dry_run)
+
+
+def format_alias(name, aliases):
+    source, command = aliases[name]
+    if source == config_file('global'):
+        source = '--global-config '
+    elif source == config_file('user'):
+        source = '--user-config '
+    elif source == config_file('local'):
+        source = ''
+    else:
+        source = '--filename=%r' % source
+    return source + name + ' ' + command
diff --git a/vendor/setuptools-39.0.1/setuptools/command/bdist_egg.py b/vendor/setuptools-39.0.1/setuptools/command/bdist_egg.py
new file mode 100644
index 00000000..423b8187
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/bdist_egg.py
@@ -0,0 +1,502 @@
+"""setuptools.command.bdist_egg
+
+Build .egg distributions"""
+
+from distutils.errors import DistutilsSetupError
+from distutils.dir_util import remove_tree, mkpath
+from distutils import log
+from types import CodeType
+import sys
+import os
+import re
+import textwrap
+import marshal
+
+from setuptools.extern import six
+
+from pkg_resources import get_build_platform, Distribution, ensure_directory
+from pkg_resources import EntryPoint
+from setuptools.extension import Library
+from setuptools import Command
+
+try:
+    # Python 2.7 or >=3.2
+    from sysconfig import get_path, get_python_version
+
+    def _get_purelib():
+        return get_path("purelib")
+except ImportError:
+    from distutils.sysconfig import get_python_lib, get_python_version
+
+    def _get_purelib():
+        return get_python_lib(False)
+
+
+def strip_module(filename):
+    if '.' in filename:
+        filename = os.path.splitext(filename)[0]
+    if filename.endswith('module'):
+        filename = filename[:-6]
+    return filename
+
+
+def sorted_walk(dir):
+    """Do os.walk in a reproducible way,
+    independent of indeterministic filesystem readdir order
+    """
+    for base, dirs, files in os.walk(dir):
+        dirs.sort()
+        files.sort()
+        yield base, dirs, files
+
+
+def write_stub(resource, pyfile):
+    _stub_template = textwrap.dedent("""
+        def __bootstrap__():
+            global __bootstrap__, __loader__, __file__
+            import sys, pkg_resources, imp
+            __file__ = pkg_resources.resource_filename(__name__, %r)
+            __loader__ = None; del __bootstrap__, __loader__
+            imp.load_dynamic(__name__,__file__)
+        __bootstrap__()
+        """).lstrip()
+    with open(pyfile, 'w') as f:
+        f.write(_stub_template % resource)
+
+
+class bdist_egg(Command):
+    description = "create an \"egg\" distribution"
+
+    user_options = [
+        ('bdist-dir=', 'b',
+         "temporary directory for creating the distribution"),
+        ('plat-name=', 'p', "platform name to embed in generated filenames "
+                            "(default: %s)" % get_build_platform()),
+        ('exclude-source-files', None,
+         "remove all .py files from the generated egg"),
+        ('keep-temp', 'k',
+         "keep the pseudo-installation tree around after " +
+         "creating the distribution archive"),
+        ('dist-dir=', 'd',
+         "directory to put final built distributions in"),
+        ('skip-build', None,
+         "skip rebuilding everything (for testing/debugging)"),
+    ]
+
+    boolean_options = [
+        'keep-temp', 'skip-build', 'exclude-source-files'
+    ]
+
+    def initialize_options(self):
+        self.bdist_dir = None
+        self.plat_name = None
+        self.keep_temp = 0
+        self.dist_dir = None
+        self.skip_build = 0
+        self.egg_output = None
+        self.exclude_source_files = None
+
+    def finalize_options(self):
+        ei_cmd = self.ei_cmd = self.get_finalized_command("egg_info")
+        self.egg_info = ei_cmd.egg_info
+
+        if self.bdist_dir is None:
+            bdist_base = self.get_finalized_command('bdist').bdist_base
+            self.bdist_dir = os.path.join(bdist_base, 'egg')
+
+        if self.plat_name is None:
+            self.plat_name = get_build_platform()
+
+        self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
+
+        if self.egg_output is None:
+
+            # Compute filename of the output egg
+            basename = Distribution(
+                None, None, ei_cmd.egg_name, ei_cmd.egg_version,
+                get_python_version(),
+                self.distribution.has_ext_modules() and self.plat_name
+            ).egg_name()
+
+            self.egg_output = os.path.join(self.dist_dir, basename + '.egg')
+
+    def do_install_data(self):
+        # Hack for packages that install data to install's --install-lib
+        self.get_finalized_command('install').install_lib = self.bdist_dir
+
+        site_packages = os.path.normcase(os.path.realpath(_get_purelib()))
+        old, self.distribution.data_files = self.distribution.data_files, []
+
+        for item in old:
+            if isinstance(item, tuple) and len(item) == 2:
+                if os.path.isabs(item[0]):
+                    realpath = os.path.realpath(item[0])
+                    normalized = os.path.normcase(realpath)
+                    if normalized == site_packages or normalized.startswith(
+                        site_packages + os.sep
+                    ):
+                        item = realpath[len(site_packages) + 1:], item[1]
+                        # XXX else: raise ???
+            self.distribution.data_files.append(item)
+
+        try:
+            log.info("installing package data to %s", self.bdist_dir)
+            self.call_command('install_data', force=0, root=None)
+        finally:
+            self.distribution.data_files = old
+
+    def get_outputs(self):
+        return [self.egg_output]
+
+    def call_command(self, cmdname, **kw):
+        """Invoke reinitialized command `cmdname` with keyword args"""
+        for dirname in INSTALL_DIRECTORY_ATTRS:
+            kw.setdefault(dirname, self.bdist_dir)
+        kw.setdefault('skip_build', self.skip_build)
+        kw.setdefault('dry_run', self.dry_run)
+        cmd = self.reinitialize_command(cmdname, **kw)
+        self.run_command(cmdname)
+        return cmd
+
+    def run(self):
+        # Generate metadata first
+        self.run_command("egg_info")
+        # We run install_lib before install_data, because some data hacks
+        # pull their data path from the install_lib command.
+        log.info("installing library code to %s", self.bdist_dir)
+        instcmd = self.get_finalized_command('install')
+        old_root = instcmd.root
+        instcmd.root = None
+        if self.distribution.has_c_libraries() and not self.skip_build:
+            self.run_command('build_clib')
+        cmd = self.call_command('install_lib', warn_dir=0)
+        instcmd.root = old_root
+
+        all_outputs, ext_outputs = self.get_ext_outputs()
+        self.stubs = []
+        to_compile = []
+        for (p, ext_name) in enumerate(ext_outputs):
+            filename, ext = os.path.splitext(ext_name)
+            pyfile = os.path.join(self.bdist_dir, strip_module(filename) +
+                                  '.py')
+            self.stubs.append(pyfile)
+            log.info("creating stub loader for %s", ext_name)
+            if not self.dry_run:
+                write_stub(os.path.basename(ext_name), pyfile)
+            to_compile.append(pyfile)
+            ext_outputs[p] = ext_name.replace(os.sep, '/')
+
+        if to_compile:
+            cmd.byte_compile(to_compile)
+        if self.distribution.data_files:
+            self.do_install_data()
+
+        # Make the EGG-INFO directory
+        archive_root = self.bdist_dir
+        egg_info = os.path.join(archive_root, 'EGG-INFO')
+        self.mkpath(egg_info)
+        if self.distribution.scripts:
+            script_dir = os.path.join(egg_info, 'scripts')
+            log.info("installing scripts to %s", script_dir)
+            self.call_command('install_scripts', install_dir=script_dir,
+                              no_ep=1)
+
+        self.copy_metadata_to(egg_info)
+        native_libs = os.path.join(egg_info, "native_libs.txt")
+        if all_outputs:
+            log.info("writing %s", native_libs)
+            if not self.dry_run:
+                ensure_directory(native_libs)
+                libs_file = open(native_libs, 'wt')
+                libs_file.write('\n'.join(all_outputs))
+                libs_file.write('\n')
+                libs_file.close()
+        elif os.path.isfile(native_libs):
+            log.info("removing %s", native_libs)
+            if not self.dry_run:
+                os.unlink(native_libs)
+
+        write_safety_flag(
+            os.path.join(archive_root, 'EGG-INFO'), self.zip_safe()
+        )
+
+        if os.path.exists(os.path.join(self.egg_info, 'depends.txt')):
+            log.warn(
+                "WARNING: 'depends.txt' will not be used by setuptools 0.6!\n"
+                "Use the install_requires/extras_require setup() args instead."
+            )
+
+        if self.exclude_source_files:
+            self.zap_pyfiles()
+
+        # Make the archive
+        make_zipfile(self.egg_output, archive_root, verbose=self.verbose,
+                     dry_run=self.dry_run, mode=self.gen_header())
+        if not self.keep_temp:
+            remove_tree(self.bdist_dir, dry_run=self.dry_run)
+
+        # Add to 'Distribution.dist_files' so that the "upload" command works
+        getattr(self.distribution, 'dist_files', []).append(
+            ('bdist_egg', get_python_version(), self.egg_output))
+
+    def zap_pyfiles(self):
+        log.info("Removing .py files from temporary directory")
+        for base, dirs, files in walk_egg(self.bdist_dir):
+            for name in files:
+                path = os.path.join(base, name)
+
+                if name.endswith('.py'):
+                    log.debug("Deleting %s", path)
+                    os.unlink(path)
+
+                if base.endswith('__pycache__'):
+                    path_old = path
+
+                    pattern = r'(?P<name>.+)\.(?P<magic>[^.]+)\.pyc'
+                    m = re.match(pattern, name)
+                    path_new = os.path.join(
+                        base, os.pardir, m.group('name') + '.pyc')
+                    log.info(
+                        "Renaming file from [%s] to [%s]"
+                        % (path_old, path_new))
+                    try:
+                        os.remove(path_new)
+                    except OSError:
+                        pass
+                    os.rename(path_old, path_new)
+
+    def zip_safe(self):
+        safe = getattr(self.distribution, 'zip_safe', None)
+        if safe is not None:
+            return safe
+        log.warn("zip_safe flag not set; analyzing archive contents...")
+        return analyze_egg(self.bdist_dir, self.stubs)
+
+    def gen_header(self):
+        epm = EntryPoint.parse_map(self.distribution.entry_points or '')
+        ep = epm.get('setuptools.installation', {}).get('eggsecutable')
+        if ep is None:
+            return 'w'  # not an eggsecutable, do it the usual way.
+
+        if not ep.attrs or ep.extras:
+            raise DistutilsSetupError(
+                "eggsecutable entry point (%r) cannot have 'extras' "
+                "or refer to a module" % (ep,)
+            )
+
+        pyver = sys.version[:3]
+        pkg = ep.module_name
+        full = '.'.join(ep.attrs)
+        base = ep.attrs[0]
+        basename = os.path.basename(self.egg_output)
+
+        header = (
+            "#!/bin/sh\n"
+            'if [ `basename $0` = "%(basename)s" ]\n'
+            'then exec python%(pyver)s -c "'
+            "import sys, os; sys.path.insert(0, os.path.abspath('$0')); "
+            "from %(pkg)s import %(base)s; sys.exit(%(full)s())"
+            '" "$@"\n'
+            'else\n'
+            '  echo $0 is not the correct name for this egg file.\n'
+            '  echo Please rename it back to %(basename)s and try again.\n'
+            '  exec false\n'
+            'fi\n'
+        ) % locals()
+
+        if not self.dry_run:
+            mkpath(os.path.dirname(self.egg_output), dry_run=self.dry_run)
+            f = open(self.egg_output, 'w')
+            f.write(header)
+            f.close()
+        return 'a'
+
+    def copy_metadata_to(self, target_dir):
+        "Copy metadata (egg info) to the target_dir"
+        # normalize the path (so that a forward-slash in egg_info will
+        # match using startswith below)
+        norm_egg_info = os.path.normpath(self.egg_info)
+        prefix = os.path.join(norm_egg_info, '')
+        for path in self.ei_cmd.filelist.files:
+            if path.startswith(prefix):
+                target = os.path.join(target_dir, path[len(prefix):])
+                ensure_directory(target)
+                self.copy_file(path, target)
+
+    def get_ext_outputs(self):
+        """Get a list of relative paths to C extensions in the output distro"""
+
+        all_outputs = []
+        ext_outputs = []
+
+        paths = {self.bdist_dir: ''}
+        for base, dirs, files in sorted_walk(self.bdist_dir):
+            for filename in files:
+                if os.path.splitext(filename)[1].lower() in NATIVE_EXTENSIONS:
+                    all_outputs.append(paths[base] + filename)
+            for filename in dirs:
+                paths[os.path.join(base, filename)] = (paths[base] +
+                                                       filename + '/')
+
+        if self.distribution.has_ext_modules():
+            build_cmd = self.get_finalized_command('build_ext')
+            for ext in build_cmd.extensions:
+                if isinstance(ext, Library):
+                    continue
+                fullname = build_cmd.get_ext_fullname(ext.name)
+                filename = build_cmd.get_ext_filename(fullname)
+                if not os.path.basename(filename).startswith('dl-'):
+                    if os.path.exists(os.path.join(self.bdist_dir, filename)):
+                        ext_outputs.append(filename)
+
+        return all_outputs, ext_outputs
+
+
+NATIVE_EXTENSIONS = dict.fromkeys('.dll .so .dylib .pyd'.split())
+
+
+def walk_egg(egg_dir):
+    """Walk an unpacked egg's contents, skipping the metadata directory"""
+    walker = sorted_walk(egg_dir)
+    base, dirs, files = next(walker)
+    if 'EGG-INFO' in dirs:
+        dirs.remove('EGG-INFO')
+    yield base, dirs, files
+    for bdf in walker:
+        yield bdf
+
+
+def analyze_egg(egg_dir, stubs):
+    # check for existing flag in EGG-INFO
+    for flag, fn in safety_flags.items():
+        if os.path.exists(os.path.join(egg_dir, 'EGG-INFO', fn)):
+            return flag
+    if not can_scan():
+        return False
+    safe = True
+    for base, dirs, files in walk_egg(egg_dir):
+        for name in files:
+            if name.endswith('.py') or name.endswith('.pyw'):
+                continue
+            elif name.endswith('.pyc') or name.endswith('.pyo'):
+                # always scan, even if we already know we're not safe
+                safe = scan_module(egg_dir, base, name, stubs) and safe
+    return safe
+
+
+def write_safety_flag(egg_dir, safe):
+    # Write or remove zip safety flag file(s)
+    for flag, fn in safety_flags.items():
+        fn = os.path.join(egg_dir, fn)
+        if os.path.exists(fn):
+            if safe is None or bool(safe) != flag:
+                os.unlink(fn)
+        elif safe is not None and bool(safe) == flag:
+            f = open(fn, 'wt')
+            f.write('\n')
+            f.close()
+
+
+safety_flags = {
+    True: 'zip-safe',
+    False: 'not-zip-safe',
+}
+
+
+def scan_module(egg_dir, base, name, stubs):
+    """Check whether module possibly uses unsafe-for-zipfile stuff"""
+
+    filename = os.path.join(base, name)
+    if filename[:-1] in stubs:
+        return True  # Extension module
+    pkg = base[len(egg_dir) + 1:].replace(os.sep, '.')
+    module = pkg + (pkg and '.' or '') + os.path.splitext(name)[0]
+    if sys.version_info < (3, 3):
+        skip = 8  # skip magic & date
+    elif sys.version_info < (3, 7):
+        skip = 12  # skip magic & date & file size
+    else:
+        skip = 16  # skip magic & reserved? & date & file size
+    f = open(filename, 'rb')
+    f.read(skip)
+    code = marshal.load(f)
+    f.close()
+    safe = True
+    symbols = dict.fromkeys(iter_symbols(code))
+    for bad in ['__file__', '__path__']:
+        if bad in symbols:
+            log.warn("%s: module references %s", module, bad)
+            safe = False
+    if 'inspect' in symbols:
+        for bad in [
+            'getsource', 'getabsfile', 'getsourcefile', 'getfile'
+            'getsourcelines', 'findsource', 'getcomments', 'getframeinfo',
+            'getinnerframes', 'getouterframes', 'stack', 'trace'
+        ]:
+            if bad in symbols:
+                log.warn("%s: module MAY be using inspect.%s", module, bad)
+                safe = False
+    return safe
+
+
+def iter_symbols(code):
+    """Yield names and strings used by `code` and its nested code objects"""
+    for name in code.co_names:
+        yield name
+    for const in code.co_consts:
+        if isinstance(const, six.string_types):
+            yield const
+        elif isinstance(const, CodeType):
+            for name in iter_symbols(const):
+                yield name
+
+
+def can_scan():
+    if not sys.platform.startswith('java') and sys.platform != 'cli':
+        # CPython, PyPy, etc.
+        return True
+    log.warn("Unable to analyze compiled code on this platform.")
+    log.warn("Please ask the author to include a 'zip_safe'"
+             " setting (either True or False) in the package's setup.py")
+
+
+# Attribute names of options for commands that might need to be convinced to
+# install to the egg build directory
+
+INSTALL_DIRECTORY_ATTRS = [
+    'install_lib', 'install_dir', 'install_data', 'install_base'
+]
+
+
+def make_zipfile(zip_filename, base_dir, verbose=0, dry_run=0, compress=True,
+                 mode='w'):
+    """Create a zip file from all the files under 'base_dir'.  The output
+    zip file will be named 'base_dir' + ".zip".  Uses either the "zipfile"
+    Python module (if available) or the InfoZIP "zip" utility (if installed
+    and found on the default search path).  If neither tool is available,
+    raises DistutilsExecError.  Returns the name of the output zip file.
+    """
+    import zipfile
+
+    mkpath(os.path.dirname(zip_filename), dry_run=dry_run)
+    log.info("creating '%s' and adding '%s' to it", zip_filename, base_dir)
+
+    def visit(z, dirname, names):
+        for name in names:
+            path = os.path.normpath(os.path.join(dirname, name))
+            if os.path.isfile(path):
+                p = path[len(base_dir) + 1:]
+                if not dry_run:
+                    z.write(path, p)
+                log.debug("adding '%s'", p)
+
+    compression = zipfile.ZIP_DEFLATED if compress else zipfile.ZIP_STORED
+    if not dry_run:
+        z = zipfile.ZipFile(zip_filename, mode, compression=compression)
+        for dirname, dirs, files in sorted_walk(base_dir):
+            visit(z, dirname, files)
+        z.close()
+    else:
+        for dirname, dirs, files in sorted_walk(base_dir):
+            visit(None, dirname, files)
+    return zip_filename
diff --git a/vendor/setuptools-39.0.1/setuptools/command/bdist_rpm.py b/vendor/setuptools-39.0.1/setuptools/command/bdist_rpm.py
new file mode 100755
index 00000000..70730927
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/bdist_rpm.py
@@ -0,0 +1,43 @@
+import distutils.command.bdist_rpm as orig
+
+
+class bdist_rpm(orig.bdist_rpm):
+    """
+    Override the default bdist_rpm behavior to do the following:
+
+    1. Run egg_info to ensure the name and version are properly calculated.
+    2. Always run 'install' using --single-version-externally-managed to
+       disable eggs in RPM distributions.
+    3. Replace dash with underscore in the version numbers for better RPM
+       compatibility.
+    """
+
+    def run(self):
+        # ensure distro name is up-to-date
+        self.run_command('egg_info')
+
+        orig.bdist_rpm.run(self)
+
+    def _make_spec_file(self):
+        version = self.distribution.get_version()
+        rpmversion = version.replace('-', '_')
+        spec = orig.bdist_rpm._make_spec_file(self)
+        line23 = '%define version ' + version
+        line24 = '%define version ' + rpmversion
+        spec = [
+            line.replace(
+                "Source0: %{name}-%{version}.tar",
+                "Source0: %{name}-%{unmangled_version}.tar"
+            ).replace(
+                "setup.py install ",
+                "setup.py install --single-version-externally-managed "
+            ).replace(
+                "%setup",
+                "%setup -n %{name}-%{unmangled_version}"
+            ).replace(line23, line24)
+            for line in spec
+        ]
+        insert_loc = spec.index(line24) + 1
+        unmangled_version = "%define unmangled_version " + version
+        spec.insert(insert_loc, unmangled_version)
+        return spec
diff --git a/vendor/setuptools-39.0.1/setuptools/command/bdist_wininst.py b/vendor/setuptools-39.0.1/setuptools/command/bdist_wininst.py
new file mode 100755
index 00000000..073de97b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/bdist_wininst.py
@@ -0,0 +1,21 @@
+import distutils.command.bdist_wininst as orig
+
+
+class bdist_wininst(orig.bdist_wininst):
+    def reinitialize_command(self, command, reinit_subcommands=0):
+        """
+        Supplement reinitialize_command to work around
+        http://bugs.python.org/issue20819
+        """
+        cmd = self.distribution.reinitialize_command(
+            command, reinit_subcommands)
+        if command in ('install', 'install_lib'):
+            cmd.install_lib = None
+        return cmd
+
+    def run(self):
+        self._is_running = True
+        try:
+            orig.bdist_wininst.run(self)
+        finally:
+            self._is_running = False
diff --git a/vendor/setuptools-39.0.1/setuptools/command/build_clib.py b/vendor/setuptools-39.0.1/setuptools/command/build_clib.py
new file mode 100644
index 00000000..09caff6f
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/build_clib.py
@@ -0,0 +1,98 @@
+import distutils.command.build_clib as orig
+from distutils.errors import DistutilsSetupError
+from distutils import log
+from setuptools.dep_util import newer_pairwise_group
+
+
+class build_clib(orig.build_clib):
+    """
+    Override the default build_clib behaviour to do the following:
+
+    1. Implement a rudimentary timestamp-based dependency system
+       so 'compile()' doesn't run every time.
+    2. Add more keys to the 'build_info' dictionary:
+        * obj_deps - specify dependencies for each object compiled.
+                     this should be a dictionary mapping a key
+                     with the source filename to a list of
+                     dependencies. Use an empty string for global
+                     dependencies.
+        * cflags   - specify a list of additional flags to pass to
+                     the compiler.
+    """
+
+    def build_libraries(self, libraries):
+        for (lib_name, build_info) in libraries:
+            sources = build_info.get('sources')
+            if sources is None or not isinstance(sources, (list, tuple)):
+                raise DistutilsSetupError(
+                       "in 'libraries' option (library '%s'), "
+                       "'sources' must be present and must be "
+                       "a list of source filenames" % lib_name)
+            sources = list(sources)
+
+            log.info("building '%s' library", lib_name)
+
+            # Make sure everything is the correct type.
+            # obj_deps should be a dictionary of keys as sources
+            # and a list/tuple of files that are its dependencies.
+            obj_deps = build_info.get('obj_deps', dict())
+            if not isinstance(obj_deps, dict):
+                raise DistutilsSetupError(
+                       "in 'libraries' option (library '%s'), "
+                       "'obj_deps' must be a dictionary of "
+                       "type 'source: list'" % lib_name)
+            dependencies = []
+
+            # Get the global dependencies that are specified by the '' key.
+            # These will go into every source's dependency list.
+            global_deps = obj_deps.get('', list())
+            if not isinstance(global_deps, (list, tuple)):
+                raise DistutilsSetupError(
+                       "in 'libraries' option (library '%s'), "
+                       "'obj_deps' must be a dictionary of "
+                       "type 'source: list'" % lib_name)
+
+            # Build the list to be used by newer_pairwise_group
+            # each source will be auto-added to its dependencies.
+            for source in sources:
+                src_deps = [source]
+                src_deps.extend(global_deps)
+                extra_deps = obj_deps.get(source, list())
+                if not isinstance(extra_deps, (list, tuple)):
+                    raise DistutilsSetupError(
+                           "in 'libraries' option (library '%s'), "
+                           "'obj_deps' must be a dictionary of "
+                           "type 'source: list'" % lib_name)
+                src_deps.extend(extra_deps)
+                dependencies.append(src_deps)
+
+            expected_objects = self.compiler.object_filenames(
+                    sources,
+                    output_dir=self.build_temp
+                    )
+
+            if newer_pairwise_group(dependencies, expected_objects) != ([], []):
+                # First, compile the source code to object files in the library
+                # directory.  (This should probably change to putting object
+                # files in a temporary build directory.)
+                macros = build_info.get('macros')
+                include_dirs = build_info.get('include_dirs')
+                cflags = build_info.get('cflags')
+                objects = self.compiler.compile(
+                        sources,
+                        output_dir=self.build_temp,
+                        macros=macros,
+                        include_dirs=include_dirs,
+                        extra_postargs=cflags,
+                        debug=self.debug
+                        )
+
+            # Now "link" the object files together into a static library.
+            # (On Unix at least, this isn't really linking -- it just
+            # builds an archive.  Whatever.)
+            self.compiler.create_static_lib(
+                    expected_objects,
+                    lib_name,
+                    output_dir=self.build_clib,
+                    debug=self.debug
+                    )
diff --git a/vendor/setuptools-39.0.1/setuptools/command/build_ext.py b/vendor/setuptools-39.0.1/setuptools/command/build_ext.py
new file mode 100644
index 00000000..ea97b37b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/build_ext.py
@@ -0,0 +1,331 @@
+import os
+import sys
+import itertools
+import imp
+from distutils.command.build_ext import build_ext as _du_build_ext
+from distutils.file_util import copy_file
+from distutils.ccompiler import new_compiler
+from distutils.sysconfig import customize_compiler, get_config_var
+from distutils.errors import DistutilsError
+from distutils import log
+
+from setuptools.extension import Library
+from setuptools.extern import six
+
+try:
+    # Attempt to use Cython for building extensions, if available
+    from Cython.Distutils.build_ext import build_ext as _build_ext
+    # Additionally, assert that the compiler module will load
+    # also. Ref #1229.
+    __import__('Cython.Compiler.Main')
+except ImportError:
+    _build_ext = _du_build_ext
+
+# make sure _config_vars is initialized
+get_config_var("LDSHARED")
+from distutils.sysconfig import _config_vars as _CONFIG_VARS
+
+
+def _customize_compiler_for_shlib(compiler):
+    if sys.platform == "darwin":
+        # building .dylib requires additional compiler flags on OSX; here we
+        # temporarily substitute the pyconfig.h variables so that distutils'
+        # 'customize_compiler' uses them before we build the shared libraries.
+        tmp = _CONFIG_VARS.copy()
+        try:
+            # XXX Help!  I don't have any idea whether these are right...
+            _CONFIG_VARS['LDSHARED'] = (
+                "gcc -Wl,-x -dynamiclib -undefined dynamic_lookup")
+            _CONFIG_VARS['CCSHARED'] = " -dynamiclib"
+            _CONFIG_VARS['SO'] = ".dylib"
+            customize_compiler(compiler)
+        finally:
+            _CONFIG_VARS.clear()
+            _CONFIG_VARS.update(tmp)
+    else:
+        customize_compiler(compiler)
+
+
+have_rtld = False
+use_stubs = False
+libtype = 'shared'
+
+if sys.platform == "darwin":
+    use_stubs = True
+elif os.name != 'nt':
+    try:
+        import dl
+        use_stubs = have_rtld = hasattr(dl, 'RTLD_NOW')
+    except ImportError:
+        pass
+
+if_dl = lambda s: s if have_rtld else ''
+
+
+def get_abi3_suffix():
+    """Return the file extension for an abi3-compliant Extension()"""
+    for suffix, _, _ in (s for s in imp.get_suffixes() if s[2] == imp.C_EXTENSION):
+        if '.abi3' in suffix:  # Unix
+            return suffix
+        elif suffix == '.pyd':  # Windows
+            return suffix
+
+
+class build_ext(_build_ext):
+    def run(self):
+        """Build extensions in build directory, then copy if --inplace"""
+        old_inplace, self.inplace = self.inplace, 0
+        _build_ext.run(self)
+        self.inplace = old_inplace
+        if old_inplace:
+            self.copy_extensions_to_source()
+
+    def copy_extensions_to_source(self):
+        build_py = self.get_finalized_command('build_py')
+        for ext in self.extensions:
+            fullname = self.get_ext_fullname(ext.name)
+            filename = self.get_ext_filename(fullname)
+            modpath = fullname.split('.')
+            package = '.'.join(modpath[:-1])
+            package_dir = build_py.get_package_dir(package)
+            dest_filename = os.path.join(package_dir,
+                                         os.path.basename(filename))
+            src_filename = os.path.join(self.build_lib, filename)
+
+            # Always copy, even if source is older than destination, to ensure
+            # that the right extensions for the current Python/platform are
+            # used.
+            copy_file(
+                src_filename, dest_filename, verbose=self.verbose,
+                dry_run=self.dry_run
+            )
+            if ext._needs_stub:
+                self.write_stub(package_dir or os.curdir, ext, True)
+
+    def get_ext_filename(self, fullname):
+        filename = _build_ext.get_ext_filename(self, fullname)
+        if fullname in self.ext_map:
+            ext = self.ext_map[fullname]
+            use_abi3 = (
+                six.PY3
+                and getattr(ext, 'py_limited_api')
+                and get_abi3_suffix()
+            )
+            if use_abi3:
+                so_ext = _get_config_var_837('EXT_SUFFIX')
+                filename = filename[:-len(so_ext)]
+                filename = filename + get_abi3_suffix()
+            if isinstance(ext, Library):
+                fn, ext = os.path.splitext(filename)
+                return self.shlib_compiler.library_filename(fn, libtype)
+            elif use_stubs and ext._links_to_dynamic:
+                d, fn = os.path.split(filename)
+                return os.path.join(d, 'dl-' + fn)
+        return filename
+
+    def initialize_options(self):
+        _build_ext.initialize_options(self)
+        self.shlib_compiler = None
+        self.shlibs = []
+        self.ext_map = {}
+
+    def finalize_options(self):
+        _build_ext.finalize_options(self)
+        self.extensions = self.extensions or []
+        self.check_extensions_list(self.extensions)
+        self.shlibs = [ext for ext in self.extensions
+                       if isinstance(ext, Library)]
+        if self.shlibs:
+            self.setup_shlib_compiler()
+        for ext in self.extensions:
+            ext._full_name = self.get_ext_fullname(ext.name)
+        for ext in self.extensions:
+            fullname = ext._full_name
+            self.ext_map[fullname] = ext
+
+            # distutils 3.1 will also ask for module names
+            # XXX what to do with conflicts?
+            self.ext_map[fullname.split('.')[-1]] = ext
+
+            ltd = self.shlibs and self.links_to_dynamic(ext) or False
+            ns = ltd and use_stubs and not isinstance(ext, Library)
+            ext._links_to_dynamic = ltd
+            ext._needs_stub = ns
+            filename = ext._file_name = self.get_ext_filename(fullname)
+            libdir = os.path.dirname(os.path.join(self.build_lib, filename))
+            if ltd and libdir not in ext.library_dirs:
+                ext.library_dirs.append(libdir)
+            if ltd and use_stubs and os.curdir not in ext.runtime_library_dirs:
+                ext.runtime_library_dirs.append(os.curdir)
+
+    def setup_shlib_compiler(self):
+        compiler = self.shlib_compiler = new_compiler(
+            compiler=self.compiler, dry_run=self.dry_run, force=self.force
+        )
+        _customize_compiler_for_shlib(compiler)
+
+        if self.include_dirs is not None:
+            compiler.set_include_dirs(self.include_dirs)
+        if self.define is not None:
+            # 'define' option is a list of (name,value) tuples
+            for (name, value) in self.define:
+                compiler.define_macro(name, value)
+        if self.undef is not None:
+            for macro in self.undef:
+                compiler.undefine_macro(macro)
+        if self.libraries is not None:
+            compiler.set_libraries(self.libraries)
+        if self.library_dirs is not None:
+            compiler.set_library_dirs(self.library_dirs)
+        if self.rpath is not None:
+            compiler.set_runtime_library_dirs(self.rpath)
+        if self.link_objects is not None:
+            compiler.set_link_objects(self.link_objects)
+
+        # hack so distutils' build_extension() builds a library instead
+        compiler.link_shared_object = link_shared_object.__get__(compiler)
+
+    def get_export_symbols(self, ext):
+        if isinstance(ext, Library):
+            return ext.export_symbols
+        return _build_ext.get_export_symbols(self, ext)
+
+    def build_extension(self, ext):
+        ext._convert_pyx_sources_to_lang()
+        _compiler = self.compiler
+        try:
+            if isinstance(ext, Library):
+                self.compiler = self.shlib_compiler
+            _build_ext.build_extension(self, ext)
+            if ext._needs_stub:
+                cmd = self.get_finalized_command('build_py').build_lib
+                self.write_stub(cmd, ext)
+        finally:
+            self.compiler = _compiler
+
+    def links_to_dynamic(self, ext):
+        """Return true if 'ext' links to a dynamic lib in the same package"""
+        # XXX this should check to ensure the lib is actually being built
+        # XXX as dynamic, and not just using a locally-found version or a
+        # XXX static-compiled version
+        libnames = dict.fromkeys([lib._full_name for lib in self.shlibs])
+        pkg = '.'.join(ext._full_name.split('.')[:-1] + [''])
+        return any(pkg + libname in libnames for libname in ext.libraries)
+
+    def get_outputs(self):
+        return _build_ext.get_outputs(self) + self.__get_stubs_outputs()
+
+    def __get_stubs_outputs(self):
+        # assemble the base name for each extension that needs a stub
+        ns_ext_bases = (
+            os.path.join(self.build_lib, *ext._full_name.split('.'))
+            for ext in self.extensions
+            if ext._needs_stub
+        )
+        # pair each base with the extension
+        pairs = itertools.product(ns_ext_bases, self.__get_output_extensions())
+        return list(base + fnext for base, fnext in pairs)
+
+    def __get_output_extensions(self):
+        yield '.py'
+        yield '.pyc'
+        if self.get_finalized_command('build_py').optimize:
+            yield '.pyo'
+
+    def write_stub(self, output_dir, ext, compile=False):
+        log.info("writing stub loader for %s to %s", ext._full_name,
+                 output_dir)
+        stub_file = (os.path.join(output_dir, *ext._full_name.split('.')) +
+                     '.py')
+        if compile and os.path.exists(stub_file):
+            raise DistutilsError(stub_file + " already exists! Please delete.")
+        if not self.dry_run:
+            f = open(stub_file, 'w')
+            f.write(
+                '\n'.join([
+                    "def __bootstrap__():",
+                    "   global __bootstrap__, __file__, __loader__",
+                    "   import sys, os, pkg_resources, imp" + if_dl(", dl"),
+                    "   __file__ = pkg_resources.resource_filename"
+                    "(__name__,%r)"
+                    % os.path.basename(ext._file_name),
+                    "   del __bootstrap__",
+                    "   if '__loader__' in globals():",
+                    "       del __loader__",
+                    if_dl("   old_flags = sys.getdlopenflags()"),
+                    "   old_dir = os.getcwd()",
+                    "   try:",
+                    "     os.chdir(os.path.dirname(__file__))",
+                    if_dl("     sys.setdlopenflags(dl.RTLD_NOW)"),
+                    "     imp.load_dynamic(__name__,__file__)",
+                    "   finally:",
+                    if_dl("     sys.setdlopenflags(old_flags)"),
+                    "     os.chdir(old_dir)",
+                    "__bootstrap__()",
+                    ""  # terminal \n
+                ])
+            )
+            f.close()
+        if compile:
+            from distutils.util import byte_compile
+
+            byte_compile([stub_file], optimize=0,
+                         force=True, dry_run=self.dry_run)
+            optimize = self.get_finalized_command('install_lib').optimize
+            if optimize > 0:
+                byte_compile([stub_file], optimize=optimize,
+                             force=True, dry_run=self.dry_run)
+            if os.path.exists(stub_file) and not self.dry_run:
+                os.unlink(stub_file)
+
+
+if use_stubs or os.name == 'nt':
+    # Build shared libraries
+    #
+    def link_shared_object(
+            self, objects, output_libname, output_dir=None, libraries=None,
+            library_dirs=None, runtime_library_dirs=None, export_symbols=None,
+            debug=0, extra_preargs=None, extra_postargs=None, build_temp=None,
+            target_lang=None):
+        self.link(
+            self.SHARED_LIBRARY, objects, output_libname,
+            output_dir, libraries, library_dirs, runtime_library_dirs,
+            export_symbols, debug, extra_preargs, extra_postargs,
+            build_temp, target_lang
+        )
+else:
+    # Build static libraries everywhere else
+    libtype = 'static'
+
+    def link_shared_object(
+            self, objects, output_libname, output_dir=None, libraries=None,
+            library_dirs=None, runtime_library_dirs=None, export_symbols=None,
+            debug=0, extra_preargs=None, extra_postargs=None, build_temp=None,
+            target_lang=None):
+        # XXX we need to either disallow these attrs on Library instances,
+        # or warn/abort here if set, or something...
+        # libraries=None, library_dirs=None, runtime_library_dirs=None,
+        # export_symbols=None, extra_preargs=None, extra_postargs=None,
+        # build_temp=None
+
+        assert output_dir is None  # distutils build_ext doesn't pass this
+        output_dir, filename = os.path.split(output_libname)
+        basename, ext = os.path.splitext(filename)
+        if self.library_filename("x").startswith('lib'):
+            # strip 'lib' prefix; this is kludgy if some platform uses
+            # a different prefix
+            basename = basename[3:]
+
+        self.create_static_lib(
+            objects, basename, output_dir, debug, target_lang
+        )
+
+
+def _get_config_var_837(name):
+    """
+    In https://github.com/pypa/setuptools/pull/837, we discovered
+    Python 3.3.0 exposes the extension suffix under the name 'SO'.
+    """
+    if sys.version_info < (3, 3, 1):
+        name = 'SO'
+    return get_config_var(name)
diff --git a/vendor/setuptools-39.0.1/setuptools/command/build_py.py b/vendor/setuptools-39.0.1/setuptools/command/build_py.py
new file mode 100644
index 00000000..b0314fd4
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/build_py.py
@@ -0,0 +1,270 @@
+from glob import glob
+from distutils.util import convert_path
+import distutils.command.build_py as orig
+import os
+import fnmatch
+import textwrap
+import io
+import distutils.errors
+import itertools
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import map, filter, filterfalse
+
+try:
+    from setuptools.lib2to3_ex import Mixin2to3
+except ImportError:
+
+    class Mixin2to3:
+        def run_2to3(self, files, doctests=True):
+            "do nothing"
+
+
+class build_py(orig.build_py, Mixin2to3):
+    """Enhanced 'build_py' command that includes data files with packages
+
+    The data files are specified via a 'package_data' argument to 'setup()'.
+    See 'setuptools.dist.Distribution' for more details.
+
+    Also, this version of the 'build_py' command allows you to specify both
+    'py_modules' and 'packages' in the same setup operation.
+    """
+
+    def finalize_options(self):
+        orig.build_py.finalize_options(self)
+        self.package_data = self.distribution.package_data
+        self.exclude_package_data = (self.distribution.exclude_package_data or
+                                     {})
+        if 'data_files' in self.__dict__:
+            del self.__dict__['data_files']
+        self.__updated_files = []
+        self.__doctests_2to3 = []
+
+    def run(self):
+        """Build modules, packages, and copy data files to build directory"""
+        if not self.py_modules and not self.packages:
+            return
+
+        if self.py_modules:
+            self.build_modules()
+
+        if self.packages:
+            self.build_packages()
+            self.build_package_data()
+
+        self.run_2to3(self.__updated_files, False)
+        self.run_2to3(self.__updated_files, True)
+        self.run_2to3(self.__doctests_2to3, True)
+
+        # Only compile actual .py files, using our base class' idea of what our
+        # output files are.
+        self.byte_compile(orig.build_py.get_outputs(self, include_bytecode=0))
+
+    def __getattr__(self, attr):
+        "lazily compute data files"
+        if attr == 'data_files':
+            self.data_files = self._get_data_files()
+            return self.data_files
+        return orig.build_py.__getattr__(self, attr)
+
+    def build_module(self, module, module_file, package):
+        if six.PY2 and isinstance(package, six.string_types):
+            # avoid errors on Python 2 when unicode is passed (#190)
+            package = package.split('.')
+        outfile, copied = orig.build_py.build_module(self, module, module_file,
+                                                     package)
+        if copied:
+            self.__updated_files.append(outfile)
+        return outfile, copied
+
+    def _get_data_files(self):
+        """Generate list of '(package,src_dir,build_dir,filenames)' tuples"""
+        self.analyze_manifest()
+        return list(map(self._get_pkg_data_files, self.packages or ()))
+
+    def _get_pkg_data_files(self, package):
+        # Locate package source directory
+        src_dir = self.get_package_dir(package)
+
+        # Compute package build directory
+        build_dir = os.path.join(*([self.build_lib] + package.split('.')))
+
+        # Strip directory from globbed filenames
+        filenames = [
+            os.path.relpath(file, src_dir)
+            for file in self.find_data_files(package, src_dir)
+        ]
+        return package, src_dir, build_dir, filenames
+
+    def find_data_files(self, package, src_dir):
+        """Return filenames for package's data files in 'src_dir'"""
+        patterns = self._get_platform_patterns(
+            self.package_data,
+            package,
+            src_dir,
+        )
+        globs_expanded = map(glob, patterns)
+        # flatten the expanded globs into an iterable of matches
+        globs_matches = itertools.chain.from_iterable(globs_expanded)
+        glob_files = filter(os.path.isfile, globs_matches)
+        files = itertools.chain(
+            self.manifest_files.get(package, []),
+            glob_files,
+        )
+        return self.exclude_data_files(package, src_dir, files)
+
+    def build_package_data(self):
+        """Copy data files into build directory"""
+        for package, src_dir, build_dir, filenames in self.data_files:
+            for filename in filenames:
+                target = os.path.join(build_dir, filename)
+                self.mkpath(os.path.dirname(target))
+                srcfile = os.path.join(src_dir, filename)
+                outf, copied = self.copy_file(srcfile, target)
+                srcfile = os.path.abspath(srcfile)
+                if (copied and
+                        srcfile in self.distribution.convert_2to3_doctests):
+                    self.__doctests_2to3.append(outf)
+
+    def analyze_manifest(self):
+        self.manifest_files = mf = {}
+        if not self.distribution.include_package_data:
+            return
+        src_dirs = {}
+        for package in self.packages or ():
+            # Locate package source directory
+            src_dirs[assert_relative(self.get_package_dir(package))] = package
+
+        self.run_command('egg_info')
+        ei_cmd = self.get_finalized_command('egg_info')
+        for path in ei_cmd.filelist.files:
+            d, f = os.path.split(assert_relative(path))
+            prev = None
+            oldf = f
+            while d and d != prev and d not in src_dirs:
+                prev = d
+                d, df = os.path.split(d)
+                f = os.path.join(df, f)
+            if d in src_dirs:
+                if path.endswith('.py') and f == oldf:
+                    continue  # it's a module, not data
+                mf.setdefault(src_dirs[d], []).append(path)
+
+    def get_data_files(self):
+        pass  # Lazily compute data files in _get_data_files() function.
+
+    def check_package(self, package, package_dir):
+        """Check namespace packages' __init__ for declare_namespace"""
+        try:
+            return self.packages_checked[package]
+        except KeyError:
+            pass
+
+        init_py = orig.build_py.check_package(self, package, package_dir)
+        self.packages_checked[package] = init_py
+
+        if not init_py or not self.distribution.namespace_packages:
+            return init_py
+
+        for pkg in self.distribution.namespace_packages:
+            if pkg == package or pkg.startswith(package + '.'):
+                break
+        else:
+            return init_py
+
+        with io.open(init_py, 'rb') as f:
+            contents = f.read()
+        if b'declare_namespace' not in contents:
+            raise distutils.errors.DistutilsError(
+                "Namespace package problem: %s is a namespace package, but "
+                "its\n__init__.py does not call declare_namespace()! Please "
+                'fix it.\n(See the setuptools manual under '
+                '"Namespace Packages" for details.)\n"' % (package,)
+            )
+        return init_py
+
+    def initialize_options(self):
+        self.packages_checked = {}
+        orig.build_py.initialize_options(self)
+
+    def get_package_dir(self, package):
+        res = orig.build_py.get_package_dir(self, package)
+        if self.distribution.src_root is not None:
+            return os.path.join(self.distribution.src_root, res)
+        return res
+
+    def exclude_data_files(self, package, src_dir, files):
+        """Filter filenames for package's data files in 'src_dir'"""
+        files = list(files)
+        patterns = self._get_platform_patterns(
+            self.exclude_package_data,
+            package,
+            src_dir,
+        )
+        match_groups = (
+            fnmatch.filter(files, pattern)
+            for pattern in patterns
+        )
+        # flatten the groups of matches into an iterable of matches
+        matches = itertools.chain.from_iterable(match_groups)
+        bad = set(matches)
+        keepers = (
+            fn
+            for fn in files
+            if fn not in bad
+        )
+        # ditch dupes
+        return list(_unique_everseen(keepers))
+
+    @staticmethod
+    def _get_platform_patterns(spec, package, src_dir):
+        """
+        yield platform-specific path patterns (suitable for glob
+        or fn_match) from a glob-based spec (such as
+        self.package_data or self.exclude_package_data)
+        matching package in src_dir.
+        """
+        raw_patterns = itertools.chain(
+            spec.get('', []),
+            spec.get(package, []),
+        )
+        return (
+            # Each pattern has to be converted to a platform-specific path
+            os.path.join(src_dir, convert_path(pattern))
+            for pattern in raw_patterns
+        )
+
+
+# from Python docs
+def _unique_everseen(iterable, key=None):
+    "List unique elements, preserving order. Remember all elements ever seen."
+    # unique_everseen('AAAABBBCCDAABBB') --> A B C D
+    # unique_everseen('ABBCcAD', str.lower) --> A B C D
+    seen = set()
+    seen_add = seen.add
+    if key is None:
+        for element in filterfalse(seen.__contains__, iterable):
+            seen_add(element)
+            yield element
+    else:
+        for element in iterable:
+            k = key(element)
+            if k not in seen:
+                seen_add(k)
+                yield element
+
+
+def assert_relative(path):
+    if not os.path.isabs(path):
+        return path
+    from distutils.errors import DistutilsSetupError
+
+    msg = textwrap.dedent("""
+        Error: setup script specifies an absolute path:
+
+            %s
+
+        setup() arguments must *always* be /-separated paths relative to the
+        setup.py directory, *never* absolute paths.
+        """).lstrip() % path
+    raise DistutilsSetupError(msg)
diff --git a/vendor/setuptools-39.0.1/setuptools/command/develop.py b/vendor/setuptools-39.0.1/setuptools/command/develop.py
new file mode 100755
index 00000000..959c932a
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/develop.py
@@ -0,0 +1,216 @@
+from distutils.util import convert_path
+from distutils import log
+from distutils.errors import DistutilsError, DistutilsOptionError
+import os
+import glob
+import io
+
+from setuptools.extern import six
+
+from pkg_resources import Distribution, PathMetadata, normalize_path
+from setuptools.command.easy_install import easy_install
+from setuptools import namespaces
+import setuptools
+
+
+class develop(namespaces.DevelopInstaller, easy_install):
+    """Set up package for development"""
+
+    description = "install package in 'development mode'"
+
+    user_options = easy_install.user_options + [
+        ("uninstall", "u", "Uninstall this source package"),
+        ("egg-path=", None, "Set the path to be used in the .egg-link file"),
+    ]
+
+    boolean_options = easy_install.boolean_options + ['uninstall']
+
+    command_consumes_arguments = False  # override base
+
+    def run(self):
+        if self.uninstall:
+            self.multi_version = True
+            self.uninstall_link()
+            self.uninstall_namespaces()
+        else:
+            self.install_for_development()
+        self.warn_deprecated_options()
+
+    def initialize_options(self):
+        self.uninstall = None
+        self.egg_path = None
+        easy_install.initialize_options(self)
+        self.setup_path = None
+        self.always_copy_from = '.'  # always copy eggs installed in curdir
+
+    def finalize_options(self):
+        ei = self.get_finalized_command("egg_info")
+        if ei.broken_egg_info:
+            template = "Please rename %r to %r before using 'develop'"
+            args = ei.egg_info, ei.broken_egg_info
+            raise DistutilsError(template % args)
+        self.args = [ei.egg_name]
+
+        easy_install.finalize_options(self)
+        self.expand_basedirs()
+        self.expand_dirs()
+        # pick up setup-dir .egg files only: no .egg-info
+        self.package_index.scan(glob.glob('*.egg'))
+
+        egg_link_fn = ei.egg_name + '.egg-link'
+        self.egg_link = os.path.join(self.install_dir, egg_link_fn)
+        self.egg_base = ei.egg_base
+        if self.egg_path is None:
+            self.egg_path = os.path.abspath(ei.egg_base)
+
+        target = normalize_path(self.egg_base)
+        egg_path = normalize_path(os.path.join(self.install_dir,
+                                               self.egg_path))
+        if egg_path != target:
+            raise DistutilsOptionError(
+                "--egg-path must be a relative path from the install"
+                " directory to " + target
+            )
+
+        # Make a distribution for the package's source
+        self.dist = Distribution(
+            target,
+            PathMetadata(target, os.path.abspath(ei.egg_info)),
+            project_name=ei.egg_name
+        )
+
+        self.setup_path = self._resolve_setup_path(
+            self.egg_base,
+            self.install_dir,
+            self.egg_path,
+        )
+
+    @staticmethod
+    def _resolve_setup_path(egg_base, install_dir, egg_path):
+        """
+        Generate a path from egg_base back to '.' where the
+        setup script resides and ensure that path points to the
+        setup path from $install_dir/$egg_path.
+        """
+        path_to_setup = egg_base.replace(os.sep, '/').rstrip('/')
+        if path_to_setup != os.curdir:
+            path_to_setup = '../' * (path_to_setup.count('/') + 1)
+        resolved = normalize_path(
+            os.path.join(install_dir, egg_path, path_to_setup)
+        )
+        if resolved != normalize_path(os.curdir):
+            raise DistutilsOptionError(
+                "Can't get a consistent path to setup script from"
+                " installation directory", resolved, normalize_path(os.curdir))
+        return path_to_setup
+
+    def install_for_development(self):
+        if six.PY3 and getattr(self.distribution, 'use_2to3', False):
+            # If we run 2to3 we can not do this inplace:
+
+            # Ensure metadata is up-to-date
+            self.reinitialize_command('build_py', inplace=0)
+            self.run_command('build_py')
+            bpy_cmd = self.get_finalized_command("build_py")
+            build_path = normalize_path(bpy_cmd.build_lib)
+
+            # Build extensions
+            self.reinitialize_command('egg_info', egg_base=build_path)
+            self.run_command('egg_info')
+
+            self.reinitialize_command('build_ext', inplace=0)
+            self.run_command('build_ext')
+
+            # Fixup egg-link and easy-install.pth
+            ei_cmd = self.get_finalized_command("egg_info")
+            self.egg_path = build_path
+            self.dist.location = build_path
+            # XXX
+            self.dist._provider = PathMetadata(build_path, ei_cmd.egg_info)
+        else:
+            # Without 2to3 inplace works fine:
+            self.run_command('egg_info')
+
+            # Build extensions in-place
+            self.reinitialize_command('build_ext', inplace=1)
+            self.run_command('build_ext')
+
+        self.install_site_py()  # ensure that target dir is site-safe
+        if setuptools.bootstrap_install_from:
+            self.easy_install(setuptools.bootstrap_install_from)
+            setuptools.bootstrap_install_from = None
+
+        self.install_namespaces()
+
+        # create an .egg-link in the installation dir, pointing to our egg
+        log.info("Creating %s (link to %s)", self.egg_link, self.egg_base)
+        if not self.dry_run:
+            with open(self.egg_link, "w") as f:
+                f.write(self.egg_path + "\n" + self.setup_path)
+        # postprocess the installed distro, fixing up .pth, installing scripts,
+        # and handling requirements
+        self.process_distribution(None, self.dist, not self.no_deps)
+
+    def uninstall_link(self):
+        if os.path.exists(self.egg_link):
+            log.info("Removing %s (link to %s)", self.egg_link, self.egg_base)
+            egg_link_file = open(self.egg_link)
+            contents = [line.rstrip() for line in egg_link_file]
+            egg_link_file.close()
+            if contents not in ([self.egg_path],
+                                [self.egg_path, self.setup_path]):
+                log.warn("Link points to %s: uninstall aborted", contents)
+                return
+            if not self.dry_run:
+                os.unlink(self.egg_link)
+        if not self.dry_run:
+            self.update_pth(self.dist)  # remove any .pth link to us
+        if self.distribution.scripts:
+            # XXX should also check for entry point scripts!
+            log.warn("Note: you must uninstall or replace scripts manually!")
+
+    def install_egg_scripts(self, dist):
+        if dist is not self.dist:
+            # Installing a dependency, so fall back to normal behavior
+            return easy_install.install_egg_scripts(self, dist)
+
+        # create wrapper scripts in the script dir, pointing to dist.scripts
+
+        # new-style...
+        self.install_wrapper_scripts(dist)
+
+        # ...and old-style
+        for script_name in self.distribution.scripts or []:
+            script_path = os.path.abspath(convert_path(script_name))
+            script_name = os.path.basename(script_path)
+            with io.open(script_path) as strm:
+                script_text = strm.read()
+            self.install_script(dist, script_name, script_text, script_path)
+
+    def install_wrapper_scripts(self, dist):
+        dist = VersionlessRequirement(dist)
+        return easy_install.install_wrapper_scripts(self, dist)
+
+
+class VersionlessRequirement(object):
+    """
+    Adapt a pkg_resources.Distribution to simply return the project
+    name as the 'requirement' so that scripts will work across
+    multiple versions.
+
+    >>> dist = Distribution(project_name='foo', version='1.0')
+    >>> str(dist.as_requirement())
+    'foo==1.0'
+    >>> adapted_dist = VersionlessRequirement(dist)
+    >>> str(adapted_dist.as_requirement())
+    'foo'
+    """
+
+    def __init__(self, dist):
+        self.__dist = dist
+
+    def __getattr__(self, name):
+        return getattr(self.__dist, name)
+
+    def as_requirement(self):
+        return self.project_name
diff --git a/vendor/setuptools-39.0.1/setuptools/command/dist_info.py b/vendor/setuptools-39.0.1/setuptools/command/dist_info.py
new file mode 100644
index 00000000..c45258fa
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/dist_info.py
@@ -0,0 +1,36 @@
+"""
+Create a dist_info directory
+As defined in the wheel specification
+"""
+
+import os
+
+from distutils.core import Command
+from distutils import log
+
+
+class dist_info(Command):
+
+    description = 'create a .dist-info directory'
+
+    user_options = [
+        ('egg-base=', 'e', "directory containing .egg-info directories"
+                           " (default: top of the source tree)"),
+    ]
+
+    def initialize_options(self):
+        self.egg_base = None
+
+    def finalize_options(self):
+        pass
+
+    def run(self):
+        egg_info = self.get_finalized_command('egg_info')
+        egg_info.egg_base = self.egg_base
+        egg_info.finalize_options()
+        egg_info.run()
+        dist_info_dir = egg_info.egg_info[:-len('.egg-info')] + '.dist-info'
+        log.info("creating '{}'".format(os.path.abspath(dist_info_dir)))
+
+        bdist_wheel = self.get_finalized_command('bdist_wheel')
+        bdist_wheel.egg2dist(egg_info.egg_info, dist_info_dir)
diff --git a/vendor/setuptools-39.0.1/setuptools/command/easy_install.py b/vendor/setuptools-39.0.1/setuptools/command/easy_install.py
new file mode 100755
index 00000000..a6f61436
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/easy_install.py
@@ -0,0 +1,2334 @@
+#!/usr/bin/env python
+"""
+Easy Install
+------------
+
+A tool for doing automatic download/extract/build of distutils-based Python
+packages.  For detailed documentation, see the accompanying EasyInstall.txt
+file, or visit the `EasyInstall home page`__.
+
+__ https://setuptools.readthedocs.io/en/latest/easy_install.html
+
+"""
+
+from glob import glob
+from distutils.util import get_platform
+from distutils.util import convert_path, subst_vars
+from distutils.errors import (
+    DistutilsArgError, DistutilsOptionError,
+    DistutilsError, DistutilsPlatformError,
+)
+from distutils.command.install import INSTALL_SCHEMES, SCHEME_KEYS
+from distutils import log, dir_util
+from distutils.command.build_scripts import first_line_re
+from distutils.spawn import find_executable
+import sys
+import os
+import zipimport
+import shutil
+import tempfile
+import zipfile
+import re
+import stat
+import random
+import textwrap
+import warnings
+import site
+import struct
+import contextlib
+import subprocess
+import shlex
+import io
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import configparser, map
+
+from setuptools import Command
+from setuptools.sandbox import run_setup
+from setuptools.py31compat import get_path, get_config_vars
+from setuptools.py27compat import rmtree_safe
+from setuptools.command import setopt
+from setuptools.archive_util import unpack_archive
+from setuptools.package_index import (
+    PackageIndex, parse_requirement_arg, URL_SCHEME,
+)
+from setuptools.command import bdist_egg, egg_info
+from setuptools.wheel import Wheel
+from pkg_resources import (
+    yield_lines, normalize_path, resource_string, ensure_directory,
+    get_distribution, find_distributions, Environment, Requirement,
+    Distribution, PathMetadata, EggMetadata, WorkingSet, DistributionNotFound,
+    VersionConflict, DEVELOP_DIST,
+)
+import pkg_resources.py31compat
+
+# Turn on PEP440Warnings
+warnings.filterwarnings("default", category=pkg_resources.PEP440Warning)
+
+__all__ = [
+    'samefile', 'easy_install', 'PthDistributions', 'extract_wininst_cfg',
+    'main', 'get_exe_prefixes',
+]
+
+
+def is_64bit():
+    return struct.calcsize("P") == 8
+
+
+def samefile(p1, p2):
+    """
+    Determine if two paths reference the same file.
+
+    Augments os.path.samefile to work on Windows and
+    suppresses errors if the path doesn't exist.
+    """
+    both_exist = os.path.exists(p1) and os.path.exists(p2)
+    use_samefile = hasattr(os.path, 'samefile') and both_exist
+    if use_samefile:
+        return os.path.samefile(p1, p2)
+    norm_p1 = os.path.normpath(os.path.normcase(p1))
+    norm_p2 = os.path.normpath(os.path.normcase(p2))
+    return norm_p1 == norm_p2
+
+
+if six.PY2:
+
+    def _to_ascii(s):
+        return s
+
+    def isascii(s):
+        try:
+            six.text_type(s, 'ascii')
+            return True
+        except UnicodeError:
+            return False
+else:
+
+    def _to_ascii(s):
+        return s.encode('ascii')
+
+    def isascii(s):
+        try:
+            s.encode('ascii')
+            return True
+        except UnicodeError:
+            return False
+
+
+_one_liner = lambda text: textwrap.dedent(text).strip().replace('\n', '; ')
+
+
+class easy_install(Command):
+    """Manage a download/build/install process"""
+    description = "Find/get/install Python packages"
+    command_consumes_arguments = True
+
+    user_options = [
+        ('prefix=', None, "installation prefix"),
+        ("zip-ok", "z", "install package as a zipfile"),
+        ("multi-version", "m", "make apps have to require() a version"),
+        ("upgrade", "U", "force upgrade (searches PyPI for latest versions)"),
+        ("install-dir=", "d", "install package to DIR"),
+        ("script-dir=", "s", "install scripts to DIR"),
+        ("exclude-scripts", "x", "Don't install scripts"),
+        ("always-copy", "a", "Copy all needed packages to install dir"),
+        ("index-url=", "i", "base URL of Python Package Index"),
+        ("find-links=", "f", "additional URL(s) to search for packages"),
+        ("build-directory=", "b",
+         "download/extract/build in DIR; keep the results"),
+        ('optimize=', 'O',
+         "also compile with optimization: -O1 for \"python -O\", "
+         "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
+        ('record=', None,
+         "filename in which to record list of installed files"),
+        ('always-unzip', 'Z', "don't install as a zipfile, no matter what"),
+        ('site-dirs=', 'S', "list of directories where .pth files work"),
+        ('editable', 'e', "Install specified packages in editable form"),
+        ('no-deps', 'N', "don't install dependencies"),
+        ('allow-hosts=', 'H', "pattern(s) that hostnames must match"),
+        ('local-snapshots-ok', 'l',
+         "allow building eggs from local checkouts"),
+        ('version', None, "print version information and exit"),
+        ('no-find-links', None,
+         "Don't load find-links defined in packages being installed")
+    ]
+    boolean_options = [
+        'zip-ok', 'multi-version', 'exclude-scripts', 'upgrade', 'always-copy',
+        'editable',
+        'no-deps', 'local-snapshots-ok', 'version'
+    ]
+
+    if site.ENABLE_USER_SITE:
+        help_msg = "install in user site-package '%s'" % site.USER_SITE
+        user_options.append(('user', None, help_msg))
+        boolean_options.append('user')
+
+    negative_opt = {'always-unzip': 'zip-ok'}
+    create_index = PackageIndex
+
+    def initialize_options(self):
+        # the --user option seems to be an opt-in one,
+        # so the default should be False.
+        self.user = 0
+        self.zip_ok = self.local_snapshots_ok = None
+        self.install_dir = self.script_dir = self.exclude_scripts = None
+        self.index_url = None
+        self.find_links = None
+        self.build_directory = None
+        self.args = None
+        self.optimize = self.record = None
+        self.upgrade = self.always_copy = self.multi_version = None
+        self.editable = self.no_deps = self.allow_hosts = None
+        self.root = self.prefix = self.no_report = None
+        self.version = None
+        self.install_purelib = None  # for pure module distributions
+        self.install_platlib = None  # non-pure (dists w/ extensions)
+        self.install_headers = None  # for C/C++ headers
+        self.install_lib = None  # set to either purelib or platlib
+        self.install_scripts = None
+        self.install_data = None
+        self.install_base = None
+        self.install_platbase = None
+        if site.ENABLE_USER_SITE:
+            self.install_userbase = site.USER_BASE
+            self.install_usersite = site.USER_SITE
+        else:
+            self.install_userbase = None
+            self.install_usersite = None
+        self.no_find_links = None
+
+        # Options not specifiable via command line
+        self.package_index = None
+        self.pth_file = self.always_copy_from = None
+        self.site_dirs = None
+        self.installed_projects = {}
+        self.sitepy_installed = False
+        # Always read easy_install options, even if we are subclassed, or have
+        # an independent instance created.  This ensures that defaults will
+        # always come from the standard configuration file(s)' "easy_install"
+        # section, even if this is a "develop" or "install" command, or some
+        # other embedding.
+        self._dry_run = None
+        self.verbose = self.distribution.verbose
+        self.distribution._set_command_options(
+            self, self.distribution.get_option_dict('easy_install')
+        )
+
+    def delete_blockers(self, blockers):
+        extant_blockers = (
+            filename for filename in blockers
+            if os.path.exists(filename) or os.path.islink(filename)
+        )
+        list(map(self._delete_path, extant_blockers))
+
+    def _delete_path(self, path):
+        log.info("Deleting %s", path)
+        if self.dry_run:
+            return
+
+        is_tree = os.path.isdir(path) and not os.path.islink(path)
+        remover = rmtree if is_tree else os.unlink
+        remover(path)
+
+    @staticmethod
+    def _render_version():
+        """
+        Render the Setuptools version and installation details, then exit.
+        """
+        ver = sys.version[:3]
+        dist = get_distribution('setuptools')
+        tmpl = 'setuptools {dist.version} from {dist.location} (Python {ver})'
+        print(tmpl.format(**locals()))
+        raise SystemExit()
+
+    def finalize_options(self):
+        self.version and self._render_version()
+
+        py_version = sys.version.split()[0]
+        prefix, exec_prefix = get_config_vars('prefix', 'exec_prefix')
+
+        self.config_vars = {
+            'dist_name': self.distribution.get_name(),
+            'dist_version': self.distribution.get_version(),
+            'dist_fullname': self.distribution.get_fullname(),
+            'py_version': py_version,
+            'py_version_short': py_version[0:3],
+            'py_version_nodot': py_version[0] + py_version[2],
+            'sys_prefix': prefix,
+            'prefix': prefix,
+            'sys_exec_prefix': exec_prefix,
+            'exec_prefix': exec_prefix,
+            # Only python 3.2+ has abiflags
+            'abiflags': getattr(sys, 'abiflags', ''),
+        }
+
+        if site.ENABLE_USER_SITE:
+            self.config_vars['userbase'] = self.install_userbase
+            self.config_vars['usersite'] = self.install_usersite
+
+        self._fix_install_dir_for_user_site()
+
+        self.expand_basedirs()
+        self.expand_dirs()
+
+        self._expand(
+            'install_dir', 'script_dir', 'build_directory',
+            'site_dirs',
+        )
+        # If a non-default installation directory was specified, default the
+        # script directory to match it.
+        if self.script_dir is None:
+            self.script_dir = self.install_dir
+
+        if self.no_find_links is None:
+            self.no_find_links = False
+
+        # Let install_dir get set by install_lib command, which in turn
+        # gets its info from the install command, and takes into account
+        # --prefix and --home and all that other crud.
+        self.set_undefined_options(
+            'install_lib', ('install_dir', 'install_dir')
+        )
+        # Likewise, set default script_dir from 'install_scripts.install_dir'
+        self.set_undefined_options(
+            'install_scripts', ('install_dir', 'script_dir')
+        )
+
+        if self.user and self.install_purelib:
+            self.install_dir = self.install_purelib
+            self.script_dir = self.install_scripts
+        # default --record from the install command
+        self.set_undefined_options('install', ('record', 'record'))
+        # Should this be moved to the if statement below? It's not used
+        # elsewhere
+        normpath = map(normalize_path, sys.path)
+        self.all_site_dirs = get_site_dirs()
+        if self.site_dirs is not None:
+            site_dirs = [
+                os.path.expanduser(s.strip()) for s in
+                self.site_dirs.split(',')
+            ]
+            for d in site_dirs:
+                if not os.path.isdir(d):
+                    log.warn("%s (in --site-dirs) does not exist", d)
+                elif normalize_path(d) not in normpath:
+                    raise DistutilsOptionError(
+                        d + " (in --site-dirs) is not on sys.path"
+                    )
+                else:
+                    self.all_site_dirs.append(normalize_path(d))
+        if not self.editable:
+            self.check_site_dir()
+        self.index_url = self.index_url or "https://pypi.python.org/simple"
+        self.shadow_path = self.all_site_dirs[:]
+        for path_item in self.install_dir, normalize_path(self.script_dir):
+            if path_item not in self.shadow_path:
+                self.shadow_path.insert(0, path_item)
+
+        if self.allow_hosts is not None:
+            hosts = [s.strip() for s in self.allow_hosts.split(',')]
+        else:
+            hosts = ['*']
+        if self.package_index is None:
+            self.package_index = self.create_index(
+                self.index_url, search_path=self.shadow_path, hosts=hosts,
+            )
+        self.local_index = Environment(self.shadow_path + sys.path)
+
+        if self.find_links is not None:
+            if isinstance(self.find_links, six.string_types):
+                self.find_links = self.find_links.split()
+        else:
+            self.find_links = []
+        if self.local_snapshots_ok:
+            self.package_index.scan_egg_links(self.shadow_path + sys.path)
+        if not self.no_find_links:
+            self.package_index.add_find_links(self.find_links)
+        self.set_undefined_options('install_lib', ('optimize', 'optimize'))
+        if not isinstance(self.optimize, int):
+            try:
+                self.optimize = int(self.optimize)
+                if not (0 <= self.optimize <= 2):
+                    raise ValueError
+            except ValueError:
+                raise DistutilsOptionError("--optimize must be 0, 1, or 2")
+
+        if self.editable and not self.build_directory:
+            raise DistutilsArgError(
+                "Must specify a build directory (-b) when using --editable"
+            )
+        if not self.args:
+            raise DistutilsArgError(
+                "No urls, filenames, or requirements specified (see --help)")
+
+        self.outputs = []
+
+    def _fix_install_dir_for_user_site(self):
+        """
+        Fix the install_dir if "--user" was used.
+        """
+        if not self.user or not site.ENABLE_USER_SITE:
+            return
+
+        self.create_home_path()
+        if self.install_userbase is None:
+            msg = "User base directory is not specified"
+            raise DistutilsPlatformError(msg)
+        self.install_base = self.install_platbase = self.install_userbase
+        scheme_name = os.name.replace('posix', 'unix') + '_user'
+        self.select_scheme(scheme_name)
+
+    def _expand_attrs(self, attrs):
+        for attr in attrs:
+            val = getattr(self, attr)
+            if val is not None:
+                if os.name == 'posix' or os.name == 'nt':
+                    val = os.path.expanduser(val)
+                val = subst_vars(val, self.config_vars)
+                setattr(self, attr, val)
+
+    def expand_basedirs(self):
+        """Calls `os.path.expanduser` on install_base, install_platbase and
+        root."""
+        self._expand_attrs(['install_base', 'install_platbase', 'root'])
+
+    def expand_dirs(self):
+        """Calls `os.path.expanduser` on install dirs."""
+        dirs = [
+            'install_purelib',
+            'install_platlib',
+            'install_lib',
+            'install_headers',
+            'install_scripts',
+            'install_data',
+        ]
+        self._expand_attrs(dirs)
+
+    def run(self):
+        if self.verbose != self.distribution.verbose:
+            log.set_verbosity(self.verbose)
+        try:
+            for spec in self.args:
+                self.easy_install(spec, not self.no_deps)
+            if self.record:
+                outputs = self.outputs
+                if self.root:  # strip any package prefix
+                    root_len = len(self.root)
+                    for counter in range(len(outputs)):
+                        outputs[counter] = outputs[counter][root_len:]
+                from distutils import file_util
+
+                self.execute(
+                    file_util.write_file, (self.record, outputs),
+                    "writing list of installed files to '%s'" %
+                    self.record
+                )
+            self.warn_deprecated_options()
+        finally:
+            log.set_verbosity(self.distribution.verbose)
+
+    def pseudo_tempname(self):
+        """Return a pseudo-tempname base in the install directory.
+        This code is intentionally naive; if a malicious party can write to
+        the target directory you're already in deep doodoo.
+        """
+        try:
+            pid = os.getpid()
+        except Exception:
+            pid = random.randint(0, sys.maxsize)
+        return os.path.join(self.install_dir, "test-easy-install-%s" % pid)
+
+    def warn_deprecated_options(self):
+        pass
+
+    def check_site_dir(self):
+        """Verify that self.install_dir is .pth-capable dir, if needed"""
+
+        instdir = normalize_path(self.install_dir)
+        pth_file = os.path.join(instdir, 'easy-install.pth')
+
+        # Is it a configured, PYTHONPATH, implicit, or explicit site dir?
+        is_site_dir = instdir in self.all_site_dirs
+
+        if not is_site_dir and not self.multi_version:
+            # No?  Then directly test whether it does .pth file processing
+            is_site_dir = self.check_pth_processing()
+        else:
+            # make sure we can write to target dir
+            testfile = self.pseudo_tempname() + '.write-test'
+            test_exists = os.path.exists(testfile)
+            try:
+                if test_exists:
+                    os.unlink(testfile)
+                open(testfile, 'w').close()
+                os.unlink(testfile)
+            except (OSError, IOError):
+                self.cant_write_to_target()
+
+        if not is_site_dir and not self.multi_version:
+            # Can't install non-multi to non-site dir
+            raise DistutilsError(self.no_default_version_msg())
+
+        if is_site_dir:
+            if self.pth_file is None:
+                self.pth_file = PthDistributions(pth_file, self.all_site_dirs)
+        else:
+            self.pth_file = None
+
+        if instdir not in map(normalize_path, _pythonpath()):
+            # only PYTHONPATH dirs need a site.py, so pretend it's there
+            self.sitepy_installed = True
+        elif self.multi_version and not os.path.exists(pth_file):
+            self.sitepy_installed = True  # don't need site.py in this case
+            self.pth_file = None  # and don't create a .pth file
+        self.install_dir = instdir
+
+    __cant_write_msg = textwrap.dedent("""
+        can't create or remove files in install directory
+
+        The following error occurred while trying to add or remove files in the
+        installation directory:
+
+            %s
+
+        The installation directory you specified (via --install-dir, --prefix, or
+        the distutils default setting) was:
+
+            %s
+        """).lstrip()
+
+    __not_exists_id = textwrap.dedent("""
+        This directory does not currently exist.  Please create it and try again, or
+        choose a different installation directory (using the -d or --install-dir
+        option).
+        """).lstrip()
+
+    __access_msg = textwrap.dedent("""
+        Perhaps your account does not have write access to this directory?  If the
+        installation directory is a system-owned directory, you may need to sign in
+        as the administrator or "root" account.  If you do not have administrative
+        access to this machine, you may wish to choose a different installation
+        directory, preferably one that is listed in your PYTHONPATH environment
+        variable.
+
+        For information on other options, you may wish to consult the
+        documentation at:
+
+          https://setuptools.readthedocs.io/en/latest/easy_install.html
+
+        Please make the appropriate changes for your system and try again.
+        """).lstrip()
+
+    def cant_write_to_target(self):
+        msg = self.__cant_write_msg % (sys.exc_info()[1], self.install_dir,)
+
+        if not os.path.exists(self.install_dir):
+            msg += '\n' + self.__not_exists_id
+        else:
+            msg += '\n' + self.__access_msg
+        raise DistutilsError(msg)
+
+    def check_pth_processing(self):
+        """Empirically verify whether .pth files are supported in inst. dir"""
+        instdir = self.install_dir
+        log.info("Checking .pth file support in %s", instdir)
+        pth_file = self.pseudo_tempname() + ".pth"
+        ok_file = pth_file + '.ok'
+        ok_exists = os.path.exists(ok_file)
+        tmpl = _one_liner("""
+            import os
+            f = open({ok_file!r}, 'w')
+            f.write('OK')
+            f.close()
+            """) + '\n'
+        try:
+            if ok_exists:
+                os.unlink(ok_file)
+            dirname = os.path.dirname(ok_file)
+            pkg_resources.py31compat.makedirs(dirname, exist_ok=True)
+            f = open(pth_file, 'w')
+        except (OSError, IOError):
+            self.cant_write_to_target()
+        else:
+            try:
+                f.write(tmpl.format(**locals()))
+                f.close()
+                f = None
+                executable = sys.executable
+                if os.name == 'nt':
+                    dirname, basename = os.path.split(executable)
+                    alt = os.path.join(dirname, 'pythonw.exe')
+                    use_alt = (
+                        basename.lower() == 'python.exe' and
+                        os.path.exists(alt)
+                    )
+                    if use_alt:
+                        # use pythonw.exe to avoid opening a console window
+                        executable = alt
+
+                from distutils.spawn import spawn
+
+                spawn([executable, '-E', '-c', 'pass'], 0)
+
+                if os.path.exists(ok_file):
+                    log.info(
+                        "TEST PASSED: %s appears to support .pth files",
+                        instdir
+                    )
+                    return True
+            finally:
+                if f:
+                    f.close()
+                if os.path.exists(ok_file):
+                    os.unlink(ok_file)
+                if os.path.exists(pth_file):
+                    os.unlink(pth_file)
+        if not self.multi_version:
+            log.warn("TEST FAILED: %s does NOT support .pth files", instdir)
+        return False
+
+    def install_egg_scripts(self, dist):
+        """Write all the scripts for `dist`, unless scripts are excluded"""
+        if not self.exclude_scripts and dist.metadata_isdir('scripts'):
+            for script_name in dist.metadata_listdir('scripts'):
+                if dist.metadata_isdir('scripts/' + script_name):
+                    # The "script" is a directory, likely a Python 3
+                    # __pycache__ directory, so skip it.
+                    continue
+                self.install_script(
+                    dist, script_name,
+                    dist.get_metadata('scripts/' + script_name)
+                )
+        self.install_wrapper_scripts(dist)
+
+    def add_output(self, path):
+        if os.path.isdir(path):
+            for base, dirs, files in os.walk(path):
+                for filename in files:
+                    self.outputs.append(os.path.join(base, filename))
+        else:
+            self.outputs.append(path)
+
+    def not_editable(self, spec):
+        if self.editable:
+            raise DistutilsArgError(
+                "Invalid argument %r: you can't use filenames or URLs "
+                "with --editable (except via the --find-links option)."
+                % (spec,)
+            )
+
+    def check_editable(self, spec):
+        if not self.editable:
+            return
+
+        if os.path.exists(os.path.join(self.build_directory, spec.key)):
+            raise DistutilsArgError(
+                "%r already exists in %s; can't do a checkout there" %
+                (spec.key, self.build_directory)
+            )
+
+    @contextlib.contextmanager
+    def _tmpdir(self):
+        tmpdir = tempfile.mkdtemp(prefix=six.u("easy_install-"))
+        try:
+            # cast to str as workaround for #709 and #710 and #712
+            yield str(tmpdir)
+        finally:
+            os.path.exists(tmpdir) and rmtree(rmtree_safe(tmpdir))
+
+    def easy_install(self, spec, deps=False):
+        if not self.editable:
+            self.install_site_py()
+
+        with self._tmpdir() as tmpdir:
+            if not isinstance(spec, Requirement):
+                if URL_SCHEME(spec):
+                    # It's a url, download it to tmpdir and process
+                    self.not_editable(spec)
+                    dl = self.package_index.download(spec, tmpdir)
+                    return self.install_item(None, dl, tmpdir, deps, True)
+
+                elif os.path.exists(spec):
+                    # Existing file or directory, just process it directly
+                    self.not_editable(spec)
+                    return self.install_item(None, spec, tmpdir, deps, True)
+                else:
+                    spec = parse_requirement_arg(spec)
+
+            self.check_editable(spec)
+            dist = self.package_index.fetch_distribution(
+                spec, tmpdir, self.upgrade, self.editable,
+                not self.always_copy, self.local_index
+            )
+            if dist is None:
+                msg = "Could not find suitable distribution for %r" % spec
+                if self.always_copy:
+                    msg += " (--always-copy skips system and development eggs)"
+                raise DistutilsError(msg)
+            elif dist.precedence == DEVELOP_DIST:
+                # .egg-info dists don't need installing, just process deps
+                self.process_distribution(spec, dist, deps, "Using")
+                return dist
+            else:
+                return self.install_item(spec, dist.location, tmpdir, deps)
+
+    def install_item(self, spec, download, tmpdir, deps, install_needed=False):
+
+        # Installation is also needed if file in tmpdir or is not an egg
+        install_needed = install_needed or self.always_copy
+        install_needed = install_needed or os.path.dirname(download) == tmpdir
+        install_needed = install_needed or not download.endswith('.egg')
+        install_needed = install_needed or (
+            self.always_copy_from is not None and
+            os.path.dirname(normalize_path(download)) ==
+            normalize_path(self.always_copy_from)
+        )
+
+        if spec and not install_needed:
+            # at this point, we know it's a local .egg, we just don't know if
+            # it's already installed.
+            for dist in self.local_index[spec.project_name]:
+                if dist.location == download:
+                    break
+            else:
+                install_needed = True  # it's not in the local index
+
+        log.info("Processing %s", os.path.basename(download))
+
+        if install_needed:
+            dists = self.install_eggs(spec, download, tmpdir)
+            for dist in dists:
+                self.process_distribution(spec, dist, deps)
+        else:
+            dists = [self.egg_distribution(download)]
+            self.process_distribution(spec, dists[0], deps, "Using")
+
+        if spec is not None:
+            for dist in dists:
+                if dist in spec:
+                    return dist
+
+    def select_scheme(self, name):
+        """Sets the install directories by applying the install schemes."""
+        # it's the caller's problem if they supply a bad name!
+        scheme = INSTALL_SCHEMES[name]
+        for key in SCHEME_KEYS:
+            attrname = 'install_' + key
+            if getattr(self, attrname) is None:
+                setattr(self, attrname, scheme[key])
+
+    def process_distribution(self, requirement, dist, deps=True, *info):
+        self.update_pth(dist)
+        self.package_index.add(dist)
+        if dist in self.local_index[dist.key]:
+            self.local_index.remove(dist)
+        self.local_index.add(dist)
+        self.install_egg_scripts(dist)
+        self.installed_projects[dist.key] = dist
+        log.info(self.installation_report(requirement, dist, *info))
+        if (dist.has_metadata('dependency_links.txt') and
+                not self.no_find_links):
+            self.package_index.add_find_links(
+                dist.get_metadata_lines('dependency_links.txt')
+            )
+        if not deps and not self.always_copy:
+            return
+        elif requirement is not None and dist.key != requirement.key:
+            log.warn("Skipping dependencies for %s", dist)
+            return  # XXX this is not the distribution we were looking for
+        elif requirement is None or dist not in requirement:
+            # if we wound up with a different version, resolve what we've got
+            distreq = dist.as_requirement()
+            requirement = Requirement(str(distreq))
+        log.info("Processing dependencies for %s", requirement)
+        try:
+            distros = WorkingSet([]).resolve(
+                [requirement], self.local_index, self.easy_install
+            )
+        except DistributionNotFound as e:
+            raise DistutilsError(str(e))
+        except VersionConflict as e:
+            raise DistutilsError(e.report())
+        if self.always_copy or self.always_copy_from:
+            # Force all the relevant distros to be copied or activated
+            for dist in distros:
+                if dist.key not in self.installed_projects:
+                    self.easy_install(dist.as_requirement())
+        log.info("Finished processing dependencies for %s", requirement)
+
+    def should_unzip(self, dist):
+        if self.zip_ok is not None:
+            return not self.zip_ok
+        if dist.has_metadata('not-zip-safe'):
+            return True
+        if not dist.has_metadata('zip-safe'):
+            return True
+        return False
+
+    def maybe_move(self, spec, dist_filename, setup_base):
+        dst = os.path.join(self.build_directory, spec.key)
+        if os.path.exists(dst):
+            msg = (
+                "%r already exists in %s; build directory %s will not be kept"
+            )
+            log.warn(msg, spec.key, self.build_directory, setup_base)
+            return setup_base
+        if os.path.isdir(dist_filename):
+            setup_base = dist_filename
+        else:
+            if os.path.dirname(dist_filename) == setup_base:
+                os.unlink(dist_filename)  # get it out of the tmp dir
+            contents = os.listdir(setup_base)
+            if len(contents) == 1:
+                dist_filename = os.path.join(setup_base, contents[0])
+                if os.path.isdir(dist_filename):
+                    # if the only thing there is a directory, move it instead
+                    setup_base = dist_filename
+        ensure_directory(dst)
+        shutil.move(setup_base, dst)
+        return dst
+
+    def install_wrapper_scripts(self, dist):
+        if self.exclude_scripts:
+            return
+        for args in ScriptWriter.best().get_args(dist):
+            self.write_script(*args)
+
+    def install_script(self, dist, script_name, script_text, dev_path=None):
+        """Generate a legacy script wrapper and install it"""
+        spec = str(dist.as_requirement())
+        is_script = is_python_script(script_text, script_name)
+
+        if is_script:
+            body = self._load_template(dev_path) % locals()
+            script_text = ScriptWriter.get_header(script_text) + body
+        self.write_script(script_name, _to_ascii(script_text), 'b')
+
+    @staticmethod
+    def _load_template(dev_path):
+        """
+        There are a couple of template scripts in the package. This
+        function loads one of them and prepares it for use.
+        """
+        # See https://github.com/pypa/setuptools/issues/134 for info
+        # on script file naming and downstream issues with SVR4
+        name = 'script.tmpl'
+        if dev_path:
+            name = name.replace('.tmpl', ' (dev).tmpl')
+
+        raw_bytes = resource_string('setuptools', name)
+        return raw_bytes.decode('utf-8')
+
+    def write_script(self, script_name, contents, mode="t", blockers=()):
+        """Write an executable file to the scripts directory"""
+        self.delete_blockers(  # clean up old .py/.pyw w/o a script
+            [os.path.join(self.script_dir, x) for x in blockers]
+        )
+        log.info("Installing %s script to %s", script_name, self.script_dir)
+        target = os.path.join(self.script_dir, script_name)
+        self.add_output(target)
+
+        if self.dry_run:
+            return
+
+        mask = current_umask()
+        ensure_directory(target)
+        if os.path.exists(target):
+            os.unlink(target)
+        with open(target, "w" + mode) as f:
+            f.write(contents)
+        chmod(target, 0o777 - mask)
+
+    def install_eggs(self, spec, dist_filename, tmpdir):
+        # .egg dirs or files are already built, so just return them
+        if dist_filename.lower().endswith('.egg'):
+            return [self.install_egg(dist_filename, tmpdir)]
+        elif dist_filename.lower().endswith('.exe'):
+            return [self.install_exe(dist_filename, tmpdir)]
+        elif dist_filename.lower().endswith('.whl'):
+            return [self.install_wheel(dist_filename, tmpdir)]
+
+        # Anything else, try to extract and build
+        setup_base = tmpdir
+        if os.path.isfile(dist_filename) and not dist_filename.endswith('.py'):
+            unpack_archive(dist_filename, tmpdir, self.unpack_progress)
+        elif os.path.isdir(dist_filename):
+            setup_base = os.path.abspath(dist_filename)
+
+        if (setup_base.startswith(tmpdir)  # something we downloaded
+                and self.build_directory and spec is not None):
+            setup_base = self.maybe_move(spec, dist_filename, setup_base)
+
+        # Find the setup.py file
+        setup_script = os.path.join(setup_base, 'setup.py')
+
+        if not os.path.exists(setup_script):
+            setups = glob(os.path.join(setup_base, '*', 'setup.py'))
+            if not setups:
+                raise DistutilsError(
+                    "Couldn't find a setup script in %s" %
+                    os.path.abspath(dist_filename)
+                )
+            if len(setups) > 1:
+                raise DistutilsError(
+                    "Multiple setup scripts in %s" %
+                    os.path.abspath(dist_filename)
+                )
+            setup_script = setups[0]
+
+        # Now run it, and return the result
+        if self.editable:
+            log.info(self.report_editable(spec, setup_script))
+            return []
+        else:
+            return self.build_and_install(setup_script, setup_base)
+
+    def egg_distribution(self, egg_path):
+        if os.path.isdir(egg_path):
+            metadata = PathMetadata(egg_path, os.path.join(egg_path,
+                                                           'EGG-INFO'))
+        else:
+            metadata = EggMetadata(zipimport.zipimporter(egg_path))
+        return Distribution.from_filename(egg_path, metadata=metadata)
+
+    def install_egg(self, egg_path, tmpdir):
+        destination = os.path.join(
+            self.install_dir,
+            os.path.basename(egg_path),
+        )
+        destination = os.path.abspath(destination)
+        if not self.dry_run:
+            ensure_directory(destination)
+
+        dist = self.egg_distribution(egg_path)
+        if not samefile(egg_path, destination):
+            if os.path.isdir(destination) and not os.path.islink(destination):
+                dir_util.remove_tree(destination, dry_run=self.dry_run)
+            elif os.path.exists(destination):
+                self.execute(
+                    os.unlink,
+                    (destination,),
+                    "Removing " + destination,
+                )
+            try:
+                new_dist_is_zipped = False
+                if os.path.isdir(egg_path):
+                    if egg_path.startswith(tmpdir):
+                        f, m = shutil.move, "Moving"
+                    else:
+                        f, m = shutil.copytree, "Copying"
+                elif self.should_unzip(dist):
+                    self.mkpath(destination)
+                    f, m = self.unpack_and_compile, "Extracting"
+                else:
+                    new_dist_is_zipped = True
+                    if egg_path.startswith(tmpdir):
+                        f, m = shutil.move, "Moving"
+                    else:
+                        f, m = shutil.copy2, "Copying"
+                self.execute(
+                    f,
+                    (egg_path, destination),
+                    (m + " %s to %s") % (
+                        os.path.basename(egg_path),
+                        os.path.dirname(destination)
+                    ),
+                )
+                update_dist_caches(
+                    destination,
+                    fix_zipimporter_caches=new_dist_is_zipped,
+                )
+            except Exception:
+                update_dist_caches(destination, fix_zipimporter_caches=False)
+                raise
+
+        self.add_output(destination)
+        return self.egg_distribution(destination)
+
+    def install_exe(self, dist_filename, tmpdir):
+        # See if it's valid, get data
+        cfg = extract_wininst_cfg(dist_filename)
+        if cfg is None:
+            raise DistutilsError(
+                "%s is not a valid distutils Windows .exe" % dist_filename
+            )
+        # Create a dummy distribution object until we build the real distro
+        dist = Distribution(
+            None,
+            project_name=cfg.get('metadata', 'name'),
+            version=cfg.get('metadata', 'version'), platform=get_platform(),
+        )
+
+        # Convert the .exe to an unpacked egg
+        egg_path = os.path.join(tmpdir, dist.egg_name() + '.egg')
+        dist.location = egg_path
+        egg_tmp = egg_path + '.tmp'
+        _egg_info = os.path.join(egg_tmp, 'EGG-INFO')
+        pkg_inf = os.path.join(_egg_info, 'PKG-INFO')
+        ensure_directory(pkg_inf)  # make sure EGG-INFO dir exists
+        dist._provider = PathMetadata(egg_tmp, _egg_info)  # XXX
+        self.exe_to_egg(dist_filename, egg_tmp)
+
+        # Write EGG-INFO/PKG-INFO
+        if not os.path.exists(pkg_inf):
+            f = open(pkg_inf, 'w')
+            f.write('Metadata-Version: 1.0\n')
+            for k, v in cfg.items('metadata'):
+                if k != 'target_version':
+                    f.write('%s: %s\n' % (k.replace('_', '-').title(), v))
+            f.close()
+        script_dir = os.path.join(_egg_info, 'scripts')
+        # delete entry-point scripts to avoid duping
+        self.delete_blockers([
+            os.path.join(script_dir, args[0])
+            for args in ScriptWriter.get_args(dist)
+        ])
+        # Build .egg file from tmpdir
+        bdist_egg.make_zipfile(
+            egg_path, egg_tmp, verbose=self.verbose, dry_run=self.dry_run,
+        )
+        # install the .egg
+        return self.install_egg(egg_path, tmpdir)
+
+    def exe_to_egg(self, dist_filename, egg_tmp):
+        """Extract a bdist_wininst to the directories an egg would use"""
+        # Check for .pth file and set up prefix translations
+        prefixes = get_exe_prefixes(dist_filename)
+        to_compile = []
+        native_libs = []
+        top_level = {}
+
+        def process(src, dst):
+            s = src.lower()
+            for old, new in prefixes:
+                if s.startswith(old):
+                    src = new + src[len(old):]
+                    parts = src.split('/')
+                    dst = os.path.join(egg_tmp, *parts)
+                    dl = dst.lower()
+                    if dl.endswith('.pyd') or dl.endswith('.dll'):
+                        parts[-1] = bdist_egg.strip_module(parts[-1])
+                        top_level[os.path.splitext(parts[0])[0]] = 1
+                        native_libs.append(src)
+                    elif dl.endswith('.py') and old != 'SCRIPTS/':
+                        top_level[os.path.splitext(parts[0])[0]] = 1
+                        to_compile.append(dst)
+                    return dst
+            if not src.endswith('.pth'):
+                log.warn("WARNING: can't process %s", src)
+            return None
+
+        # extract, tracking .pyd/.dll->native_libs and .py -> to_compile
+        unpack_archive(dist_filename, egg_tmp, process)
+        stubs = []
+        for res in native_libs:
+            if res.lower().endswith('.pyd'):  # create stubs for .pyd's
+                parts = res.split('/')
+                resource = parts[-1]
+                parts[-1] = bdist_egg.strip_module(parts[-1]) + '.py'
+                pyfile = os.path.join(egg_tmp, *parts)
+                to_compile.append(pyfile)
+                stubs.append(pyfile)
+                bdist_egg.write_stub(resource, pyfile)
+        self.byte_compile(to_compile)  # compile .py's
+        bdist_egg.write_safety_flag(
+            os.path.join(egg_tmp, 'EGG-INFO'),
+            bdist_egg.analyze_egg(egg_tmp, stubs))  # write zip-safety flag
+
+        for name in 'top_level', 'native_libs':
+            if locals()[name]:
+                txt = os.path.join(egg_tmp, 'EGG-INFO', name + '.txt')
+                if not os.path.exists(txt):
+                    f = open(txt, 'w')
+                    f.write('\n'.join(locals()[name]) + '\n')
+                    f.close()
+
+    def install_wheel(self, wheel_path, tmpdir):
+        wheel = Wheel(wheel_path)
+        assert wheel.is_compatible()
+        destination = os.path.join(self.install_dir, wheel.egg_name())
+        destination = os.path.abspath(destination)
+        if not self.dry_run:
+            ensure_directory(destination)
+        if os.path.isdir(destination) and not os.path.islink(destination):
+            dir_util.remove_tree(destination, dry_run=self.dry_run)
+        elif os.path.exists(destination):
+            self.execute(
+                os.unlink,
+                (destination,),
+                "Removing " + destination,
+            )
+        try:
+            self.execute(
+                wheel.install_as_egg,
+                (destination,),
+                ("Installing %s to %s") % (
+                    os.path.basename(wheel_path),
+                    os.path.dirname(destination)
+                ),
+            )
+        finally:
+            update_dist_caches(destination, fix_zipimporter_caches=False)
+        self.add_output(destination)
+        return self.egg_distribution(destination)
+
+    __mv_warning = textwrap.dedent("""
+        Because this distribution was installed --multi-version, before you can
+        import modules from this package in an application, you will need to
+        'import pkg_resources' and then use a 'require()' call similar to one of
+        these examples, in order to select the desired version:
+
+            pkg_resources.require("%(name)s")  # latest installed version
+            pkg_resources.require("%(name)s==%(version)s")  # this exact version
+            pkg_resources.require("%(name)s>=%(version)s")  # this version or higher
+        """).lstrip()
+
+    __id_warning = textwrap.dedent("""
+        Note also that the installation directory must be on sys.path at runtime for
+        this to work.  (e.g. by being the application's script directory, by being on
+        PYTHONPATH, or by being added to sys.path by your code.)
+        """)
+
+    def installation_report(self, req, dist, what="Installed"):
+        """Helpful installation message for display to package users"""
+        msg = "\n%(what)s %(eggloc)s%(extras)s"
+        if self.multi_version and not self.no_report:
+            msg += '\n' + self.__mv_warning
+            if self.install_dir not in map(normalize_path, sys.path):
+                msg += '\n' + self.__id_warning
+
+        eggloc = dist.location
+        name = dist.project_name
+        version = dist.version
+        extras = ''  # TODO: self.report_extras(req, dist)
+        return msg % locals()
+
+    __editable_msg = textwrap.dedent("""
+        Extracted editable version of %(spec)s to %(dirname)s
+
+        If it uses setuptools in its setup script, you can activate it in
+        "development" mode by going to that directory and running::
+
+            %(python)s setup.py develop
+
+        See the setuptools documentation for the "develop" command for more info.
+        """).lstrip()
+
+    def report_editable(self, spec, setup_script):
+        dirname = os.path.dirname(setup_script)
+        python = sys.executable
+        return '\n' + self.__editable_msg % locals()
+
+    def run_setup(self, setup_script, setup_base, args):
+        sys.modules.setdefault('distutils.command.bdist_egg', bdist_egg)
+        sys.modules.setdefault('distutils.command.egg_info', egg_info)
+
+        args = list(args)
+        if self.verbose > 2:
+            v = 'v' * (self.verbose - 1)
+            args.insert(0, '-' + v)
+        elif self.verbose < 2:
+            args.insert(0, '-q')
+        if self.dry_run:
+            args.insert(0, '-n')
+        log.info(
+            "Running %s %s", setup_script[len(setup_base) + 1:], ' '.join(args)
+        )
+        try:
+            run_setup(setup_script, args)
+        except SystemExit as v:
+            raise DistutilsError("Setup script exited with %s" % (v.args[0],))
+
+    def build_and_install(self, setup_script, setup_base):
+        args = ['bdist_egg', '--dist-dir']
+
+        dist_dir = tempfile.mkdtemp(
+            prefix='egg-dist-tmp-', dir=os.path.dirname(setup_script)
+        )
+        try:
+            self._set_fetcher_options(os.path.dirname(setup_script))
+            args.append(dist_dir)
+
+            self.run_setup(setup_script, setup_base, args)
+            all_eggs = Environment([dist_dir])
+            eggs = []
+            for key in all_eggs:
+                for dist in all_eggs[key]:
+                    eggs.append(self.install_egg(dist.location, setup_base))
+            if not eggs and not self.dry_run:
+                log.warn("No eggs found in %s (setup script problem?)",
+                         dist_dir)
+            return eggs
+        finally:
+            rmtree(dist_dir)
+            log.set_verbosity(self.verbose)  # restore our log verbosity
+
+    def _set_fetcher_options(self, base):
+        """
+        When easy_install is about to run bdist_egg on a source dist, that
+        source dist might have 'setup_requires' directives, requiring
+        additional fetching. Ensure the fetcher options given to easy_install
+        are available to that command as well.
+        """
+        # find the fetch options from easy_install and write them out
+        # to the setup.cfg file.
+        ei_opts = self.distribution.get_option_dict('easy_install').copy()
+        fetch_directives = (
+            'find_links', 'site_dirs', 'index_url', 'optimize',
+            'site_dirs', 'allow_hosts',
+        )
+        fetch_options = {}
+        for key, val in ei_opts.items():
+            if key not in fetch_directives:
+                continue
+            fetch_options[key.replace('_', '-')] = val[1]
+        # create a settings dictionary suitable for `edit_config`
+        settings = dict(easy_install=fetch_options)
+        cfg_filename = os.path.join(base, 'setup.cfg')
+        setopt.edit_config(cfg_filename, settings)
+
+    def update_pth(self, dist):
+        if self.pth_file is None:
+            return
+
+        for d in self.pth_file[dist.key]:  # drop old entries
+            if self.multi_version or d.location != dist.location:
+                log.info("Removing %s from easy-install.pth file", d)
+                self.pth_file.remove(d)
+                if d.location in self.shadow_path:
+                    self.shadow_path.remove(d.location)
+
+        if not self.multi_version:
+            if dist.location in self.pth_file.paths:
+                log.info(
+                    "%s is already the active version in easy-install.pth",
+                    dist,
+                )
+            else:
+                log.info("Adding %s to easy-install.pth file", dist)
+                self.pth_file.add(dist)  # add new entry
+                if dist.location not in self.shadow_path:
+                    self.shadow_path.append(dist.location)
+
+        if not self.dry_run:
+
+            self.pth_file.save()
+
+            if dist.key == 'setuptools':
+                # Ensure that setuptools itself never becomes unavailable!
+                # XXX should this check for latest version?
+                filename = os.path.join(self.install_dir, 'setuptools.pth')
+                if os.path.islink(filename):
+                    os.unlink(filename)
+                f = open(filename, 'wt')
+                f.write(self.pth_file.make_relative(dist.location) + '\n')
+                f.close()
+
+    def unpack_progress(self, src, dst):
+        # Progress filter for unpacking
+        log.debug("Unpacking %s to %s", src, dst)
+        return dst  # only unpack-and-compile skips files for dry run
+
+    def unpack_and_compile(self, egg_path, destination):
+        to_compile = []
+        to_chmod = []
+
+        def pf(src, dst):
+            if dst.endswith('.py') and not src.startswith('EGG-INFO/'):
+                to_compile.append(dst)
+            elif dst.endswith('.dll') or dst.endswith('.so'):
+                to_chmod.append(dst)
+            self.unpack_progress(src, dst)
+            return not self.dry_run and dst or None
+
+        unpack_archive(egg_path, destination, pf)
+        self.byte_compile(to_compile)
+        if not self.dry_run:
+            for f in to_chmod:
+                mode = ((os.stat(f)[stat.ST_MODE]) | 0o555) & 0o7755
+                chmod(f, mode)
+
+    def byte_compile(self, to_compile):
+        if sys.dont_write_bytecode:
+            return
+
+        from distutils.util import byte_compile
+
+        try:
+            # try to make the byte compile messages quieter
+            log.set_verbosity(self.verbose - 1)
+
+            byte_compile(to_compile, optimize=0, force=1, dry_run=self.dry_run)
+            if self.optimize:
+                byte_compile(
+                    to_compile, optimize=self.optimize, force=1,
+                    dry_run=self.dry_run,
+                )
+        finally:
+            log.set_verbosity(self.verbose)  # restore original verbosity
+
+    __no_default_msg = textwrap.dedent("""
+        bad install directory or PYTHONPATH
+
+        You are attempting to install a package to a directory that is not
+        on PYTHONPATH and which Python does not read ".pth" files from.  The
+        installation directory you specified (via --install-dir, --prefix, or
+        the distutils default setting) was:
+
+            %s
+
+        and your PYTHONPATH environment variable currently contains:
+
+            %r
+
+        Here are some of your options for correcting the problem:
+
+        * You can choose a different installation directory, i.e., one that is
+          on PYTHONPATH or supports .pth files
+
+        * You can add the installation directory to the PYTHONPATH environment
+          variable.  (It must then also be on PYTHONPATH whenever you run
+          Python and want to use the package(s) you are installing.)
+
+        * You can set up the installation directory to support ".pth" files by
+          using one of the approaches described here:
+
+          https://setuptools.readthedocs.io/en/latest/easy_install.html#custom-installation-locations
+
+
+        Please make the appropriate changes for your system and try again.""").lstrip()
+
+    def no_default_version_msg(self):
+        template = self.__no_default_msg
+        return template % (self.install_dir, os.environ.get('PYTHONPATH', ''))
+
+    def install_site_py(self):
+        """Make sure there's a site.py in the target dir, if needed"""
+
+        if self.sitepy_installed:
+            return  # already did it, or don't need to
+
+        sitepy = os.path.join(self.install_dir, "site.py")
+        source = resource_string("setuptools", "site-patch.py")
+        source = source.decode('utf-8')
+        current = ""
+
+        if os.path.exists(sitepy):
+            log.debug("Checking existing site.py in %s", self.install_dir)
+            with io.open(sitepy) as strm:
+                current = strm.read()
+
+            if not current.startswith('def __boot():'):
+                raise DistutilsError(
+                    "%s is not a setuptools-generated site.py; please"
+                    " remove it." % sitepy
+                )
+
+        if current != source:
+            log.info("Creating %s", sitepy)
+            if not self.dry_run:
+                ensure_directory(sitepy)
+                with io.open(sitepy, 'w', encoding='utf-8') as strm:
+                    strm.write(source)
+            self.byte_compile([sitepy])
+
+        self.sitepy_installed = True
+
+    def create_home_path(self):
+        """Create directories under ~."""
+        if not self.user:
+            return
+        home = convert_path(os.path.expanduser("~"))
+        for name, path in six.iteritems(self.config_vars):
+            if path.startswith(home) and not os.path.isdir(path):
+                self.debug_print("os.makedirs('%s', 0o700)" % path)
+                os.makedirs(path, 0o700)
+
+    INSTALL_SCHEMES = dict(
+        posix=dict(
+            install_dir='$base/lib/python$py_version_short/site-packages',
+            script_dir='$base/bin',
+        ),
+    )
+
+    DEFAULT_SCHEME = dict(
+        install_dir='$base/Lib/site-packages',
+        script_dir='$base/Scripts',
+    )
+
+    def _expand(self, *attrs):
+        config_vars = self.get_finalized_command('install').config_vars
+
+        if self.prefix:
+            # Set default install_dir/scripts from --prefix
+            config_vars = config_vars.copy()
+            config_vars['base'] = self.prefix
+            scheme = self.INSTALL_SCHEMES.get(os.name, self.DEFAULT_SCHEME)
+            for attr, val in scheme.items():
+                if getattr(self, attr, None) is None:
+                    setattr(self, attr, val)
+
+        from distutils.util import subst_vars
+
+        for attr in attrs:
+            val = getattr(self, attr)
+            if val is not None:
+                val = subst_vars(val, config_vars)
+                if os.name == 'posix':
+                    val = os.path.expanduser(val)
+                setattr(self, attr, val)
+
+
+def _pythonpath():
+    items = os.environ.get('PYTHONPATH', '').split(os.pathsep)
+    return filter(None, items)
+
+
+def get_site_dirs():
+    """
+    Return a list of 'site' dirs
+    """
+
+    sitedirs = []
+
+    # start with PYTHONPATH
+    sitedirs.extend(_pythonpath())
+
+    prefixes = [sys.prefix]
+    if sys.exec_prefix != sys.prefix:
+        prefixes.append(sys.exec_prefix)
+    for prefix in prefixes:
+        if prefix:
+            if sys.platform in ('os2emx', 'riscos'):
+                sitedirs.append(os.path.join(prefix, "Lib", "site-packages"))
+            elif os.sep == '/':
+                sitedirs.extend([
+                    os.path.join(
+                        prefix,
+                        "lib",
+                        "python" + sys.version[:3],
+                        "site-packages",
+                    ),
+                    os.path.join(prefix, "lib", "site-python"),
+                ])
+            else:
+                sitedirs.extend([
+                    prefix,
+                    os.path.join(prefix, "lib", "site-packages"),
+                ])
+            if sys.platform == 'darwin':
+                # for framework builds *only* we add the standard Apple
+                # locations. Currently only per-user, but /Library and
+                # /Network/Library could be added too
+                if 'Python.framework' in prefix:
+                    home = os.environ.get('HOME')
+                    if home:
+                        home_sp = os.path.join(
+                            home,
+                            'Library',
+                            'Python',
+                            sys.version[:3],
+                            'site-packages',
+                        )
+                        sitedirs.append(home_sp)
+    lib_paths = get_path('purelib'), get_path('platlib')
+    for site_lib in lib_paths:
+        if site_lib not in sitedirs:
+            sitedirs.append(site_lib)
+
+    if site.ENABLE_USER_SITE:
+        sitedirs.append(site.USER_SITE)
+
+    try:
+        sitedirs.extend(site.getsitepackages())
+    except AttributeError:
+        pass
+
+    sitedirs = list(map(normalize_path, sitedirs))
+
+    return sitedirs
+
+
+def expand_paths(inputs):
+    """Yield sys.path directories that might contain "old-style" packages"""
+
+    seen = {}
+
+    for dirname in inputs:
+        dirname = normalize_path(dirname)
+        if dirname in seen:
+            continue
+
+        seen[dirname] = 1
+        if not os.path.isdir(dirname):
+            continue
+
+        files = os.listdir(dirname)
+        yield dirname, files
+
+        for name in files:
+            if not name.endswith('.pth'):
+                # We only care about the .pth files
+                continue
+            if name in ('easy-install.pth', 'setuptools.pth'):
+                # Ignore .pth files that we control
+                continue
+
+            # Read the .pth file
+            f = open(os.path.join(dirname, name))
+            lines = list(yield_lines(f))
+            f.close()
+
+            # Yield existing non-dupe, non-import directory lines from it
+            for line in lines:
+                if not line.startswith("import"):
+                    line = normalize_path(line.rstrip())
+                    if line not in seen:
+                        seen[line] = 1
+                        if not os.path.isdir(line):
+                            continue
+                        yield line, os.listdir(line)
+
+
+def extract_wininst_cfg(dist_filename):
+    """Extract configuration data from a bdist_wininst .exe
+
+    Returns a configparser.RawConfigParser, or None
+    """
+    f = open(dist_filename, 'rb')
+    try:
+        endrec = zipfile._EndRecData(f)
+        if endrec is None:
+            return None
+
+        prepended = (endrec[9] - endrec[5]) - endrec[6]
+        if prepended < 12:  # no wininst data here
+            return None
+        f.seek(prepended - 12)
+
+        tag, cfglen, bmlen = struct.unpack("<iii", f.read(12))
+        if tag not in (0x1234567A, 0x1234567B):
+            return None  # not a valid tag
+
+        f.seek(prepended - (12 + cfglen))
+        init = {'version': '', 'target_version': ''}
+        cfg = configparser.RawConfigParser(init)
+        try:
+            part = f.read(cfglen)
+            # Read up to the first null byte.
+            config = part.split(b'\0', 1)[0]
+            # Now the config is in bytes, but for RawConfigParser, it should
+            #  be text, so decode it.
+            config = config.decode(sys.getfilesystemencoding())
+            cfg.readfp(six.StringIO(config))
+        except configparser.Error:
+            return None
+        if not cfg.has_section('metadata') or not cfg.has_section('Setup'):
+            return None
+        return cfg
+
+    finally:
+        f.close()
+
+
+def get_exe_prefixes(exe_filename):
+    """Get exe->egg path translations for a given .exe file"""
+
+    prefixes = [
+        ('PURELIB/', ''),
+        ('PLATLIB/pywin32_system32', ''),
+        ('PLATLIB/', ''),
+        ('SCRIPTS/', 'EGG-INFO/scripts/'),
+        ('DATA/lib/site-packages', ''),
+    ]
+    z = zipfile.ZipFile(exe_filename)
+    try:
+        for info in z.infolist():
+            name = info.filename
+            parts = name.split('/')
+            if len(parts) == 3 and parts[2] == 'PKG-INFO':
+                if parts[1].endswith('.egg-info'):
+                    prefixes.insert(0, ('/'.join(parts[:2]), 'EGG-INFO/'))
+                    break
+            if len(parts) != 2 or not name.endswith('.pth'):
+                continue
+            if name.endswith('-nspkg.pth'):
+                continue
+            if parts[0].upper() in ('PURELIB', 'PLATLIB'):
+                contents = z.read(name)
+                if six.PY3:
+                    contents = contents.decode()
+                for pth in yield_lines(contents):
+                    pth = pth.strip().replace('\\', '/')
+                    if not pth.startswith('import'):
+                        prefixes.append((('%s/%s/' % (parts[0], pth)), ''))
+    finally:
+        z.close()
+    prefixes = [(x.lower(), y) for x, y in prefixes]
+    prefixes.sort()
+    prefixes.reverse()
+    return prefixes
+
+
+class PthDistributions(Environment):
+    """A .pth file with Distribution paths in it"""
+
+    dirty = False
+
+    def __init__(self, filename, sitedirs=()):
+        self.filename = filename
+        self.sitedirs = list(map(normalize_path, sitedirs))
+        self.basedir = normalize_path(os.path.dirname(self.filename))
+        self._load()
+        Environment.__init__(self, [], None, None)
+        for path in yield_lines(self.paths):
+            list(map(self.add, find_distributions(path, True)))
+
+    def _load(self):
+        self.paths = []
+        saw_import = False
+        seen = dict.fromkeys(self.sitedirs)
+        if os.path.isfile(self.filename):
+            f = open(self.filename, 'rt')
+            for line in f:
+                if line.startswith('import'):
+                    saw_import = True
+                    continue
+                path = line.rstrip()
+                self.paths.append(path)
+                if not path.strip() or path.strip().startswith('#'):
+                    continue
+                # skip non-existent paths, in case somebody deleted a package
+                # manually, and duplicate paths as well
+                path = self.paths[-1] = normalize_path(
+                    os.path.join(self.basedir, path)
+                )
+                if not os.path.exists(path) or path in seen:
+                    self.paths.pop()  # skip it
+                    self.dirty = True  # we cleaned up, so we're dirty now :)
+                    continue
+                seen[path] = 1
+            f.close()
+
+        if self.paths and not saw_import:
+            self.dirty = True  # ensure anything we touch has import wrappers
+        while self.paths and not self.paths[-1].strip():
+            self.paths.pop()
+
+    def save(self):
+        """Write changed .pth file back to disk"""
+        if not self.dirty:
+            return
+
+        rel_paths = list(map(self.make_relative, self.paths))
+        if rel_paths:
+            log.debug("Saving %s", self.filename)
+            lines = self._wrap_lines(rel_paths)
+            data = '\n'.join(lines) + '\n'
+
+            if os.path.islink(self.filename):
+                os.unlink(self.filename)
+            with open(self.filename, 'wt') as f:
+                f.write(data)
+
+        elif os.path.exists(self.filename):
+            log.debug("Deleting empty %s", self.filename)
+            os.unlink(self.filename)
+
+        self.dirty = False
+
+    @staticmethod
+    def _wrap_lines(lines):
+        return lines
+
+    def add(self, dist):
+        """Add `dist` to the distribution map"""
+        new_path = (
+            dist.location not in self.paths and (
+                dist.location not in self.sitedirs or
+                # account for '.' being in PYTHONPATH
+                dist.location == os.getcwd()
+            )
+        )
+        if new_path:
+            self.paths.append(dist.location)
+            self.dirty = True
+        Environment.add(self, dist)
+
+    def remove(self, dist):
+        """Remove `dist` from the distribution map"""
+        while dist.location in self.paths:
+            self.paths.remove(dist.location)
+            self.dirty = True
+        Environment.remove(self, dist)
+
+    def make_relative(self, path):
+        npath, last = os.path.split(normalize_path(path))
+        baselen = len(self.basedir)
+        parts = [last]
+        sep = os.altsep == '/' and '/' or os.sep
+        while len(npath) >= baselen:
+            if npath == self.basedir:
+                parts.append(os.curdir)
+                parts.reverse()
+                return sep.join(parts)
+            npath, last = os.path.split(npath)
+            parts.append(last)
+        else:
+            return path
+
+
+class RewritePthDistributions(PthDistributions):
+    @classmethod
+    def _wrap_lines(cls, lines):
+        yield cls.prelude
+        for line in lines:
+            yield line
+        yield cls.postlude
+
+    prelude = _one_liner("""
+        import sys
+        sys.__plen = len(sys.path)
+        """)
+    postlude = _one_liner("""
+        import sys
+        new = sys.path[sys.__plen:]
+        del sys.path[sys.__plen:]
+        p = getattr(sys, '__egginsert', 0)
+        sys.path[p:p] = new
+        sys.__egginsert = p + len(new)
+        """)
+
+
+if os.environ.get('SETUPTOOLS_SYS_PATH_TECHNIQUE', 'raw') == 'rewrite':
+    PthDistributions = RewritePthDistributions
+
+
+def _first_line_re():
+    """
+    Return a regular expression based on first_line_re suitable for matching
+    strings.
+    """
+    if isinstance(first_line_re.pattern, str):
+        return first_line_re
+
+    # first_line_re in Python >=3.1.4 and >=3.2.1 is a bytes pattern.
+    return re.compile(first_line_re.pattern.decode())
+
+
+def auto_chmod(func, arg, exc):
+    if func in [os.unlink, os.remove] and os.name == 'nt':
+        chmod(arg, stat.S_IWRITE)
+        return func(arg)
+    et, ev, _ = sys.exc_info()
+    six.reraise(et, (ev[0], ev[1] + (" %s %s" % (func, arg))))
+
+
+def update_dist_caches(dist_path, fix_zipimporter_caches):
+    """
+    Fix any globally cached `dist_path` related data
+
+    `dist_path` should be a path of a newly installed egg distribution (zipped
+    or unzipped).
+
+    sys.path_importer_cache contains finder objects that have been cached when
+    importing data from the original distribution. Any such finders need to be
+    cleared since the replacement distribution might be packaged differently,
+    e.g. a zipped egg distribution might get replaced with an unzipped egg
+    folder or vice versa. Having the old finders cached may then cause Python
+    to attempt loading modules from the replacement distribution using an
+    incorrect loader.
+
+    zipimport.zipimporter objects are Python loaders charged with importing
+    data packaged inside zip archives. If stale loaders referencing the
+    original distribution, are left behind, they can fail to load modules from
+    the replacement distribution. E.g. if an old zipimport.zipimporter instance
+    is used to load data from a new zipped egg archive, it may cause the
+    operation to attempt to locate the requested data in the wrong location -
+    one indicated by the original distribution's zip archive directory
+    information. Such an operation may then fail outright, e.g. report having
+    read a 'bad local file header', or even worse, it may fail silently &
+    return invalid data.
+
+    zipimport._zip_directory_cache contains cached zip archive directory
+    information for all existing zipimport.zipimporter instances and all such
+    instances connected to the same archive share the same cached directory
+    information.
+
+    If asked, and the underlying Python implementation allows it, we can fix
+    all existing zipimport.zipimporter instances instead of having to track
+    them down and remove them one by one, by updating their shared cached zip
+    archive directory information. This, of course, assumes that the
+    replacement distribution is packaged as a zipped egg.
+
+    If not asked to fix existing zipimport.zipimporter instances, we still do
+    our best to clear any remaining zipimport.zipimporter related cached data
+    that might somehow later get used when attempting to load data from the new
+    distribution and thus cause such load operations to fail. Note that when
+    tracking down such remaining stale data, we can not catch every conceivable
+    usage from here, and we clear only those that we know of and have found to
+    cause problems if left alive. Any remaining caches should be updated by
+    whomever is in charge of maintaining them, i.e. they should be ready to
+    handle us replacing their zip archives with new distributions at runtime.
+
+    """
+    # There are several other known sources of stale zipimport.zipimporter
+    # instances that we do not clear here, but might if ever given a reason to
+    # do so:
+    # * Global setuptools pkg_resources.working_set (a.k.a. 'master working
+    # set') may contain distributions which may in turn contain their
+    #   zipimport.zipimporter loaders.
+    # * Several zipimport.zipimporter loaders held by local variables further
+    #   up the function call stack when running the setuptools installation.
+    # * Already loaded modules may have their __loader__ attribute set to the
+    #   exact loader instance used when importing them. Python 3.4 docs state
+    #   that this information is intended mostly for introspection and so is
+    #   not expected to cause us problems.
+    normalized_path = normalize_path(dist_path)
+    _uncache(normalized_path, sys.path_importer_cache)
+    if fix_zipimporter_caches:
+        _replace_zip_directory_cache_data(normalized_path)
+    else:
+        # Here, even though we do not want to fix existing and now stale
+        # zipimporter cache information, we still want to remove it. Related to
+        # Python's zip archive directory information cache, we clear each of
+        # its stale entries in two phases:
+        #   1. Clear the entry so attempting to access zip archive information
+        #      via any existing stale zipimport.zipimporter instances fails.
+        #   2. Remove the entry from the cache so any newly constructed
+        #      zipimport.zipimporter instances do not end up using old stale
+        #      zip archive directory information.
+        # This whole stale data removal step does not seem strictly necessary,
+        # but has been left in because it was done before we started replacing
+        # the zip archive directory information cache content if possible, and
+        # there are no relevant unit tests that we can depend on to tell us if
+        # this is really needed.
+        _remove_and_clear_zip_directory_cache_data(normalized_path)
+
+
+def _collect_zipimporter_cache_entries(normalized_path, cache):
+    """
+    Return zipimporter cache entry keys related to a given normalized path.
+
+    Alternative path spellings (e.g. those using different character case or
+    those using alternative path separators) related to the same path are
+    included. Any sub-path entries are included as well, i.e. those
+    corresponding to zip archives embedded in other zip archives.
+
+    """
+    result = []
+    prefix_len = len(normalized_path)
+    for p in cache:
+        np = normalize_path(p)
+        if (np.startswith(normalized_path) and
+                np[prefix_len:prefix_len + 1] in (os.sep, '')):
+            result.append(p)
+    return result
+
+
+def _update_zipimporter_cache(normalized_path, cache, updater=None):
+    """
+    Update zipimporter cache data for a given normalized path.
+
+    Any sub-path entries are processed as well, i.e. those corresponding to zip
+    archives embedded in other zip archives.
+
+    Given updater is a callable taking a cache entry key and the original entry
+    (after already removing the entry from the cache), and expected to update
+    the entry and possibly return a new one to be inserted in its place.
+    Returning None indicates that the entry should not be replaced with a new
+    one. If no updater is given, the cache entries are simply removed without
+    any additional processing, the same as if the updater simply returned None.
+
+    """
+    for p in _collect_zipimporter_cache_entries(normalized_path, cache):
+        # N.B. pypy's custom zipimport._zip_directory_cache implementation does
+        # not support the complete dict interface:
+        # * Does not support item assignment, thus not allowing this function
+        #    to be used only for removing existing cache entries.
+        #  * Does not support the dict.pop() method, forcing us to use the
+        #    get/del patterns instead. For more detailed information see the
+        #    following links:
+        #      https://github.com/pypa/setuptools/issues/202#issuecomment-202913420
+        #      http://bit.ly/2h9itJX
+        old_entry = cache[p]
+        del cache[p]
+        new_entry = updater and updater(p, old_entry)
+        if new_entry is not None:
+            cache[p] = new_entry
+
+
+def _uncache(normalized_path, cache):
+    _update_zipimporter_cache(normalized_path, cache)
+
+
+def _remove_and_clear_zip_directory_cache_data(normalized_path):
+    def clear_and_remove_cached_zip_archive_directory_data(path, old_entry):
+        old_entry.clear()
+
+    _update_zipimporter_cache(
+        normalized_path, zipimport._zip_directory_cache,
+        updater=clear_and_remove_cached_zip_archive_directory_data)
+
+
+# PyPy Python implementation does not allow directly writing to the
+# zipimport._zip_directory_cache and so prevents us from attempting to correct
+# its content. The best we can do there is clear the problematic cache content
+# and have PyPy repopulate it as needed. The downside is that if there are any
+# stale zipimport.zipimporter instances laying around, attempting to use them
+# will fail due to not having its zip archive directory information available
+# instead of being automatically corrected to use the new correct zip archive
+# directory information.
+if '__pypy__' in sys.builtin_module_names:
+    _replace_zip_directory_cache_data = \
+        _remove_and_clear_zip_directory_cache_data
+else:
+
+    def _replace_zip_directory_cache_data(normalized_path):
+        def replace_cached_zip_archive_directory_data(path, old_entry):
+            # N.B. In theory, we could load the zip directory information just
+            # once for all updated path spellings, and then copy it locally and
+            # update its contained path strings to contain the correct
+            # spelling, but that seems like a way too invasive move (this cache
+            # structure is not officially documented anywhere and could in
+            # theory change with new Python releases) for no significant
+            # benefit.
+            old_entry.clear()
+            zipimport.zipimporter(path)
+            old_entry.update(zipimport._zip_directory_cache[path])
+            return old_entry
+
+        _update_zipimporter_cache(
+            normalized_path, zipimport._zip_directory_cache,
+            updater=replace_cached_zip_archive_directory_data)
+
+
+def is_python(text, filename='<string>'):
+    "Is this string a valid Python script?"
+    try:
+        compile(text, filename, 'exec')
+    except (SyntaxError, TypeError):
+        return False
+    else:
+        return True
+
+
+def is_sh(executable):
+    """Determine if the specified executable is a .sh (contains a #! line)"""
+    try:
+        with io.open(executable, encoding='latin-1') as fp:
+            magic = fp.read(2)
+    except (OSError, IOError):
+        return executable
+    return magic == '#!'
+
+
+def nt_quote_arg(arg):
+    """Quote a command line argument according to Windows parsing rules"""
+    return subprocess.list2cmdline([arg])
+
+
+def is_python_script(script_text, filename):
+    """Is this text, as a whole, a Python script? (as opposed to shell/bat/etc.
+    """
+    if filename.endswith('.py') or filename.endswith('.pyw'):
+        return True  # extension says it's Python
+    if is_python(script_text, filename):
+        return True  # it's syntactically valid Python
+    if script_text.startswith('#!'):
+        # It begins with a '#!' line, so check if 'python' is in it somewhere
+        return 'python' in script_text.splitlines()[0].lower()
+
+    return False  # Not any Python I can recognize
+
+
+try:
+    from os import chmod as _chmod
+except ImportError:
+    # Jython compatibility
+    def _chmod(*args):
+        pass
+
+
+def chmod(path, mode):
+    log.debug("changing mode of %s to %o", path, mode)
+    try:
+        _chmod(path, mode)
+    except os.error as e:
+        log.debug("chmod failed: %s", e)
+
+
+class CommandSpec(list):
+    """
+    A command spec for a #! header, specified as a list of arguments akin to
+    those passed to Popen.
+    """
+
+    options = []
+    split_args = dict()
+
+    @classmethod
+    def best(cls):
+        """
+        Choose the best CommandSpec class based on environmental conditions.
+        """
+        return cls
+
+    @classmethod
+    def _sys_executable(cls):
+        _default = os.path.normpath(sys.executable)
+        return os.environ.get('__PYVENV_LAUNCHER__', _default)
+
+    @classmethod
+    def from_param(cls, param):
+        """
+        Construct a CommandSpec from a parameter to build_scripts, which may
+        be None.
+        """
+        if isinstance(param, cls):
+            return param
+        if isinstance(param, list):
+            return cls(param)
+        if param is None:
+            return cls.from_environment()
+        # otherwise, assume it's a string.
+        return cls.from_string(param)
+
+    @classmethod
+    def from_environment(cls):
+        return cls([cls._sys_executable()])
+
+    @classmethod
+    def from_string(cls, string):
+        """
+        Construct a command spec from a simple string representing a command
+        line parseable by shlex.split.
+        """
+        items = shlex.split(string, **cls.split_args)
+        return cls(items)
+
+    def install_options(self, script_text):
+        self.options = shlex.split(self._extract_options(script_text))
+        cmdline = subprocess.list2cmdline(self)
+        if not isascii(cmdline):
+            self.options[:0] = ['-x']
+
+    @staticmethod
+    def _extract_options(orig_script):
+        """
+        Extract any options from the first line of the script.
+        """
+        first = (orig_script + '\n').splitlines()[0]
+        match = _first_line_re().match(first)
+        options = match.group(1) or '' if match else ''
+        return options.strip()
+
+    def as_header(self):
+        return self._render(self + list(self.options))
+
+    @staticmethod
+    def _strip_quotes(item):
+        _QUOTES = '"\''
+        for q in _QUOTES:
+            if item.startswith(q) and item.endswith(q):
+                return item[1:-1]
+        return item
+
+    @staticmethod
+    def _render(items):
+        cmdline = subprocess.list2cmdline(
+            CommandSpec._strip_quotes(item.strip()) for item in items)
+        return '#!' + cmdline + '\n'
+
+
+# For pbr compat; will be removed in a future version.
+sys_executable = CommandSpec._sys_executable()
+
+
+class WindowsCommandSpec(CommandSpec):
+    split_args = dict(posix=False)
+
+
+class ScriptWriter(object):
+    """
+    Encapsulates behavior around writing entry point scripts for console and
+    gui apps.
+    """
+
+    template = textwrap.dedent(r"""
+        # EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r
+        __requires__ = %(spec)r
+        import re
+        import sys
+        from pkg_resources import load_entry_point
+
+        if __name__ == '__main__':
+            sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
+            sys.exit(
+                load_entry_point(%(spec)r, %(group)r, %(name)r)()
+            )
+    """).lstrip()
+
+    command_spec_class = CommandSpec
+
+    @classmethod
+    def get_script_args(cls, dist, executable=None, wininst=False):
+        # for backward compatibility
+        warnings.warn("Use get_args", DeprecationWarning)
+        writer = (WindowsScriptWriter if wininst else ScriptWriter).best()
+        header = cls.get_script_header("", executable, wininst)
+        return writer.get_args(dist, header)
+
+    @classmethod
+    def get_script_header(cls, script_text, executable=None, wininst=False):
+        # for backward compatibility
+        warnings.warn("Use get_header", DeprecationWarning)
+        if wininst:
+            executable = "python.exe"
+        cmd = cls.command_spec_class.best().from_param(executable)
+        cmd.install_options(script_text)
+        return cmd.as_header()
+
+    @classmethod
+    def get_args(cls, dist, header=None):
+        """
+        Yield write_script() argument tuples for a distribution's
+        console_scripts and gui_scripts entry points.
+        """
+        if header is None:
+            header = cls.get_header()
+        spec = str(dist.as_requirement())
+        for type_ in 'console', 'gui':
+            group = type_ + '_scripts'
+            for name, ep in dist.get_entry_map(group).items():
+                cls._ensure_safe_name(name)
+                script_text = cls.template % locals()
+                args = cls._get_script_args(type_, name, header, script_text)
+                for res in args:
+                    yield res
+
+    @staticmethod
+    def _ensure_safe_name(name):
+        """
+        Prevent paths in *_scripts entry point names.
+        """
+        has_path_sep = re.search(r'[\\/]', name)
+        if has_path_sep:
+            raise ValueError("Path separators not allowed in script names")
+
+    @classmethod
+    def get_writer(cls, force_windows):
+        # for backward compatibility
+        warnings.warn("Use best", DeprecationWarning)
+        return WindowsScriptWriter.best() if force_windows else cls.best()
+
+    @classmethod
+    def best(cls):
+        """
+        Select the best ScriptWriter for this environment.
+        """
+        if sys.platform == 'win32' or (os.name == 'java' and os._name == 'nt'):
+            return WindowsScriptWriter.best()
+        else:
+            return cls
+
+    @classmethod
+    def _get_script_args(cls, type_, name, header, script_text):
+        # Simply write the stub with no extension.
+        yield (name, header + script_text)
+
+    @classmethod
+    def get_header(cls, script_text="", executable=None):
+        """Create a #! line, getting options (if any) from script_text"""
+        cmd = cls.command_spec_class.best().from_param(executable)
+        cmd.install_options(script_text)
+        return cmd.as_header()
+
+
+class WindowsScriptWriter(ScriptWriter):
+    command_spec_class = WindowsCommandSpec
+
+    @classmethod
+    def get_writer(cls):
+        # for backward compatibility
+        warnings.warn("Use best", DeprecationWarning)
+        return cls.best()
+
+    @classmethod
+    def best(cls):
+        """
+        Select the best ScriptWriter suitable for Windows
+        """
+        writer_lookup = dict(
+            executable=WindowsExecutableLauncherWriter,
+            natural=cls,
+        )
+        # for compatibility, use the executable launcher by default
+        launcher = os.environ.get('SETUPTOOLS_LAUNCHER', 'executable')
+        return writer_lookup[launcher]
+
+    @classmethod
+    def _get_script_args(cls, type_, name, header, script_text):
+        "For Windows, add a .py extension"
+        ext = dict(console='.pya', gui='.pyw')[type_]
+        if ext not in os.environ['PATHEXT'].lower().split(';'):
+            msg = (
+                "{ext} not listed in PATHEXT; scripts will not be "
+                "recognized as executables."
+            ).format(**locals())
+            warnings.warn(msg, UserWarning)
+        old = ['.pya', '.py', '-script.py', '.pyc', '.pyo', '.pyw', '.exe']
+        old.remove(ext)
+        header = cls._adjust_header(type_, header)
+        blockers = [name + x for x in old]
+        yield name + ext, header + script_text, 't', blockers
+
+    @classmethod
+    def _adjust_header(cls, type_, orig_header):
+        """
+        Make sure 'pythonw' is used for gui and and 'python' is used for
+        console (regardless of what sys.executable is).
+        """
+        pattern = 'pythonw.exe'
+        repl = 'python.exe'
+        if type_ == 'gui':
+            pattern, repl = repl, pattern
+        pattern_ob = re.compile(re.escape(pattern), re.IGNORECASE)
+        new_header = pattern_ob.sub(string=orig_header, repl=repl)
+        return new_header if cls._use_header(new_header) else orig_header
+
+    @staticmethod
+    def _use_header(new_header):
+        """
+        Should _adjust_header use the replaced header?
+
+        On non-windows systems, always use. On
+        Windows systems, only use the replaced header if it resolves
+        to an executable on the system.
+        """
+        clean_header = new_header[2:-1].strip('"')
+        return sys.platform != 'win32' or find_executable(clean_header)
+
+
+class WindowsExecutableLauncherWriter(WindowsScriptWriter):
+    @classmethod
+    def _get_script_args(cls, type_, name, header, script_text):
+        """
+        For Windows, add a .py extension and an .exe launcher
+        """
+        if type_ == 'gui':
+            launcher_type = 'gui'
+            ext = '-script.pyw'
+            old = ['.pyw']
+        else:
+            launcher_type = 'cli'
+            ext = '-script.py'
+            old = ['.py', '.pyc', '.pyo']
+        hdr = cls._adjust_header(type_, header)
+        blockers = [name + x for x in old]
+        yield (name + ext, hdr + script_text, 't', blockers)
+        yield (
+            name + '.exe', get_win_launcher(launcher_type),
+            'b'  # write in binary mode
+        )
+        if not is_64bit():
+            # install a manifest for the launcher to prevent Windows
+            # from detecting it as an installer (which it will for
+            #  launchers like easy_install.exe). Consider only
+            #  adding a manifest for launchers detected as installers.
+            #  See Distribute #143 for details.
+            m_name = name + '.exe.manifest'
+            yield (m_name, load_launcher_manifest(name), 't')
+
+
+# for backward-compatibility
+get_script_args = ScriptWriter.get_script_args
+get_script_header = ScriptWriter.get_script_header
+
+
+def get_win_launcher(type):
+    """
+    Load the Windows launcher (executable) suitable for launching a script.
+
+    `type` should be either 'cli' or 'gui'
+
+    Returns the executable as a byte string.
+    """
+    launcher_fn = '%s.exe' % type
+    if is_64bit():
+        launcher_fn = launcher_fn.replace(".", "-64.")
+    else:
+        launcher_fn = launcher_fn.replace(".", "-32.")
+    return resource_string('setuptools', launcher_fn)
+
+
+def load_launcher_manifest(name):
+    manifest = pkg_resources.resource_string(__name__, 'launcher manifest.xml')
+    if six.PY2:
+        return manifest % vars()
+    else:
+        return manifest.decode('utf-8') % vars()
+
+
+def rmtree(path, ignore_errors=False, onerror=auto_chmod):
+    return shutil.rmtree(path, ignore_errors, onerror)
+
+
+def current_umask():
+    tmp = os.umask(0o022)
+    os.umask(tmp)
+    return tmp
+
+
+def bootstrap():
+    # This function is called when setuptools*.egg is run using /bin/sh
+    import setuptools
+
+    argv0 = os.path.dirname(setuptools.__path__[0])
+    sys.argv[0] = argv0
+    sys.argv.append(argv0)
+    main()
+
+
+def main(argv=None, **kw):
+    from setuptools import setup
+    from setuptools.dist import Distribution
+
+    class DistributionWithoutHelpCommands(Distribution):
+        common_usage = ""
+
+        def _show_help(self, *args, **kw):
+            with _patch_usage():
+                Distribution._show_help(self, *args, **kw)
+
+    if argv is None:
+        argv = sys.argv[1:]
+
+    with _patch_usage():
+        setup(
+            script_args=['-q', 'easy_install', '-v'] + argv,
+            script_name=sys.argv[0] or 'easy_install',
+            distclass=DistributionWithoutHelpCommands,
+            **kw
+        )
+
+
+@contextlib.contextmanager
+def _patch_usage():
+    import distutils.core
+    USAGE = textwrap.dedent("""
+        usage: %(script)s [options] requirement_or_url ...
+           or: %(script)s --help
+        """).lstrip()
+
+    def gen_usage(script_name):
+        return USAGE % dict(
+            script=os.path.basename(script_name),
+        )
+
+    saved = distutils.core.gen_usage
+    distutils.core.gen_usage = gen_usage
+    try:
+        yield
+    finally:
+        distutils.core.gen_usage = saved
diff --git a/vendor/setuptools-39.0.1/setuptools/command/egg_info.py b/vendor/setuptools-39.0.1/setuptools/command/egg_info.py
new file mode 100755
index 00000000..f3e604d3
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/egg_info.py
@@ -0,0 +1,696 @@
+"""setuptools.command.egg_info
+
+Create a distribution's .egg-info directory and contents"""
+
+from distutils.filelist import FileList as _FileList
+from distutils.errors import DistutilsInternalError
+from distutils.util import convert_path
+from distutils import log
+import distutils.errors
+import distutils.filelist
+import os
+import re
+import sys
+import io
+import warnings
+import time
+import collections
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import map
+
+from setuptools import Command
+from setuptools.command.sdist import sdist
+from setuptools.command.sdist import walk_revctrl
+from setuptools.command.setopt import edit_config
+from setuptools.command import bdist_egg
+from pkg_resources import (
+    parse_requirements, safe_name, parse_version,
+    safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename)
+import setuptools.unicode_utils as unicode_utils
+from setuptools.glob import glob
+
+from setuptools.extern import packaging
+
+
+def translate_pattern(glob):
+    """
+    Translate a file path glob like '*.txt' in to a regular expression.
+    This differs from fnmatch.translate which allows wildcards to match
+    directory separators. It also knows about '**/' which matches any number of
+    directories.
+    """
+    pat = ''
+
+    # This will split on '/' within [character classes]. This is deliberate.
+    chunks = glob.split(os.path.sep)
+
+    sep = re.escape(os.sep)
+    valid_char = '[^%s]' % (sep,)
+
+    for c, chunk in enumerate(chunks):
+        last_chunk = c == len(chunks) - 1
+
+        # Chunks that are a literal ** are globstars. They match anything.
+        if chunk == '**':
+            if last_chunk:
+                # Match anything if this is the last component
+                pat += '.*'
+            else:
+                # Match '(name/)*'
+                pat += '(?:%s+%s)*' % (valid_char, sep)
+            continue  # Break here as the whole path component has been handled
+
+        # Find any special characters in the remainder
+        i = 0
+        chunk_len = len(chunk)
+        while i < chunk_len:
+            char = chunk[i]
+            if char == '*':
+                # Match any number of name characters
+                pat += valid_char + '*'
+            elif char == '?':
+                # Match a name character
+                pat += valid_char
+            elif char == '[':
+                # Character class
+                inner_i = i + 1
+                # Skip initial !/] chars
+                if inner_i < chunk_len and chunk[inner_i] == '!':
+                    inner_i = inner_i + 1
+                if inner_i < chunk_len and chunk[inner_i] == ']':
+                    inner_i = inner_i + 1
+
+                # Loop till the closing ] is found
+                while inner_i < chunk_len and chunk[inner_i] != ']':
+                    inner_i = inner_i + 1
+
+                if inner_i >= chunk_len:
+                    # Got to the end of the string without finding a closing ]
+                    # Do not treat this as a matching group, but as a literal [
+                    pat += re.escape(char)
+                else:
+                    # Grab the insides of the [brackets]
+                    inner = chunk[i + 1:inner_i]
+                    char_class = ''
+
+                    # Class negation
+                    if inner[0] == '!':
+                        char_class = '^'
+                        inner = inner[1:]
+
+                    char_class += re.escape(inner)
+                    pat += '[%s]' % (char_class,)
+
+                    # Skip to the end ]
+                    i = inner_i
+            else:
+                pat += re.escape(char)
+            i += 1
+
+        # Join each chunk with the dir separator
+        if not last_chunk:
+            pat += sep
+
+    pat += r'\Z'
+    return re.compile(pat, flags=re.MULTILINE|re.DOTALL)
+
+
+class egg_info(Command):
+    description = "create a distribution's .egg-info directory"
+
+    user_options = [
+        ('egg-base=', 'e', "directory containing .egg-info directories"
+                           " (default: top of the source tree)"),
+        ('tag-date', 'd', "Add date stamp (e.g. 20050528) to version number"),
+        ('tag-build=', 'b', "Specify explicit tag to add to version number"),
+        ('no-date', 'D', "Don't include date stamp [default]"),
+    ]
+
+    boolean_options = ['tag-date']
+    negative_opt = {
+        'no-date': 'tag-date',
+    }
+
+    def initialize_options(self):
+        self.egg_name = None
+        self.egg_version = None
+        self.egg_base = None
+        self.egg_info = None
+        self.tag_build = None
+        self.tag_date = 0
+        self.broken_egg_info = False
+        self.vtags = None
+
+    ####################################
+    # allow the 'tag_svn_revision' to be detected and
+    # set, supporting sdists built on older Setuptools.
+    @property
+    def tag_svn_revision(self):
+        pass
+
+    @tag_svn_revision.setter
+    def tag_svn_revision(self, value):
+        pass
+    ####################################
+
+    def save_version_info(self, filename):
+        """
+        Materialize the value of date into the
+        build tag. Install build keys in a deterministic order
+        to avoid arbitrary reordering on subsequent builds.
+        """
+        egg_info = collections.OrderedDict()
+        # follow the order these keys would have been added
+        # when PYTHONHASHSEED=0
+        egg_info['tag_build'] = self.tags()
+        egg_info['tag_date'] = 0
+        edit_config(filename, dict(egg_info=egg_info))
+
+    def finalize_options(self):
+        self.egg_name = safe_name(self.distribution.get_name())
+        self.vtags = self.tags()
+        self.egg_version = self.tagged_version()
+
+        parsed_version = parse_version(self.egg_version)
+
+        try:
+            is_version = isinstance(parsed_version, packaging.version.Version)
+            spec = (
+                "%s==%s" if is_version else "%s===%s"
+            )
+            list(
+                parse_requirements(spec % (self.egg_name, self.egg_version))
+            )
+        except ValueError:
+            raise distutils.errors.DistutilsOptionError(
+                "Invalid distribution name or version syntax: %s-%s" %
+                (self.egg_name, self.egg_version)
+            )
+
+        if self.egg_base is None:
+            dirs = self.distribution.package_dir
+            self.egg_base = (dirs or {}).get('', os.curdir)
+
+        self.ensure_dirname('egg_base')
+        self.egg_info = to_filename(self.egg_name) + '.egg-info'
+        if self.egg_base != os.curdir:
+            self.egg_info = os.path.join(self.egg_base, self.egg_info)
+        if '-' in self.egg_name:
+            self.check_broken_egg_info()
+
+        # Set package version for the benefit of dumber commands
+        # (e.g. sdist, bdist_wininst, etc.)
+        #
+        self.distribution.metadata.version = self.egg_version
+
+        # If we bootstrapped around the lack of a PKG-INFO, as might be the
+        # case in a fresh checkout, make sure that any special tags get added
+        # to the version info
+        #
+        pd = self.distribution._patched_dist
+        if pd is not None and pd.key == self.egg_name.lower():
+            pd._version = self.egg_version
+            pd._parsed_version = parse_version(self.egg_version)
+            self.distribution._patched_dist = None
+
+    def write_or_delete_file(self, what, filename, data, force=False):
+        """Write `data` to `filename` or delete if empty
+
+        If `data` is non-empty, this routine is the same as ``write_file()``.
+        If `data` is empty but not ``None``, this is the same as calling
+        ``delete_file(filename)`.  If `data` is ``None``, then this is a no-op
+        unless `filename` exists, in which case a warning is issued about the
+        orphaned file (if `force` is false), or deleted (if `force` is true).
+        """
+        if data:
+            self.write_file(what, filename, data)
+        elif os.path.exists(filename):
+            if data is None and not force:
+                log.warn(
+                    "%s not set in setup(), but %s exists", what, filename
+                )
+                return
+            else:
+                self.delete_file(filename)
+
+    def write_file(self, what, filename, data):
+        """Write `data` to `filename` (if not a dry run) after announcing it
+
+        `what` is used in a log message to identify what is being written
+        to the file.
+        """
+        log.info("writing %s to %s", what, filename)
+        if six.PY3:
+            data = data.encode("utf-8")
+        if not self.dry_run:
+            f = open(filename, 'wb')
+            f.write(data)
+            f.close()
+
+    def delete_file(self, filename):
+        """Delete `filename` (if not a dry run) after announcing it"""
+        log.info("deleting %s", filename)
+        if not self.dry_run:
+            os.unlink(filename)
+
+    def tagged_version(self):
+        version = self.distribution.get_version()
+        # egg_info may be called more than once for a distribution,
+        # in which case the version string already contains all tags.
+        if self.vtags and version.endswith(self.vtags):
+            return safe_version(version)
+        return safe_version(version + self.vtags)
+
+    def run(self):
+        self.mkpath(self.egg_info)
+        installer = self.distribution.fetch_build_egg
+        for ep in iter_entry_points('egg_info.writers'):
+            ep.require(installer=installer)
+            writer = ep.resolve()
+            writer(self, ep.name, os.path.join(self.egg_info, ep.name))
+
+        # Get rid of native_libs.txt if it was put there by older bdist_egg
+        nl = os.path.join(self.egg_info, "native_libs.txt")
+        if os.path.exists(nl):
+            self.delete_file(nl)
+
+        self.find_sources()
+
+    def tags(self):
+        version = ''
+        if self.tag_build:
+            version += self.tag_build
+        if self.tag_date:
+            version += time.strftime("-%Y%m%d")
+        return version
+
+    def find_sources(self):
+        """Generate SOURCES.txt manifest file"""
+        manifest_filename = os.path.join(self.egg_info, "SOURCES.txt")
+        mm = manifest_maker(self.distribution)
+        mm.manifest = manifest_filename
+        mm.run()
+        self.filelist = mm.filelist
+
+    def check_broken_egg_info(self):
+        bei = self.egg_name + '.egg-info'
+        if self.egg_base != os.curdir:
+            bei = os.path.join(self.egg_base, bei)
+        if os.path.exists(bei):
+            log.warn(
+                "-" * 78 + '\n'
+                "Note: Your current .egg-info directory has a '-' in its name;"
+                '\nthis will not work correctly with "setup.py develop".\n\n'
+                'Please rename %s to %s to correct this problem.\n' + '-' * 78,
+                bei, self.egg_info
+            )
+            self.broken_egg_info = self.egg_info
+            self.egg_info = bei  # make it work for now
+
+
+class FileList(_FileList):
+    # Implementations of the various MANIFEST.in commands
+
+    def process_template_line(self, line):
+        # Parse the line: split it up, make sure the right number of words
+        # is there, and return the relevant words.  'action' is always
+        # defined: it's the first word of the line.  Which of the other
+        # three are defined depends on the action; it'll be either
+        # patterns, (dir and patterns), or (dir_pattern).
+        (action, patterns, dir, dir_pattern) = self._parse_template_line(line)
+
+        # OK, now we know that the action is valid and we have the
+        # right number of words on the line for that action -- so we
+        # can proceed with minimal error-checking.
+        if action == 'include':
+            self.debug_print("include " + ' '.join(patterns))
+            for pattern in patterns:
+                if not self.include(pattern):
+                    log.warn("warning: no files found matching '%s'", pattern)
+
+        elif action == 'exclude':
+            self.debug_print("exclude " + ' '.join(patterns))
+            for pattern in patterns:
+                if not self.exclude(pattern):
+                    log.warn(("warning: no previously-included files "
+                              "found matching '%s'"), pattern)
+
+        elif action == 'global-include':
+            self.debug_print("global-include " + ' '.join(patterns))
+            for pattern in patterns:
+                if not self.global_include(pattern):
+                    log.warn(("warning: no files found matching '%s' "
+                              "anywhere in distribution"), pattern)
+
+        elif action == 'global-exclude':
+            self.debug_print("global-exclude " + ' '.join(patterns))
+            for pattern in patterns:
+                if not self.global_exclude(pattern):
+                    log.warn(("warning: no previously-included files matching "
+                              "'%s' found anywhere in distribution"),
+                             pattern)
+
+        elif action == 'recursive-include':
+            self.debug_print("recursive-include %s %s" %
+                             (dir, ' '.join(patterns)))
+            for pattern in patterns:
+                if not self.recursive_include(dir, pattern):
+                    log.warn(("warning: no files found matching '%s' "
+                              "under directory '%s'"),
+                             pattern, dir)
+
+        elif action == 'recursive-exclude':
+            self.debug_print("recursive-exclude %s %s" %
+                             (dir, ' '.join(patterns)))
+            for pattern in patterns:
+                if not self.recursive_exclude(dir, pattern):
+                    log.warn(("warning: no previously-included files matching "
+                              "'%s' found under directory '%s'"),
+                             pattern, dir)
+
+        elif action == 'graft':
+            self.debug_print("graft " + dir_pattern)
+            if not self.graft(dir_pattern):
+                log.warn("warning: no directories found matching '%s'",
+                         dir_pattern)
+
+        elif action == 'prune':
+            self.debug_print("prune " + dir_pattern)
+            if not self.prune(dir_pattern):
+                log.warn(("no previously-included directories found "
+                          "matching '%s'"), dir_pattern)
+
+        else:
+            raise DistutilsInternalError(
+                "this cannot happen: invalid action '%s'" % action)
+
+    def _remove_files(self, predicate):
+        """
+        Remove all files from the file list that match the predicate.
+        Return True if any matching files were removed
+        """
+        found = False
+        for i in range(len(self.files) - 1, -1, -1):
+            if predicate(self.files[i]):
+                self.debug_print(" removing " + self.files[i])
+                del self.files[i]
+                found = True
+        return found
+
+    def include(self, pattern):
+        """Include files that match 'pattern'."""
+        found = [f for f in glob(pattern) if not os.path.isdir(f)]
+        self.extend(found)
+        return bool(found)
+
+    def exclude(self, pattern):
+        """Exclude files that match 'pattern'."""
+        match = translate_pattern(pattern)
+        return self._remove_files(match.match)
+
+    def recursive_include(self, dir, pattern):
+        """
+        Include all files anywhere in 'dir/' that match the pattern.
+        """
+        full_pattern = os.path.join(dir, '**', pattern)
+        found = [f for f in glob(full_pattern, recursive=True)
+                 if not os.path.isdir(f)]
+        self.extend(found)
+        return bool(found)
+
+    def recursive_exclude(self, dir, pattern):
+        """
+        Exclude any file anywhere in 'dir/' that match the pattern.
+        """
+        match = translate_pattern(os.path.join(dir, '**', pattern))
+        return self._remove_files(match.match)
+
+    def graft(self, dir):
+        """Include all files from 'dir/'."""
+        found = [
+            item
+            for match_dir in glob(dir)
+            for item in distutils.filelist.findall(match_dir)
+        ]
+        self.extend(found)
+        return bool(found)
+
+    def prune(self, dir):
+        """Filter out files from 'dir/'."""
+        match = translate_pattern(os.path.join(dir, '**'))
+        return self._remove_files(match.match)
+
+    def global_include(self, pattern):
+        """
+        Include all files anywhere in the current directory that match the
+        pattern. This is very inefficient on large file trees.
+        """
+        if self.allfiles is None:
+            self.findall()
+        match = translate_pattern(os.path.join('**', pattern))
+        found = [f for f in self.allfiles if match.match(f)]
+        self.extend(found)
+        return bool(found)
+
+    def global_exclude(self, pattern):
+        """
+        Exclude all files anywhere that match the pattern.
+        """
+        match = translate_pattern(os.path.join('**', pattern))
+        return self._remove_files(match.match)
+
+    def append(self, item):
+        if item.endswith('\r'):  # Fix older sdists built on Windows
+            item = item[:-1]
+        path = convert_path(item)
+
+        if self._safe_path(path):
+            self.files.append(path)
+
+    def extend(self, paths):
+        self.files.extend(filter(self._safe_path, paths))
+
+    def _repair(self):
+        """
+        Replace self.files with only safe paths
+
+        Because some owners of FileList manipulate the underlying
+        ``files`` attribute directly, this method must be called to
+        repair those paths.
+        """
+        self.files = list(filter(self._safe_path, self.files))
+
+    def _safe_path(self, path):
+        enc_warn = "'%s' not %s encodable -- skipping"
+
+        # To avoid accidental trans-codings errors, first to unicode
+        u_path = unicode_utils.filesys_decode(path)
+        if u_path is None:
+            log.warn("'%s' in unexpected encoding -- skipping" % path)
+            return False
+
+        # Must ensure utf-8 encodability
+        utf8_path = unicode_utils.try_encode(u_path, "utf-8")
+        if utf8_path is None:
+            log.warn(enc_warn, path, 'utf-8')
+            return False
+
+        try:
+            # accept is either way checks out
+            if os.path.exists(u_path) or os.path.exists(utf8_path):
+                return True
+        # this will catch any encode errors decoding u_path
+        except UnicodeEncodeError:
+            log.warn(enc_warn, path, sys.getfilesystemencoding())
+
+
+class manifest_maker(sdist):
+    template = "MANIFEST.in"
+
+    def initialize_options(self):
+        self.use_defaults = 1
+        self.prune = 1
+        self.manifest_only = 1
+        self.force_manifest = 1
+
+    def finalize_options(self):
+        pass
+
+    def run(self):
+        self.filelist = FileList()
+        if not os.path.exists(self.manifest):
+            self.write_manifest()  # it must exist so it'll get in the list
+        self.add_defaults()
+        if os.path.exists(self.template):
+            self.read_template()
+        self.prune_file_list()
+        self.filelist.sort()
+        self.filelist.remove_duplicates()
+        self.write_manifest()
+
+    def _manifest_normalize(self, path):
+        path = unicode_utils.filesys_decode(path)
+        return path.replace(os.sep, '/')
+
+    def write_manifest(self):
+        """
+        Write the file list in 'self.filelist' to the manifest file
+        named by 'self.manifest'.
+        """
+        self.filelist._repair()
+
+        # Now _repairs should encodability, but not unicode
+        files = [self._manifest_normalize(f) for f in self.filelist.files]
+        msg = "writing manifest file '%s'" % self.manifest
+        self.execute(write_file, (self.manifest, files), msg)
+
+    def warn(self, msg):
+        if not self._should_suppress_warning(msg):
+            sdist.warn(self, msg)
+
+    @staticmethod
+    def _should_suppress_warning(msg):
+        """
+        suppress missing-file warnings from sdist
+        """
+        return re.match(r"standard file .*not found", msg)
+
+    def add_defaults(self):
+        sdist.add_defaults(self)
+        self.filelist.append(self.template)
+        self.filelist.append(self.manifest)
+        rcfiles = list(walk_revctrl())
+        if rcfiles:
+            self.filelist.extend(rcfiles)
+        elif os.path.exists(self.manifest):
+            self.read_manifest()
+        ei_cmd = self.get_finalized_command('egg_info')
+        self.filelist.graft(ei_cmd.egg_info)
+
+    def prune_file_list(self):
+        build = self.get_finalized_command('build')
+        base_dir = self.distribution.get_fullname()
+        self.filelist.prune(build.build_base)
+        self.filelist.prune(base_dir)
+        sep = re.escape(os.sep)
+        self.filelist.exclude_pattern(r'(^|' + sep + r')(RCS|CVS|\.svn)' + sep,
+                                      is_regex=1)
+
+
+def write_file(filename, contents):
+    """Create a file with the specified name and write 'contents' (a
+    sequence of strings without line terminators) to it.
+    """
+    contents = "\n".join(contents)
+
+    # assuming the contents has been vetted for utf-8 encoding
+    contents = contents.encode("utf-8")
+
+    with open(filename, "wb") as f:  # always write POSIX-style manifest
+        f.write(contents)
+
+
+def write_pkg_info(cmd, basename, filename):
+    log.info("writing %s", filename)
+    if not cmd.dry_run:
+        metadata = cmd.distribution.metadata
+        metadata.version, oldver = cmd.egg_version, metadata.version
+        metadata.name, oldname = cmd.egg_name, metadata.name
+
+        try:
+            # write unescaped data to PKG-INFO, so older pkg_resources
+            # can still parse it
+            metadata.write_pkg_info(cmd.egg_info)
+        finally:
+            metadata.name, metadata.version = oldname, oldver
+
+        safe = getattr(cmd.distribution, 'zip_safe', None)
+
+        bdist_egg.write_safety_flag(cmd.egg_info, safe)
+
+
+def warn_depends_obsolete(cmd, basename, filename):
+    if os.path.exists(filename):
+        log.warn(
+            "WARNING: 'depends.txt' is not used by setuptools 0.6!\n"
+            "Use the install_requires/extras_require setup() args instead."
+        )
+
+
+def _write_requirements(stream, reqs):
+    lines = yield_lines(reqs or ())
+    append_cr = lambda line: line + '\n'
+    lines = map(append_cr, lines)
+    stream.writelines(lines)
+
+
+def write_requirements(cmd, basename, filename):
+    dist = cmd.distribution
+    data = six.StringIO()
+    _write_requirements(data, dist.install_requires)
+    extras_require = dist.extras_require or {}
+    for extra in sorted(extras_require):
+        data.write('\n[{extra}]\n'.format(**vars()))
+        _write_requirements(data, extras_require[extra])
+    cmd.write_or_delete_file("requirements", filename, data.getvalue())
+
+
+def write_setup_requirements(cmd, basename, filename):
+    data = io.StringIO()
+    _write_requirements(data, cmd.distribution.setup_requires)
+    cmd.write_or_delete_file("setup-requirements", filename, data.getvalue())
+
+
+def write_toplevel_names(cmd, basename, filename):
+    pkgs = dict.fromkeys(
+        [
+            k.split('.', 1)[0]
+            for k in cmd.distribution.iter_distribution_names()
+        ]
+    )
+    cmd.write_file("top-level names", filename, '\n'.join(sorted(pkgs)) + '\n')
+
+
+def overwrite_arg(cmd, basename, filename):
+    write_arg(cmd, basename, filename, True)
+
+
+def write_arg(cmd, basename, filename, force=False):
+    argname = os.path.splitext(basename)[0]
+    value = getattr(cmd.distribution, argname, None)
+    if value is not None:
+        value = '\n'.join(value) + '\n'
+    cmd.write_or_delete_file(argname, filename, value, force)
+
+
+def write_entries(cmd, basename, filename):
+    ep = cmd.distribution.entry_points
+
+    if isinstance(ep, six.string_types) or ep is None:
+        data = ep
+    elif ep is not None:
+        data = []
+        for section, contents in sorted(ep.items()):
+            if not isinstance(contents, six.string_types):
+                contents = EntryPoint.parse_group(section, contents)
+                contents = '\n'.join(sorted(map(str, contents.values())))
+            data.append('[%s]\n%s\n\n' % (section, contents))
+        data = ''.join(data)
+
+    cmd.write_or_delete_file('entry points', filename, data, True)
+
+
+def get_pkg_info_revision():
+    """
+    Get a -r### off of PKG-INFO Version in case this is an sdist of
+    a subversion revision.
+    """
+    warnings.warn("get_pkg_info_revision is deprecated.", DeprecationWarning)
+    if os.path.exists('PKG-INFO'):
+        with io.open('PKG-INFO') as f:
+            for line in f:
+                match = re.match(r"Version:.*-r(\d+)\s*$", line)
+                if match:
+                    return int(match.group(1))
+    return 0
diff --git a/vendor/setuptools-39.0.1/setuptools/command/install.py b/vendor/setuptools-39.0.1/setuptools/command/install.py
new file mode 100644
index 00000000..31a5ddb5
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/install.py
@@ -0,0 +1,125 @@
+from distutils.errors import DistutilsArgError
+import inspect
+import glob
+import warnings
+import platform
+import distutils.command.install as orig
+
+import setuptools
+
+# Prior to numpy 1.9, NumPy relies on the '_install' name, so provide it for
+# now. See https://github.com/pypa/setuptools/issues/199/
+_install = orig.install
+
+
+class install(orig.install):
+    """Use easy_install to install the package, w/dependencies"""
+
+    user_options = orig.install.user_options + [
+        ('old-and-unmanageable', None, "Try not to use this!"),
+        ('single-version-externally-managed', None,
+         "used by system package builders to create 'flat' eggs"),
+    ]
+    boolean_options = orig.install.boolean_options + [
+        'old-and-unmanageable', 'single-version-externally-managed',
+    ]
+    new_commands = [
+        ('install_egg_info', lambda self: True),
+        ('install_scripts', lambda self: True),
+    ]
+    _nc = dict(new_commands)
+
+    def initialize_options(self):
+        orig.install.initialize_options(self)
+        self.old_and_unmanageable = None
+        self.single_version_externally_managed = None
+
+    def finalize_options(self):
+        orig.install.finalize_options(self)
+        if self.root:
+            self.single_version_externally_managed = True
+        elif self.single_version_externally_managed:
+            if not self.root and not self.record:
+                raise DistutilsArgError(
+                    "You must specify --record or --root when building system"
+                    " packages"
+                )
+
+    def handle_extra_path(self):
+        if self.root or self.single_version_externally_managed:
+            # explicit backward-compatibility mode, allow extra_path to work
+            return orig.install.handle_extra_path(self)
+
+        # Ignore extra_path when installing an egg (or being run by another
+        # command without --root or --single-version-externally-managed
+        self.path_file = None
+        self.extra_dirs = ''
+
+    def run(self):
+        # Explicit request for old-style install?  Just do it
+        if self.old_and_unmanageable or self.single_version_externally_managed:
+            return orig.install.run(self)
+
+        if not self._called_from_setup(inspect.currentframe()):
+            # Run in backward-compatibility mode to support bdist_* commands.
+            orig.install.run(self)
+        else:
+            self.do_egg_install()
+
+    @staticmethod
+    def _called_from_setup(run_frame):
+        """
+        Attempt to detect whether run() was called from setup() or by another
+        command.  If called by setup(), the parent caller will be the
+        'run_command' method in 'distutils.dist', and *its* caller will be
+        the 'run_commands' method.  If called any other way, the
+        immediate caller *might* be 'run_command', but it won't have been
+        called by 'run_commands'. Return True in that case or if a call stack
+        is unavailable. Return False otherwise.
+        """
+        if run_frame is None:
+            msg = "Call stack not available. bdist_* commands may fail."
+            warnings.warn(msg)
+            if platform.python_implementation() == 'IronPython':
+                msg = "For best results, pass -X:Frames to enable call stack."
+                warnings.warn(msg)
+            return True
+        res = inspect.getouterframes(run_frame)[2]
+        caller, = res[:1]
+        info = inspect.getframeinfo(caller)
+        caller_module = caller.f_globals.get('__name__', '')
+        return (
+            caller_module == 'distutils.dist'
+            and info.function == 'run_commands'
+        )
+
+    def do_egg_install(self):
+
+        easy_install = self.distribution.get_command_class('easy_install')
+
+        cmd = easy_install(
+            self.distribution, args="x", root=self.root, record=self.record,
+        )
+        cmd.ensure_finalized()  # finalize before bdist_egg munges install cmd
+        cmd.always_copy_from = '.'  # make sure local-dir eggs get installed
+
+        # pick up setup-dir .egg files only: no .egg-info
+        cmd.package_index.scan(glob.glob('*.egg'))
+
+        self.run_command('bdist_egg')
+        args = [self.distribution.get_command_obj('bdist_egg').egg_output]
+
+        if setuptools.bootstrap_install_from:
+            # Bootstrap self-installation of setuptools
+            args.insert(0, setuptools.bootstrap_install_from)
+
+        cmd.args = args
+        cmd.run()
+        setuptools.bootstrap_install_from = None
+
+
+# XXX Python 3.1 doesn't see _nc if this is inside the class
+install.sub_commands = (
+    [cmd for cmd in orig.install.sub_commands if cmd[0] not in install._nc] +
+    install.new_commands
+)
diff --git a/vendor/setuptools-39.0.1/setuptools/command/install_egg_info.py b/vendor/setuptools-39.0.1/setuptools/command/install_egg_info.py
new file mode 100755
index 00000000..edc4718b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/install_egg_info.py
@@ -0,0 +1,62 @@
+from distutils import log, dir_util
+import os
+
+from setuptools import Command
+from setuptools import namespaces
+from setuptools.archive_util import unpack_archive
+import pkg_resources
+
+
+class install_egg_info(namespaces.Installer, Command):
+    """Install an .egg-info directory for the package"""
+
+    description = "Install an .egg-info directory for the package"
+
+    user_options = [
+        ('install-dir=', 'd', "directory to install to"),
+    ]
+
+    def initialize_options(self):
+        self.install_dir = None
+
+    def finalize_options(self):
+        self.set_undefined_options('install_lib',
+                                   ('install_dir', 'install_dir'))
+        ei_cmd = self.get_finalized_command("egg_info")
+        basename = pkg_resources.Distribution(
+            None, None, ei_cmd.egg_name, ei_cmd.egg_version
+        ).egg_name() + '.egg-info'
+        self.source = ei_cmd.egg_info
+        self.target = os.path.join(self.install_dir, basename)
+        self.outputs = []
+
+    def run(self):
+        self.run_command('egg_info')
+        if os.path.isdir(self.target) and not os.path.islink(self.target):
+            dir_util.remove_tree(self.target, dry_run=self.dry_run)
+        elif os.path.exists(self.target):
+            self.execute(os.unlink, (self.target,), "Removing " + self.target)
+        if not self.dry_run:
+            pkg_resources.ensure_directory(self.target)
+        self.execute(
+            self.copytree, (), "Copying %s to %s" % (self.source, self.target)
+        )
+        self.install_namespaces()
+
+    def get_outputs(self):
+        return self.outputs
+
+    def copytree(self):
+        # Copy the .egg-info tree to site-packages
+        def skimmer(src, dst):
+            # filter out source-control directories; note that 'src' is always
+            # a '/'-separated path, regardless of platform.  'dst' is a
+            # platform-specific path.
+            for skip in '.svn/', 'CVS/':
+                if src.startswith(skip) or '/' + skip in src:
+                    return None
+            self.outputs.append(dst)
+            log.debug("Copying %s to %s", src, dst)
+            return dst
+
+        unpack_archive(self.source, self.target, skimmer)
diff --git a/vendor/setuptools-39.0.1/setuptools/command/install_lib.py b/vendor/setuptools-39.0.1/setuptools/command/install_lib.py
new file mode 100644
index 00000000..2b31c3e3
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/install_lib.py
@@ -0,0 +1,121 @@
+import os
+import imp
+from itertools import product, starmap
+import distutils.command.install_lib as orig
+
+
+class install_lib(orig.install_lib):
+    """Don't add compiled flags to filenames of non-Python files"""
+
+    def run(self):
+        self.build()
+        outfiles = self.install()
+        if outfiles is not None:
+            # always compile, in case we have any extension stubs to deal with
+            self.byte_compile(outfiles)
+
+    def get_exclusions(self):
+        """
+        Return a collections.Sized collections.Container of paths to be
+        excluded for single_version_externally_managed installations.
+        """
+        all_packages = (
+            pkg
+            for ns_pkg in self._get_SVEM_NSPs()
+            for pkg in self._all_packages(ns_pkg)
+        )
+
+        excl_specs = product(all_packages, self._gen_exclusion_paths())
+        return set(starmap(self._exclude_pkg_path, excl_specs))
+
+    def _exclude_pkg_path(self, pkg, exclusion_path):
+        """
+        Given a package name and exclusion path within that package,
+        compute the full exclusion path.
+        """
+        parts = pkg.split('.') + [exclusion_path]
+        return os.path.join(self.install_dir, *parts)
+
+    @staticmethod
+    def _all_packages(pkg_name):
+        """
+        >>> list(install_lib._all_packages('foo.bar.baz'))
+        ['foo.bar.baz', 'foo.bar', 'foo']
+        """
+        while pkg_name:
+            yield pkg_name
+            pkg_name, sep, child = pkg_name.rpartition('.')
+
+    def _get_SVEM_NSPs(self):
+        """
+        Get namespace packages (list) but only for
+        single_version_externally_managed installations and empty otherwise.
+        """
+        # TODO: is it necessary to short-circuit here? i.e. what's the cost
+        # if get_finalized_command is called even when namespace_packages is
+        # False?
+        if not self.distribution.namespace_packages:
+            return []
+
+        install_cmd = self.get_finalized_command('install')
+        svem = install_cmd.single_version_externally_managed
+
+        return self.distribution.namespace_packages if svem else []
+
+    @staticmethod
+    def _gen_exclusion_paths():
+        """
+        Generate file paths to be excluded for namespace packages (bytecode
+        cache files).
+        """
+        # always exclude the package module itself
+        yield '__init__.py'
+
+        yield '__init__.pyc'
+        yield '__init__.pyo'
+
+        if not hasattr(imp, 'get_tag'):
+            return
+
+        base = os.path.join('__pycache__', '__init__.' + imp.get_tag())
+        yield base + '.pyc'
+        yield base + '.pyo'
+        yield base + '.opt-1.pyc'
+        yield base + '.opt-2.pyc'
+
+    def copy_tree(
+            self, infile, outfile,
+            preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1
+    ):
+        assert preserve_mode and preserve_times and not preserve_symlinks
+        exclude = self.get_exclusions()
+
+        if not exclude:
+            return orig.install_lib.copy_tree(self, infile, outfile)
+
+        # Exclude namespace package __init__.py* files from the output
+
+        from setuptools.archive_util import unpack_directory
+        from distutils import log
+
+        outfiles = []
+
+        def pf(src, dst):
+            if dst in exclude:
+                log.warn("Skipping installation of %s (namespace package)",
+                         dst)
+                return False
+
+            log.info("copying %s -> %s", src, os.path.dirname(dst))
+            outfiles.append(dst)
+            return dst
+
+        unpack_directory(infile, outfile, pf)
+        return outfiles
+
+    def get_outputs(self):
+        outputs = orig.install_lib.get_outputs(self)
+        exclude = self.get_exclusions()
+        if exclude:
+            return [f for f in outputs if f not in exclude]
+        return outputs
diff --git a/vendor/setuptools-39.0.1/setuptools/command/install_scripts.py b/vendor/setuptools-39.0.1/setuptools/command/install_scripts.py
new file mode 100755
index 00000000..16234273
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/install_scripts.py
@@ -0,0 +1,65 @@
+from distutils import log
+import distutils.command.install_scripts as orig
+import os
+import sys
+
+from pkg_resources import Distribution, PathMetadata, ensure_directory
+
+
+class install_scripts(orig.install_scripts):
+    """Do normal script install, plus any egg_info wrapper scripts"""
+
+    def initialize_options(self):
+        orig.install_scripts.initialize_options(self)
+        self.no_ep = False
+
+    def run(self):
+        import setuptools.command.easy_install as ei
+
+        self.run_command("egg_info")
+        if self.distribution.scripts:
+            orig.install_scripts.run(self)  # run first to set up self.outfiles
+        else:
+            self.outfiles = []
+        if self.no_ep:
+            # don't install entry point scripts into .egg file!
+            return
+
+        ei_cmd = self.get_finalized_command("egg_info")
+        dist = Distribution(
+            ei_cmd.egg_base, PathMetadata(ei_cmd.egg_base, ei_cmd.egg_info),
+            ei_cmd.egg_name, ei_cmd.egg_version,
+        )
+        bs_cmd = self.get_finalized_command('build_scripts')
+        exec_param = getattr(bs_cmd, 'executable', None)
+        bw_cmd = self.get_finalized_command("bdist_wininst")
+        is_wininst = getattr(bw_cmd, '_is_running', False)
+        writer = ei.ScriptWriter
+        if is_wininst:
+            exec_param = "python.exe"
+            writer = ei.WindowsScriptWriter
+        if exec_param == sys.executable:
+            # In case the path to the Python executable contains a space, wrap
+            # it so it's not split up.
+            exec_param = [exec_param]
+        # resolve the writer to the environment
+        writer = writer.best()
+        cmd = writer.command_spec_class.best().from_param(exec_param)
+        for args in writer.get_args(dist, cmd.as_header()):
+            self.write_script(*args)
+
+    def write_script(self, script_name, contents, mode="t", *ignored):
+        """Write an executable file to the scripts directory"""
+        from setuptools.command.easy_install import chmod, current_umask
+
+        log.info("Installing %s script to %s", script_name, self.install_dir)
+        target = os.path.join(self.install_dir, script_name)
+        self.outfiles.append(target)
+
+        mask = current_umask()
+        if not self.dry_run:
+            ensure_directory(target)
+            f = open(target, "w" + mode)
+            f.write(contents)
+            f.close()
+            chmod(target, 0o777 - mask)
diff --git a/vendor/setuptools-39.0.1/setuptools/command/launcher manifest.xml b/vendor/setuptools-39.0.1/setuptools/command/launcher manifest.xml
new file mode 100644
index 00000000..5972a96d
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/launcher manifest.xml	
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+    <assemblyIdentity version="1.0.0.0"
+                      processorArchitecture="X86"
+                      name="%(name)s"
+                      type="win32"/>
+    <!-- Identify the application security requirements. -->
+    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+        <security>
+            <requestedPrivileges>
+                <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+            </requestedPrivileges>
+        </security>
+    </trustInfo>
+</assembly>
diff --git a/vendor/setuptools-39.0.1/setuptools/command/py36compat.py b/vendor/setuptools-39.0.1/setuptools/command/py36compat.py
new file mode 100644
index 00000000..61063e75
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/py36compat.py
@@ -0,0 +1,136 @@
+import os
+from glob import glob
+from distutils.util import convert_path
+from distutils.command import sdist
+
+from setuptools.extern.six.moves import filter
+
+
+class sdist_add_defaults:
+    """
+    Mix-in providing forward-compatibility for functionality as found in
+    distutils on Python 3.7.
+
+    Do not edit the code in this class except to update functionality
+    as implemented in distutils. Instead, override in the subclass.
+    """
+
+    def add_defaults(self):
+        """Add all the default files to self.filelist:
+          - README or README.txt
+          - setup.py
+          - test/test*.py
+          - all pure Python modules mentioned in setup script
+          - all files pointed by package_data (build_py)
+          - all files defined in data_files.
+          - all files defined as scripts.
+          - all C sources listed as part of extensions or C libraries
+            in the setup script (doesn't catch C headers!)
+        Warns if (README or README.txt) or setup.py are missing; everything
+        else is optional.
+        """
+        self._add_defaults_standards()
+        self._add_defaults_optional()
+        self._add_defaults_python()
+        self._add_defaults_data_files()
+        self._add_defaults_ext()
+        self._add_defaults_c_libs()
+        self._add_defaults_scripts()
+
+    @staticmethod
+    def _cs_path_exists(fspath):
+        """
+        Case-sensitive path existence check
+
+        >>> sdist_add_defaults._cs_path_exists(__file__)
+        True
+        >>> sdist_add_defaults._cs_path_exists(__file__.upper())
+        False
+        """
+        if not os.path.exists(fspath):
+            return False
+        # make absolute so we always have a directory
+        abspath = os.path.abspath(fspath)
+        directory, filename = os.path.split(abspath)
+        return filename in os.listdir(directory)
+
+    def _add_defaults_standards(self):
+        standards = [self.READMES, self.distribution.script_name]
+        for fn in standards:
+            if isinstance(fn, tuple):
+                alts = fn
+                got_it = False
+                for fn in alts:
+                    if self._cs_path_exists(fn):
+                        got_it = True
+                        self.filelist.append(fn)
+                        break
+
+                if not got_it:
+                    self.warn("standard file not found: should have one of " +
+                              ', '.join(alts))
+            else:
+                if self._cs_path_exists(fn):
+                    self.filelist.append(fn)
+                else:
+                    self.warn("standard file '%s' not found" % fn)
+
+    def _add_defaults_optional(self):
+        optional = ['test/test*.py', 'setup.cfg']
+        for pattern in optional:
+            files = filter(os.path.isfile, glob(pattern))
+            self.filelist.extend(files)
+
+    def _add_defaults_python(self):
+        # build_py is used to get:
+        #  - python modules
+        #  - files defined in package_data
+        build_py = self.get_finalized_command('build_py')
+
+        # getting python files
+        if self.distribution.has_pure_modules():
+            self.filelist.extend(build_py.get_source_files())
+
+        # getting package_data files
+        # (computed in build_py.data_files by build_py.finalize_options)
+        for pkg, src_dir, build_dir, filenames in build_py.data_files:
+            for filename in filenames:
+                self.filelist.append(os.path.join(src_dir, filename))
+
+    def _add_defaults_data_files(self):
+        # getting distribution.data_files
+        if self.distribution.has_data_files():
+            for item in self.distribution.data_files:
+                if isinstance(item, str):
+                    # plain file
+                    item = convert_path(item)
+                    if os.path.isfile(item):
+                        self.filelist.append(item)
+                else:
+                    # a (dirname, filenames) tuple
+                    dirname, filenames = item
+                    for f in filenames:
+                        f = convert_path(f)
+                        if os.path.isfile(f):
+                            self.filelist.append(f)
+
+    def _add_defaults_ext(self):
+        if self.distribution.has_ext_modules():
+            build_ext = self.get_finalized_command('build_ext')
+            self.filelist.extend(build_ext.get_source_files())
+
+    def _add_defaults_c_libs(self):
+        if self.distribution.has_c_libraries():
+            build_clib = self.get_finalized_command('build_clib')
+            self.filelist.extend(build_clib.get_source_files())
+
+    def _add_defaults_scripts(self):
+        if self.distribution.has_scripts():
+            build_scripts = self.get_finalized_command('build_scripts')
+            self.filelist.extend(build_scripts.get_source_files())
+
+
+if hasattr(sdist.sdist, '_add_defaults_standards'):
+    # disable the functionality already available upstream
+    class sdist_add_defaults:
+        pass
diff --git a/vendor/setuptools-39.0.1/setuptools/command/register.py b/vendor/setuptools-39.0.1/setuptools/command/register.py
new file mode 100755
index 00000000..8d6336a1
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/register.py
@@ -0,0 +1,10 @@
+import distutils.command.register as orig
+
+
+class register(orig.register):
+    __doc__ = orig.register.__doc__
+
+    def run(self):
+        # Make sure that we are using valid current name/version info
+        self.run_command('egg_info')
+        orig.register.run(self)
diff --git a/vendor/setuptools-39.0.1/setuptools/command/rotate.py b/vendor/setuptools-39.0.1/setuptools/command/rotate.py
new file mode 100755
index 00000000..b89353f5
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/rotate.py
@@ -0,0 +1,66 @@
+from distutils.util import convert_path
+from distutils import log
+from distutils.errors import DistutilsOptionError
+import os
+import shutil
+
+from setuptools.extern import six
+
+from setuptools import Command
+
+
+class rotate(Command):
+    """Delete older distributions"""
+
+    description = "delete older distributions, keeping N newest files"
+    user_options = [
+        ('match=', 'm', "patterns to match (required)"),
+        ('dist-dir=', 'd', "directory where the distributions are"),
+        ('keep=', 'k', "number of matching distributions to keep"),
+    ]
+
+    boolean_options = []
+
+    def initialize_options(self):
+        self.match = None
+        self.dist_dir = None
+        self.keep = None
+
+    def finalize_options(self):
+        if self.match is None:
+            raise DistutilsOptionError(
+                "Must specify one or more (comma-separated) match patterns "
+                "(e.g. '.zip' or '.egg')"
+            )
+        if self.keep is None:
+            raise DistutilsOptionError("Must specify number of files to keep")
+        try:
+            self.keep = int(self.keep)
+        except ValueError:
+            raise DistutilsOptionError("--keep must be an integer")
+        if isinstance(self.match, six.string_types):
+            self.match = [
+                convert_path(p.strip()) for p in self.match.split(',')
+            ]
+        self.set_undefined_options('bdist', ('dist_dir', 'dist_dir'))
+
+    def run(self):
+        self.run_command("egg_info")
+        from glob import glob
+
+        for pattern in self.match:
+            pattern = self.distribution.get_name() + '*' + pattern
+            files = glob(os.path.join(self.dist_dir, pattern))
+            files = [(os.path.getmtime(f), f) for f in files]
+            files.sort()
+            files.reverse()
+
+            log.info("%d file(s) matching %s", len(files), pattern)
+            files = files[self.keep:]
+            for (t, f) in files:
+                log.info("Deleting %s", f)
+                if not self.dry_run:
+                    if os.path.isdir(f):
+                        shutil.rmtree(f)
+                    else:
+                        os.unlink(f)
diff --git a/vendor/setuptools-39.0.1/setuptools/command/saveopts.py b/vendor/setuptools-39.0.1/setuptools/command/saveopts.py
new file mode 100755
index 00000000..611cec55
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/saveopts.py
@@ -0,0 +1,22 @@
+from setuptools.command.setopt import edit_config, option_base
+
+
+class saveopts(option_base):
+    """Save command-line options to a file"""
+
+    description = "save supplied options to setup.cfg or other config file"
+
+    def run(self):
+        dist = self.distribution
+        settings = {}
+
+        for cmd in dist.command_options:
+
+            if cmd == 'saveopts':
+                continue  # don't save our own options!
+
+            for opt, (src, val) in dist.get_option_dict(cmd).items():
+                if src == "command line":
+                    settings.setdefault(cmd, {})[opt] = val
+
+        edit_config(self.filename, settings, self.dry_run)
diff --git a/vendor/setuptools-39.0.1/setuptools/command/sdist.py b/vendor/setuptools-39.0.1/setuptools/command/sdist.py
new file mode 100755
index 00000000..bcfae4d8
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/sdist.py
@@ -0,0 +1,200 @@
+from distutils import log
+import distutils.command.sdist as orig
+import os
+import sys
+import io
+import contextlib
+
+from setuptools.extern import six
+
+from .py36compat import sdist_add_defaults
+
+import pkg_resources
+
+_default_revctrl = list
+
+
+def walk_revctrl(dirname=''):
+    """Find all files under revision control"""
+    for ep in pkg_resources.iter_entry_points('setuptools.file_finders'):
+        for item in ep.load()(dirname):
+            yield item
+
+
+class sdist(sdist_add_defaults, orig.sdist):
+    """Smart sdist that finds anything supported by revision control"""
+
+    user_options = [
+        ('formats=', None,
+         "formats for source distribution (comma-separated list)"),
+        ('keep-temp', 'k',
+         "keep the distribution tree around after creating " +
+         "archive file(s)"),
+        ('dist-dir=', 'd',
+         "directory to put the source distribution archive(s) in "
+         "[default: dist]"),
+    ]
+
+    negative_opt = {}
+
+    README_EXTENSIONS = ['', '.rst', '.txt', '.md']
+    READMES = tuple('README{0}'.format(ext) for ext in README_EXTENSIONS)
+
+    def run(self):
+        self.run_command('egg_info')
+        ei_cmd = self.get_finalized_command('egg_info')
+        self.filelist = ei_cmd.filelist
+        self.filelist.append(os.path.join(ei_cmd.egg_info, 'SOURCES.txt'))
+        self.check_readme()
+
+        # Run sub commands
+        for cmd_name in self.get_sub_commands():
+            self.run_command(cmd_name)
+
+        self.make_distribution()
+
+        dist_files = getattr(self.distribution, 'dist_files', [])
+        for file in self.archive_files:
+            data = ('sdist', '', file)
+            if data not in dist_files:
+                dist_files.append(data)
+
+    def initialize_options(self):
+        orig.sdist.initialize_options(self)
+
+        self._default_to_gztar()
+
+    def _default_to_gztar(self):
+        # only needed on Python prior to 3.6.
+        if sys.version_info >= (3, 6, 0, 'beta', 1):
+            return
+        self.formats = ['gztar']
+
+    def make_distribution(self):
+        """
+        Workaround for #516
+        """
+        with self._remove_os_link():
+            orig.sdist.make_distribution(self)
+
+    @staticmethod
+    @contextlib.contextmanager
+    def _remove_os_link():
+        """
+        In a context, remove and restore os.link if it exists
+        """
+
+        class NoValue:
+            pass
+
+        orig_val = getattr(os, 'link', NoValue)
+        try:
+            del os.link
+        except Exception:
+            pass
+        try:
+            yield
+        finally:
+            if orig_val is not NoValue:
+                setattr(os, 'link', orig_val)
+
+    def __read_template_hack(self):
+        # This grody hack closes the template file (MANIFEST.in) if an
+        #  exception occurs during read_template.
+        # Doing so prevents an error when easy_install attempts to delete the
+        #  file.
+        try:
+            orig.sdist.read_template(self)
+        except Exception:
+            _, _, tb = sys.exc_info()
+            tb.tb_next.tb_frame.f_locals['template'].close()
+            raise
+
+    # Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle
+    #  has been fixed, so only override the method if we're using an earlier
+    #  Python.
+    has_leaky_handle = (
+        sys.version_info < (2, 7, 2)
+        or (3, 0) <= sys.version_info < (3, 1, 4)
+        or (3, 2) <= sys.version_info < (3, 2, 1)
+    )
+    if has_leaky_handle:
+        read_template = __read_template_hack
+
+    def _add_defaults_python(self):
+        """getting python files"""
+        if self.distribution.has_pure_modules():
+            build_py = self.get_finalized_command('build_py')
+            self.filelist.extend(build_py.get_source_files())
+            # This functionality is incompatible with include_package_data, and
+            # will in fact create an infinite recursion if include_package_data
+            # is True.  Use of include_package_data will imply that
+            # distutils-style automatic handling of package_data is disabled
+            if not self.distribution.include_package_data:
+                for _, src_dir, _, filenames in build_py.data_files:
+                    self.filelist.extend([os.path.join(src_dir, filename)
+                                          for filename in filenames])
+
+    def _add_defaults_data_files(self):
+        try:
+            if six.PY2:
+                sdist_add_defaults._add_defaults_data_files(self)
+            else:
+                super()._add_defaults_data_files()
+        except TypeError:
+            log.warn("data_files contains unexpected objects")
+
+    def check_readme(self):
+        for f in self.READMES:
+            if os.path.exists(f):
+                return
+        else:
+            self.warn(
+                "standard file not found: should have one of " +
+                ', '.join(self.READMES)
+            )
+
+    def make_release_tree(self, base_dir, files):
+        orig.sdist.make_release_tree(self, base_dir, files)
+
+        # Save any egg_info command line options used to create this sdist
+        dest = os.path.join(base_dir, 'setup.cfg')
+        if hasattr(os, 'link') and os.path.exists(dest):
+            # unlink and re-copy, since it might be hard-linked, and
+            # we don't want to change the source version
+            os.unlink(dest)
+            self.copy_file('setup.cfg', dest)
+
+        self.get_finalized_command('egg_info').save_version_info(dest)
+
+    def _manifest_is_not_generated(self):
+        # check for special comment used in 2.7.1 and higher
+        if not os.path.isfile(self.manifest):
+            return False
+
+        with io.open(self.manifest, 'rb') as fp:
+            first_line = fp.readline()
+        return (first_line !=
+                '# file GENERATED by distutils, do NOT edit\n'.encode())
+
+    def read_manifest(self):
+        """Read the manifest file (named by 'self.manifest') and use it to
+        fill in 'self.filelist', the list of files to include in the source
+        distribution.
+        """
+        log.info("reading manifest file '%s'", self.manifest)
+        manifest = open(self.manifest, 'rb')
+        for line in manifest:
+            # The manifest must contain UTF-8. See #303.
+            if six.PY3:
+                try:
+                    line = line.decode('UTF-8')
+                except UnicodeDecodeError:
+                    log.warn("%r not UTF-8 decodable -- skipping" % line)
+                    continue
+            # ignore comments and blank lines
+            line = line.strip()
+            if line.startswith('#') or not line:
+                continue
+            self.filelist.append(line)
+        manifest.close()
diff --git a/vendor/setuptools-39.0.1/setuptools/command/setopt.py b/vendor/setuptools-39.0.1/setuptools/command/setopt.py
new file mode 100755
index 00000000..7e57cc02
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/setopt.py
@@ -0,0 +1,149 @@
+from distutils.util import convert_path
+from distutils import log
+from distutils.errors import DistutilsOptionError
+import distutils
+import os
+
+from setuptools.extern.six.moves import configparser
+
+from setuptools import Command
+
+__all__ = ['config_file', 'edit_config', 'option_base', 'setopt']
+
+
+def config_file(kind="local"):
+    """Get the filename of the distutils, local, global, or per-user config
+
+    `kind` must be one of "local", "global", or "user"
+    """
+    if kind == 'local':
+        return 'setup.cfg'
+    if kind == 'global':
+        return os.path.join(
+            os.path.dirname(distutils.__file__), 'distutils.cfg'
+        )
+    if kind == 'user':
+        dot = os.name == 'posix' and '.' or ''
+        return os.path.expanduser(convert_path("~/%spydistutils.cfg" % dot))
+    raise ValueError(
+        "config_file() type must be 'local', 'global', or 'user'", kind
+    )
+
+
+def edit_config(filename, settings, dry_run=False):
+    """Edit a configuration file to include `settings`
+
+    `settings` is a dictionary of dictionaries or ``None`` values, keyed by
+    command/section name.  A ``None`` value means to delete the entire section,
+    while a dictionary lists settings to be changed or deleted in that section.
+    A setting of ``None`` means to delete that setting.
+    """
+    log.debug("Reading configuration from %s", filename)
+    opts = configparser.RawConfigParser()
+    opts.read([filename])
+    for section, options in settings.items():
+        if options is None:
+            log.info("Deleting section [%s] from %s", section, filename)
+            opts.remove_section(section)
+        else:
+            if not opts.has_section(section):
+                log.debug("Adding new section [%s] to %s", section, filename)
+                opts.add_section(section)
+            for option, value in options.items():
+                if value is None:
+                    log.debug(
+                        "Deleting %s.%s from %s",
+                        section, option, filename
+                    )
+                    opts.remove_option(section, option)
+                    if not opts.options(section):
+                        log.info("Deleting empty [%s] section from %s",
+                                 section, filename)
+                        opts.remove_section(section)
+                else:
+                    log.debug(
+                        "Setting %s.%s to %r in %s",
+                        section, option, value, filename
+                    )
+                    opts.set(section, option, value)
+
+    log.info("Writing %s", filename)
+    if not dry_run:
+        with open(filename, 'w') as f:
+            opts.write(f)
+
+
+class option_base(Command):
+    """Abstract base class for commands that mess with config files"""
+
+    user_options = [
+        ('global-config', 'g',
+         "save options to the site-wide distutils.cfg file"),
+        ('user-config', 'u',
+         "save options to the current user's pydistutils.cfg file"),
+        ('filename=', 'f',
+         "configuration file to use (default=setup.cfg)"),
+    ]
+
+    boolean_options = [
+        'global-config', 'user-config',
+    ]
+
+    def initialize_options(self):
+        self.global_config = None
+        self.user_config = None
+        self.filename = None
+
+    def finalize_options(self):
+        filenames = []
+        if self.global_config:
+            filenames.append(config_file('global'))
+        if self.user_config:
+            filenames.append(config_file('user'))
+        if self.filename is not None:
+            filenames.append(self.filename)
+        if not filenames:
+            filenames.append(config_file('local'))
+        if len(filenames) > 1:
+            raise DistutilsOptionError(
+                "Must specify only one configuration file option",
+                filenames
+            )
+        self.filename, = filenames
+
+
+class setopt(option_base):
+    """Save command-line options to a file"""
+
+    description = "set an option in setup.cfg or another config file"
+
+    user_options = [
+        ('command=', 'c', 'command to set an option for'),
+        ('option=', 'o', 'option to set'),
+        ('set-value=', 's', 'value of the option'),
+        ('remove', 'r', 'remove (unset) the value'),
+    ] + option_base.user_options
+
+    boolean_options = option_base.boolean_options + ['remove']
+
+    def initialize_options(self):
+        option_base.initialize_options(self)
+        self.command = None
+        self.option = None
+        self.set_value = None
+        self.remove = None
+
+    def finalize_options(self):
+        option_base.finalize_options(self)
+        if self.command is None or self.option is None:
+            raise DistutilsOptionError("Must specify --command *and* --option")
+        if self.set_value is None and not self.remove:
+            raise DistutilsOptionError("Must specify --set-value or --remove")
+
+    def run(self):
+        edit_config(
+            self.filename, {
+                self.command: {self.option.replace('-', '_'): self.set_value}
+            },
+            self.dry_run
+        )
diff --git a/vendor/setuptools-39.0.1/setuptools/command/test.py b/vendor/setuptools-39.0.1/setuptools/command/test.py
new file mode 100644
index 00000000..51aee1f7
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/test.py
@@ -0,0 +1,268 @@
+import os
+import operator
+import sys
+import contextlib
+import itertools
+import unittest
+from distutils.errors import DistutilsError, DistutilsOptionError
+from distutils import log
+from unittest import TestLoader
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import map, filter
+
+from pkg_resources import (resource_listdir, resource_exists, normalize_path,
+                           working_set, _namespace_packages, evaluate_marker,
+                           add_activation_listener, require, EntryPoint)
+from setuptools import Command
+
+
+class ScanningLoader(TestLoader):
+
+    def __init__(self):
+        TestLoader.__init__(self)
+        self._visited = set()
+
+    def loadTestsFromModule(self, module, pattern=None):
+        """Return a suite of all tests cases contained in the given module
+
+        If the module is a package, load tests from all the modules in it.
+        If the module has an ``additional_tests`` function, call it and add
+        the return value to the tests.
+        """
+        if module in self._visited:
+            return None
+        self._visited.add(module)
+
+        tests = []
+        tests.append(TestLoader.loadTestsFromModule(self, module))
+
+        if hasattr(module, "additional_tests"):
+            tests.append(module.additional_tests())
+
+        if hasattr(module, '__path__'):
+            for file in resource_listdir(module.__name__, ''):
+                if file.endswith('.py') and file != '__init__.py':
+                    submodule = module.__name__ + '.' + file[:-3]
+                else:
+                    if resource_exists(module.__name__, file + '/__init__.py'):
+                        submodule = module.__name__ + '.' + file
+                    else:
+                        continue
+                tests.append(self.loadTestsFromName(submodule))
+
+        if len(tests) != 1:
+            return self.suiteClass(tests)
+        else:
+            return tests[0]  # don't create a nested suite for only one return
+
+
+# adapted from jaraco.classes.properties:NonDataProperty
+class NonDataProperty(object):
+    def __init__(self, fget):
+        self.fget = fget
+
+    def __get__(self, obj, objtype=None):
+        if obj is None:
+            return self
+        return self.fget(obj)
+
+
+class test(Command):
+    """Command to run unit tests after in-place build"""
+
+    description = "run unit tests after in-place build"
+
+    user_options = [
+        ('test-module=', 'm', "Run 'test_suite' in specified module"),
+        ('test-suite=', 's',
+         "Run single test, case or suite (e.g. 'module.test_suite')"),
+        ('test-runner=', 'r', "Test runner to use"),
+    ]
+
+    def initialize_options(self):
+        self.test_suite = None
+        self.test_module = None
+        self.test_loader = None
+        self.test_runner = None
+
+    def finalize_options(self):
+
+        if self.test_suite and self.test_module:
+            msg = "You may specify a module or a suite, but not both"
+            raise DistutilsOptionError(msg)
+
+        if self.test_suite is None:
+            if self.test_module is None:
+                self.test_suite = self.distribution.test_suite
+            else:
+                self.test_suite = self.test_module + ".test_suite"
+
+        if self.test_loader is None:
+            self.test_loader = getattr(self.distribution, 'test_loader', None)
+        if self.test_loader is None:
+            self.test_loader = "setuptools.command.test:ScanningLoader"
+        if self.test_runner is None:
+            self.test_runner = getattr(self.distribution, 'test_runner', None)
+
+    @NonDataProperty
+    def test_args(self):
+        return list(self._test_args())
+
+    def _test_args(self):
+        if not self.test_suite and sys.version_info >= (2, 7):
+            yield 'discover'
+        if self.verbose:
+            yield '--verbose'
+        if self.test_suite:
+            yield self.test_suite
+
+    def with_project_on_sys_path(self, func):
+        """
+        Backward compatibility for project_on_sys_path context.
+        """
+        with self.project_on_sys_path():
+            func()
+
+    @contextlib.contextmanager
+    def project_on_sys_path(self, include_dists=[]):
+        with_2to3 = six.PY3 and getattr(self.distribution, 'use_2to3', False)
+
+        if with_2to3:
+            # If we run 2to3 we can not do this inplace:
+
+            # Ensure metadata is up-to-date
+            self.reinitialize_command('build_py', inplace=0)
+            self.run_command('build_py')
+            bpy_cmd = self.get_finalized_command("build_py")
+            build_path = normalize_path(bpy_cmd.build_lib)
+
+            # Build extensions
+            self.reinitialize_command('egg_info', egg_base=build_path)
+            self.run_command('egg_info')
+
+            self.reinitialize_command('build_ext', inplace=0)
+            self.run_command('build_ext')
+        else:
+            # Without 2to3 inplace works fine:
+            self.run_command('egg_info')
+
+            # Build extensions in-place
+            self.reinitialize_command('build_ext', inplace=1)
+            self.run_command('build_ext')
+
+        ei_cmd = self.get_finalized_command("egg_info")
+
+        old_path = sys.path[:]
+        old_modules = sys.modules.copy()
+
+        try:
+            project_path = normalize_path(ei_cmd.egg_base)
+            sys.path.insert(0, project_path)
+            working_set.__init__()
+            add_activation_listener(lambda dist: dist.activate())
+            require('%s==%s' % (ei_cmd.egg_name, ei_cmd.egg_version))
+            with self.paths_on_pythonpath([project_path]):
+                yield
+        finally:
+            sys.path[:] = old_path
+            sys.modules.clear()
+            sys.modules.update(old_modules)
+            working_set.__init__()
+
+    @staticmethod
+    @contextlib.contextmanager
+    def paths_on_pythonpath(paths):
+        """
+        Add the indicated paths to the head of the PYTHONPATH environment
+        variable so that subprocesses will also see the packages at
+        these paths.
+
+        Do this in a context that restores the value on exit.
+        """
+        nothing = object()
+        orig_pythonpath = os.environ.get('PYTHONPATH', nothing)
+        current_pythonpath = os.environ.get('PYTHONPATH', '')
+        try:
+            prefix = os.pathsep.join(paths)
+            to_join = filter(None, [prefix, current_pythonpath])
+            new_path = os.pathsep.join(to_join)
+            if new_path:
+                os.environ['PYTHONPATH'] = new_path
+            yield
+        finally:
+            if orig_pythonpath is nothing:
+                os.environ.pop('PYTHONPATH', None)
+            else:
+                os.environ['PYTHONPATH'] = orig_pythonpath
+
+    @staticmethod
+    def install_dists(dist):
+        """
+        Install the requirements indicated by self.distribution and
+        return an iterable of the dists that were built.
+        """
+        ir_d = dist.fetch_build_eggs(dist.install_requires)
+        tr_d = dist.fetch_build_eggs(dist.tests_require or [])
+        er_d = dist.fetch_build_eggs(
+            v for k, v in dist.extras_require.items()
+            if k.startswith(':') and evaluate_marker(k[1:])
+        )
+        return itertools.chain(ir_d, tr_d, er_d)
+
+    def run(self):
+        installed_dists = self.install_dists(self.distribution)
+
+        cmd = ' '.join(self._argv)
+        if self.dry_run:
+            self.announce('skipping "%s" (dry run)' % cmd)
+            return
+
+        self.announce('running "%s"' % cmd)
+
+        paths = map(operator.attrgetter('location'), installed_dists)
+        with self.paths_on_pythonpath(paths):
+            with self.project_on_sys_path():
+                self.run_tests()
+
+    def run_tests(self):
+        # Purge modules under test from sys.modules. The test loader will
+        # re-import them from the build location. Required when 2to3 is used
+        # with namespace packages.
+        if six.PY3 and getattr(self.distribution, 'use_2to3', False):
+            module = self.test_suite.split('.')[0]
+            if module in _namespace_packages:
+                del_modules = []
+                if module in sys.modules:
+                    del_modules.append(module)
+                module += '.'
+                for name in sys.modules:
+                    if name.startswith(module):
+                        del_modules.append(name)
+                list(map(sys.modules.__delitem__, del_modules))
+
+        test = unittest.main(
+            None, None, self._argv,
+            testLoader=self._resolve_as_ep(self.test_loader),
+            testRunner=self._resolve_as_ep(self.test_runner),
+            exit=False,
+        )
+        if not test.result.wasSuccessful():
+            msg = 'Test failed: %s' % test.result
+            self.announce(msg, log.ERROR)
+            raise DistutilsError(msg)
+
+    @property
+    def _argv(self):
+        return ['unittest'] + self.test_args
+
+    @staticmethod
+    def _resolve_as_ep(val):
+        """
+        Load the indicated attribute value, called, as a as if it were
+        specified as an entry point.
+        """
+        if val is None:
+            return
+        parsed = EntryPoint.parse("x=" + val)
+        return parsed.resolve()()
diff --git a/vendor/setuptools-39.0.1/setuptools/command/upload.py b/vendor/setuptools-39.0.1/setuptools/command/upload.py
new file mode 100644
index 00000000..a44173a9
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/upload.py
@@ -0,0 +1,42 @@
+import getpass
+from distutils.command import upload as orig
+
+
+class upload(orig.upload):
+    """
+    Override default upload behavior to obtain password
+    in a variety of different ways.
+    """
+
+    def finalize_options(self):
+        orig.upload.finalize_options(self)
+        self.username = (
+            self.username or
+            getpass.getuser()
+        )
+        # Attempt to obtain password. Short circuit evaluation at the first
+        # sign of success.
+        self.password = (
+            self.password or
+            self._load_password_from_keyring() or
+            self._prompt_for_password()
+        )
+
+    def _load_password_from_keyring(self):
+        """
+        Attempt to load password from keyring. Suppress Exceptions.
+        """
+        try:
+            keyring = __import__('keyring')
+            return keyring.get_password(self.repository, self.username)
+        except Exception:
+            pass
+
+    def _prompt_for_password(self):
+        """
+        Prompt for a password on the tty. Suppress Exceptions.
+        """
+        try:
+            return getpass.getpass()
+        except (Exception, KeyboardInterrupt):
+            pass
diff --git a/vendor/setuptools-39.0.1/setuptools/command/upload_docs.py b/vendor/setuptools-39.0.1/setuptools/command/upload_docs.py
new file mode 100644
index 00000000..07aa564a
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/command/upload_docs.py
@@ -0,0 +1,206 @@
+# -*- coding: utf-8 -*-
+"""upload_docs
+
+Implements a Distutils 'upload_docs' subcommand (upload documentation to
+PyPI's pythonhosted.org).
+"""
+
+from base64 import standard_b64encode
+from distutils import log
+from distutils.errors import DistutilsOptionError
+import os
+import socket
+import zipfile
+import tempfile
+import shutil
+import itertools
+import functools
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import http_client, urllib
+
+from pkg_resources import iter_entry_points
+from .upload import upload
+
+
+def _encode(s):
+    errors = 'surrogateescape' if six.PY3 else 'strict'
+    return s.encode('utf-8', errors)
+
+
+class upload_docs(upload):
+    # override the default repository as upload_docs isn't
+    # supported by Warehouse (and won't be).
+    DEFAULT_REPOSITORY = 'https://pypi.python.org/pypi/'
+
+    description = 'Upload documentation to PyPI'
+
+    user_options = [
+        ('repository=', 'r',
+         "url of repository [default: %s]" % upload.DEFAULT_REPOSITORY),
+        ('show-response', None,
+         'display full response text from server'),
+        ('upload-dir=', None, 'directory to upload'),
+    ]
+    boolean_options = upload.boolean_options
+
+    def has_sphinx(self):
+        if self.upload_dir is None:
+            for ep in iter_entry_points('distutils.commands', 'build_sphinx'):
+                return True
+
+    sub_commands = [('build_sphinx', has_sphinx)]
+
+    def initialize_options(self):
+        upload.initialize_options(self)
+        self.upload_dir = None
+        self.target_dir = None
+
+    def finalize_options(self):
+        upload.finalize_options(self)
+        if self.upload_dir is None:
+            if self.has_sphinx():
+                build_sphinx = self.get_finalized_command('build_sphinx')
+                self.target_dir = build_sphinx.builder_target_dir
+            else:
+                build = self.get_finalized_command('build')
+                self.target_dir = os.path.join(build.build_base, 'docs')
+        else:
+            self.ensure_dirname('upload_dir')
+            self.target_dir = self.upload_dir
+        if 'pypi.python.org' in self.repository:
+            log.warn("Upload_docs command is deprecated. Use RTD instead.")
+        self.announce('Using upload directory %s' % self.target_dir)
+
+    def create_zipfile(self, filename):
+        zip_file = zipfile.ZipFile(filename, "w")
+        try:
+            self.mkpath(self.target_dir)  # just in case
+            for root, dirs, files in os.walk(self.target_dir):
+                if root == self.target_dir and not files:
+                    tmpl = "no files found in upload directory '%s'"
+                    raise DistutilsOptionError(tmpl % self.target_dir)
+                for name in files:
+                    full = os.path.join(root, name)
+                    relative = root[len(self.target_dir):].lstrip(os.path.sep)
+                    dest = os.path.join(relative, name)
+                    zip_file.write(full, dest)
+        finally:
+            zip_file.close()
+
+    def run(self):
+        # Run sub commands
+        for cmd_name in self.get_sub_commands():
+            self.run_command(cmd_name)
+
+        tmp_dir = tempfile.mkdtemp()
+        name = self.distribution.metadata.get_name()
+        zip_file = os.path.join(tmp_dir, "%s.zip" % name)
+        try:
+            self.create_zipfile(zip_file)
+            self.upload_file(zip_file)
+        finally:
+            shutil.rmtree(tmp_dir)
+
+    @staticmethod
+    def _build_part(item, sep_boundary):
+        key, values = item
+        title = '\nContent-Disposition: form-data; name="%s"' % key
+        # handle multiple entries for the same name
+        if not isinstance(values, list):
+            values = [values]
+        for value in values:
+            if isinstance(value, tuple):
+                title += '; filename="%s"' % value[0]
+                value = value[1]
+            else:
+                value = _encode(value)
+            yield sep_boundary
+            yield _encode(title)
+            yield b"\n\n"
+            yield value
+            if value and value[-1:] == b'\r':
+                yield b'\n'  # write an extra newline (lurve Macs)
+
+    @classmethod
+    def _build_multipart(cls, data):
+        """
+        Build up the MIME payload for the POST data
+        """
+        boundary = b'--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
+        sep_boundary = b'\n--' + boundary
+        end_boundary = sep_boundary + b'--'
+        end_items = end_boundary, b"\n",
+        builder = functools.partial(
+            cls._build_part,
+            sep_boundary=sep_boundary,
+        )
+        part_groups = map(builder, data.items())
+        parts = itertools.chain.from_iterable(part_groups)
+        body_items = itertools.chain(parts, end_items)
+        content_type = 'multipart/form-data; boundary=%s' % boundary.decode('ascii')
+        return b''.join(body_items), content_type
+
+    def upload_file(self, filename):
+        with open(filename, 'rb') as f:
+            content = f.read()
+        meta = self.distribution.metadata
+        data = {
+            ':action': 'doc_upload',
+            'name': meta.get_name(),
+            'content': (os.path.basename(filename), content),
+        }
+        # set up the authentication
+        credentials = _encode(self.username + ':' + self.password)
+        credentials = standard_b64encode(credentials)
+        if six.PY3:
+            credentials = credentials.decode('ascii')
+        auth = "Basic " + credentials
+
+        body, ct = self._build_multipart(data)
+
+        msg = "Submitting documentation to %s" % (self.repository)
+        self.announce(msg, log.INFO)
+
+        # build the Request
+        # We can't use urllib2 since we need to send the Basic
+        # auth right with the first request
+        schema, netloc, url, params, query, fragments = \
+            urllib.parse.urlparse(self.repository)
+        assert not params and not query and not fragments
+        if schema == 'http':
+            conn = http_client.HTTPConnection(netloc)
+        elif schema == 'https':
+            conn = http_client.HTTPSConnection(netloc)
+        else:
+            raise AssertionError("unsupported schema " + schema)
+
+        data = ''
+        try:
+            conn.connect()
+            conn.putrequest("POST", url)
+            content_type = ct
+            conn.putheader('Content-type', content_type)
+            conn.putheader('Content-length', str(len(body)))
+            conn.putheader('Authorization', auth)
+            conn.endheaders()
+            conn.send(body)
+        except socket.error as e:
+            self.announce(str(e), log.ERROR)
+            return
+
+        r = conn.getresponse()
+        if r.status == 200:
+            msg = 'Server response (%s): %s' % (r.status, r.reason)
+            self.announce(msg, log.INFO)
+        elif r.status == 301:
+            location = r.getheader('Location')
+            if location is None:
+                location = 'https://pythonhosted.org/%s/' % meta.get_name()
+            msg = 'Upload successful. Visit %s' % location
+            self.announce(msg, log.INFO)
+        else:
+            msg = 'Upload failed (%s): %s' % (r.status, r.reason)
+            self.announce(msg, log.ERROR)
+        if self.show_response:
+            print('-' * 75, r.read(), '-' * 75)
diff --git a/vendor/setuptools-39.0.1/setuptools/config.py b/vendor/setuptools-39.0.1/setuptools/config.py
new file mode 100644
index 00000000..8eddcae8
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/config.py
@@ -0,0 +1,556 @@
+from __future__ import absolute_import, unicode_literals
+import io
+import os
+import sys
+from collections import defaultdict
+from functools import partial
+from importlib import import_module
+
+from distutils.errors import DistutilsOptionError, DistutilsFileError
+from setuptools.extern.six import string_types
+
+
+def read_configuration(
+        filepath, find_others=False, ignore_option_errors=False):
+    """Read given configuration file and returns options from it as a dict.
+
+    :param str|unicode filepath: Path to configuration file
+        to get options from.
+
+    :param bool find_others: Whether to search for other configuration files
+        which could be on in various places.
+
+    :param bool ignore_option_errors: Whether to silently ignore
+        options, values of which could not be resolved (e.g. due to exceptions
+        in directives such as file:, attr:, etc.).
+        If False exceptions are propagated as expected.
+
+    :rtype: dict
+    """
+    from setuptools.dist import Distribution, _Distribution
+
+    filepath = os.path.abspath(filepath)
+
+    if not os.path.isfile(filepath):
+        raise DistutilsFileError(
+            'Configuration file %s does not exist.' % filepath)
+
+    current_directory = os.getcwd()
+    os.chdir(os.path.dirname(filepath))
+
+    try:
+        dist = Distribution()
+
+        filenames = dist.find_config_files() if find_others else []
+        if filepath not in filenames:
+            filenames.append(filepath)
+
+        _Distribution.parse_config_files(dist, filenames=filenames)
+
+        handlers = parse_configuration(
+            dist, dist.command_options,
+            ignore_option_errors=ignore_option_errors)
+
+    finally:
+        os.chdir(current_directory)
+
+    return configuration_to_dict(handlers)
+
+
+def configuration_to_dict(handlers):
+    """Returns configuration data gathered by given handlers as a dict.
+
+    :param list[ConfigHandler] handlers: Handlers list,
+        usually from parse_configuration()
+
+    :rtype: dict
+    """
+    config_dict = defaultdict(dict)
+
+    for handler in handlers:
+
+        obj_alias = handler.section_prefix
+        target_obj = handler.target_obj
+
+        for option in handler.set_options:
+            getter = getattr(target_obj, 'get_%s' % option, None)
+
+            if getter is None:
+                value = getattr(target_obj, option)
+
+            else:
+                value = getter()
+
+            config_dict[obj_alias][option] = value
+
+    return config_dict
+
+
+def parse_configuration(
+        distribution, command_options, ignore_option_errors=False):
+    """Performs additional parsing of configuration options
+    for a distribution.
+
+    Returns a list of used option handlers.
+
+    :param Distribution distribution:
+    :param dict command_options:
+    :param bool ignore_option_errors: Whether to silently ignore
+        options, values of which could not be resolved (e.g. due to exceptions
+        in directives such as file:, attr:, etc.).
+        If False exceptions are propagated as expected.
+    :rtype: list
+    """
+    meta = ConfigMetadataHandler(
+        distribution.metadata, command_options, ignore_option_errors)
+    meta.parse()
+
+    options = ConfigOptionsHandler(
+        distribution, command_options, ignore_option_errors)
+    options.parse()
+
+    return meta, options
+
+
+class ConfigHandler(object):
+    """Handles metadata supplied in configuration files."""
+
+    section_prefix = None
+    """Prefix for config sections handled by this handler.
+    Must be provided by class heirs.
+
+    """
+
+    aliases = {}
+    """Options aliases.
+    For compatibility with various packages. E.g.: d2to1 and pbr.
+    Note: `-` in keys is replaced with `_` by config parser.
+
+    """
+
+    def __init__(self, target_obj, options, ignore_option_errors=False):
+        sections = {}
+
+        section_prefix = self.section_prefix
+        for section_name, section_options in options.items():
+            if not section_name.startswith(section_prefix):
+                continue
+
+            section_name = section_name.replace(section_prefix, '').strip('.')
+            sections[section_name] = section_options
+
+        self.ignore_option_errors = ignore_option_errors
+        self.target_obj = target_obj
+        self.sections = sections
+        self.set_options = []
+
+    @property
+    def parsers(self):
+        """Metadata item name to parser function mapping."""
+        raise NotImplementedError(
+            '%s must provide .parsers property' % self.__class__.__name__)
+
+    def __setitem__(self, option_name, value):
+        unknown = tuple()
+        target_obj = self.target_obj
+
+        # Translate alias into real name.
+        option_name = self.aliases.get(option_name, option_name)
+
+        current_value = getattr(target_obj, option_name, unknown)
+
+        if current_value is unknown:
+            raise KeyError(option_name)
+
+        if current_value:
+            # Already inhabited. Skipping.
+            return
+
+        skip_option = False
+        parser = self.parsers.get(option_name)
+        if parser:
+            try:
+                value = parser(value)
+
+            except Exception:
+                skip_option = True
+                if not self.ignore_option_errors:
+                    raise
+
+        if skip_option:
+            return
+
+        setter = getattr(target_obj, 'set_%s' % option_name, None)
+        if setter is None:
+            setattr(target_obj, option_name, value)
+        else:
+            setter(value)
+
+        self.set_options.append(option_name)
+
+    @classmethod
+    def _parse_list(cls, value, separator=','):
+        """Represents value as a list.
+
+        Value is split either by separator (defaults to comma) or by lines.
+
+        :param value:
+        :param separator: List items separator character.
+        :rtype: list
+        """
+        if isinstance(value, list):  # _get_parser_compound case
+            return value
+
+        if '\n' in value:
+            value = value.splitlines()
+        else:
+            value = value.split(separator)
+
+        return [chunk.strip() for chunk in value if chunk.strip()]
+
+    @classmethod
+    def _parse_dict(cls, value):
+        """Represents value as a dict.
+
+        :param value:
+        :rtype: dict
+        """
+        separator = '='
+        result = {}
+        for line in cls._parse_list(value):
+            key, sep, val = line.partition(separator)
+            if sep != separator:
+                raise DistutilsOptionError(
+                    'Unable to parse option value to dict: %s' % value)
+            result[key.strip()] = val.strip()
+
+        return result
+
+    @classmethod
+    def _parse_bool(cls, value):
+        """Represents value as boolean.
+
+        :param value:
+        :rtype: bool
+        """
+        value = value.lower()
+        return value in ('1', 'true', 'yes')
+
+    @classmethod
+    def _parse_file(cls, value):
+        """Represents value as a string, allowing including text
+        from nearest files using `file:` directive.
+
+        Directive is sandboxed and won't reach anything outside
+        directory with setup.py.
+
+        Examples:
+            file: LICENSE
+            file: README.rst, CHANGELOG.md, src/file.txt
+
+        :param str value:
+        :rtype: str
+        """
+        include_directive = 'file:'
+
+        if not isinstance(value, string_types):
+            return value
+
+        if not value.startswith(include_directive):
+            return value
+
+        spec = value[len(include_directive):]
+        filepaths = (os.path.abspath(path.strip()) for path in spec.split(','))
+        return '\n'.join(
+            cls._read_file(path)
+            for path in filepaths
+            if (cls._assert_local(path) or True)
+            and os.path.isfile(path)
+        )
+
+    @staticmethod
+    def _assert_local(filepath):
+        if not filepath.startswith(os.getcwd()):
+            raise DistutilsOptionError(
+                '`file:` directive can not access %s' % filepath)
+
+    @staticmethod
+    def _read_file(filepath):
+        with io.open(filepath, encoding='utf-8') as f:
+            return f.read()
+
+    @classmethod
+    def _parse_attr(cls, value):
+        """Represents value as a module attribute.
+
+        Examples:
+            attr: package.attr
+            attr: package.module.attr
+
+        :param str value:
+        :rtype: str
+        """
+        attr_directive = 'attr:'
+        if not value.startswith(attr_directive):
+            return value
+
+        attrs_path = value.replace(attr_directive, '').strip().split('.')
+        attr_name = attrs_path.pop()
+
+        module_name = '.'.join(attrs_path)
+        module_name = module_name or '__init__'
+
+        sys.path.insert(0, os.getcwd())
+        try:
+            module = import_module(module_name)
+            value = getattr(module, attr_name)
+
+        finally:
+            sys.path = sys.path[1:]
+
+        return value
+
+    @classmethod
+    def _get_parser_compound(cls, *parse_methods):
+        """Returns parser function to represents value as a list.
+
+        Parses a value applying given methods one after another.
+
+        :param parse_methods:
+        :rtype: callable
+        """
+        def parse(value):
+            parsed = value
+
+            for method in parse_methods:
+                parsed = method(parsed)
+
+            return parsed
+
+        return parse
+
+    @classmethod
+    def _parse_section_to_dict(cls, section_options, values_parser=None):
+        """Parses section options into a dictionary.
+
+        Optionally applies a given parser to values.
+
+        :param dict section_options:
+        :param callable values_parser:
+        :rtype: dict
+        """
+        value = {}
+        values_parser = values_parser or (lambda val: val)
+        for key, (_, val) in section_options.items():
+            value[key] = values_parser(val)
+        return value
+
+    def parse_section(self, section_options):
+        """Parses configuration file section.
+
+        :param dict section_options:
+        """
+        for (name, (_, value)) in section_options.items():
+            try:
+                self[name] = value
+
+            except KeyError:
+                pass  # Keep silent for a new option may appear anytime.
+
+    def parse(self):
+        """Parses configuration file items from one
+        or more related sections.
+
+        """
+        for section_name, section_options in self.sections.items():
+
+            method_postfix = ''
+            if section_name:  # [section.option] variant
+                method_postfix = '_%s' % section_name
+
+            section_parser_method = getattr(
+                self,
+                # Dots in section names are tranlsated into dunderscores.
+                ('parse_section%s' % method_postfix).replace('.', '__'),
+                None)
+
+            if section_parser_method is None:
+                raise DistutilsOptionError(
+                    'Unsupported distribution option section: [%s.%s]' % (
+                        self.section_prefix, section_name))
+
+            section_parser_method(section_options)
+
+
+class ConfigMetadataHandler(ConfigHandler):
+
+    section_prefix = 'metadata'
+
+    aliases = {
+        'home_page': 'url',
+        'summary': 'description',
+        'classifier': 'classifiers',
+        'platform': 'platforms',
+    }
+
+    strict_mode = False
+    """We need to keep it loose, to be partially compatible with
+    `pbr` and `d2to1` packages which also uses `metadata` section.
+
+    """
+
+    @property
+    def parsers(self):
+        """Metadata item name to parser function mapping."""
+        parse_list = self._parse_list
+        parse_file = self._parse_file
+        parse_dict = self._parse_dict
+
+        return {
+            'platforms': parse_list,
+            'keywords': parse_list,
+            'provides': parse_list,
+            'requires': parse_list,
+            'obsoletes': parse_list,
+            'classifiers': self._get_parser_compound(parse_file, parse_list),
+            'license': parse_file,
+            'description': parse_file,
+            'long_description': parse_file,
+            'version': self._parse_version,
+            'project_urls': parse_dict,
+        }
+
+    def _parse_version(self, value):
+        """Parses `version` option value.
+
+        :param value:
+        :rtype: str
+
+        """
+        version = self._parse_attr(value)
+
+        if callable(version):
+            version = version()
+
+        if not isinstance(version, string_types):
+            if hasattr(version, '__iter__'):
+                version = '.'.join(map(str, version))
+            else:
+                version = '%s' % version
+
+        return version
+
+
+class ConfigOptionsHandler(ConfigHandler):
+
+    section_prefix = 'options'
+
+    @property
+    def parsers(self):
+        """Metadata item name to parser function mapping."""
+        parse_list = self._parse_list
+        parse_list_semicolon = partial(self._parse_list, separator=';')
+        parse_bool = self._parse_bool
+        parse_dict = self._parse_dict
+
+        return {
+            'zip_safe': parse_bool,
+            'use_2to3': parse_bool,
+            'include_package_data': parse_bool,
+            'package_dir': parse_dict,
+            'use_2to3_fixers': parse_list,
+            'use_2to3_exclude_fixers': parse_list,
+            'convert_2to3_doctests': parse_list,
+            'scripts': parse_list,
+            'eager_resources': parse_list,
+            'dependency_links': parse_list,
+            'namespace_packages': parse_list,
+            'install_requires': parse_list_semicolon,
+            'setup_requires': parse_list_semicolon,
+            'tests_require': parse_list_semicolon,
+            'packages': self._parse_packages,
+            'entry_points': self._parse_file,
+            'py_modules': parse_list,
+        }
+
+    def _parse_packages(self, value):
+        """Parses `packages` option value.
+
+        :param value:
+        :rtype: list
+        """
+        find_directive = 'find:'
+
+        if not value.startswith(find_directive):
+            return self._parse_list(value)
+
+        # Read function arguments from a dedicated section.
+        find_kwargs = self.parse_section_packages__find(
+            self.sections.get('packages.find', {}))
+
+        from setuptools import find_packages
+
+        return find_packages(**find_kwargs)
+
+    def parse_section_packages__find(self, section_options):
+        """Parses `packages.find` configuration file section.
+
+        To be used in conjunction with _parse_packages().
+
+        :param dict section_options:
+        """
+        section_data = self._parse_section_to_dict(
+            section_options, self._parse_list)
+
+        valid_keys = ['where', 'include', 'exclude']
+
+        find_kwargs = dict(
+            [(k, v) for k, v in section_data.items() if k in valid_keys and v])
+
+        where = find_kwargs.get('where')
+        if where is not None:
+            find_kwargs['where'] = where[0]  # cast list to single val
+
+        return find_kwargs
+
+    def parse_section_entry_points(self, section_options):
+        """Parses `entry_points` configuration file section.
+
+        :param dict section_options:
+        """
+        parsed = self._parse_section_to_dict(section_options, self._parse_list)
+        self['entry_points'] = parsed
+
+    def _parse_package_data(self, section_options):
+        parsed = self._parse_section_to_dict(section_options, self._parse_list)
+
+        root = parsed.get('*')
+        if root:
+            parsed[''] = root
+            del parsed['*']
+
+        return parsed
+
+    def parse_section_package_data(self, section_options):
+        """Parses `package_data` configuration file section.
+
+        :param dict section_options:
+        """
+        self['package_data'] = self._parse_package_data(section_options)
+
+    def parse_section_exclude_package_data(self, section_options):
+        """Parses `exclude_package_data` configuration file section.
+
+        :param dict section_options:
+        """
+        self['exclude_package_data'] = self._parse_package_data(
+            section_options)
+
+    def parse_section_extras_require(self, section_options):
+        """Parses `extras_require` configuration file section.
+
+        :param dict section_options:
+        """
+        parse_list = partial(self._parse_list, separator=';')
+        self['extras_require'] = self._parse_section_to_dict(
+            section_options, parse_list)
diff --git a/vendor/setuptools-39.0.1/setuptools/dep_util.py b/vendor/setuptools-39.0.1/setuptools/dep_util.py
new file mode 100644
index 00000000..2931c13e
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/dep_util.py
@@ -0,0 +1,23 @@
+from distutils.dep_util import newer_group
+
+# yes, this is was almost entirely copy-pasted from
+# 'newer_pairwise()', this is just another convenience
+# function.
+def newer_pairwise_group(sources_groups, targets):
+    """Walk both arguments in parallel, testing if each source group is newer
+    than its corresponding target. Returns a pair of lists (sources_groups,
+    targets) where sources is newer than target, according to the semantics
+    of 'newer_group()'.
+    """
+    if len(sources_groups) != len(targets):
+        raise ValueError("'sources_group' and 'targets' must be the same length")
+
+    # build a pair of lists (sources_groups, targets) where source is newer
+    n_sources = []
+    n_targets = []
+    for i in range(len(sources_groups)):
+        if newer_group(sources_groups[i], targets[i]):
+            n_sources.append(sources_groups[i])
+            n_targets.append(targets[i])
+
+    return n_sources, n_targets
diff --git a/vendor/setuptools-39.0.1/setuptools/depends.py b/vendor/setuptools-39.0.1/setuptools/depends.py
new file mode 100644
index 00000000..45e7052d
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/depends.py
@@ -0,0 +1,186 @@
+import sys
+import imp
+import marshal
+from distutils.version import StrictVersion
+from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN
+
+from .py33compat import Bytecode
+
+
+__all__ = [
+    'Require', 'find_module', 'get_module_constant', 'extract_constant'
+]
+
+
+class Require:
+    """A prerequisite to building or installing a distribution"""
+
+    def __init__(self, name, requested_version, module, homepage='',
+            attribute=None, format=None):
+
+        if format is None and requested_version is not None:
+            format = StrictVersion
+
+        if format is not None:
+            requested_version = format(requested_version)
+            if attribute is None:
+                attribute = '__version__'
+
+        self.__dict__.update(locals())
+        del self.self
+
+    def full_name(self):
+        """Return full package/distribution name, w/version"""
+        if self.requested_version is not None:
+            return '%s-%s' % (self.name, self.requested_version)
+        return self.name
+
+    def version_ok(self, version):
+        """Is 'version' sufficiently up-to-date?"""
+        return self.attribute is None or self.format is None or \
+            str(version) != "unknown" and version >= self.requested_version
+
+    def get_version(self, paths=None, default="unknown"):
+        """Get version number of installed module, 'None', or 'default'
+
+        Search 'paths' for module.  If not found, return 'None'.  If found,
+        return the extracted version attribute, or 'default' if no version
+        attribute was specified, or the value cannot be determined without
+        importing the module.  The version is formatted according to the
+        requirement's version format (if any), unless it is 'None' or the
+        supplied 'default'.
+        """
+
+        if self.attribute is None:
+            try:
+                f, p, i = find_module(self.module, paths)
+                if f:
+                    f.close()
+                return default
+            except ImportError:
+                return None
+
+        v = get_module_constant(self.module, self.attribute, default, paths)
+
+        if v is not None and v is not default and self.format is not None:
+            return self.format(v)
+
+        return v
+
+    def is_present(self, paths=None):
+        """Return true if dependency is present on 'paths'"""
+        return self.get_version(paths) is not None
+
+    def is_current(self, paths=None):
+        """Return true if dependency is present and up-to-date on 'paths'"""
+        version = self.get_version(paths)
+        if version is None:
+            return False
+        return self.version_ok(version)
+
+
+def find_module(module, paths=None):
+    """Just like 'imp.find_module()', but with package support"""
+
+    parts = module.split('.')
+
+    while parts:
+        part = parts.pop(0)
+        f, path, (suffix, mode, kind) = info = imp.find_module(part, paths)
+
+        if kind == PKG_DIRECTORY:
+            parts = parts or ['__init__']
+            paths = [path]
+
+        elif parts:
+            raise ImportError("Can't find %r in %s" % (parts, module))
+
+    return info
+
+
+def get_module_constant(module, symbol, default=-1, paths=None):
+    """Find 'module' by searching 'paths', and extract 'symbol'
+
+    Return 'None' if 'module' does not exist on 'paths', or it does not define
+    'symbol'.  If the module defines 'symbol' as a constant, return the
+    constant.  Otherwise, return 'default'."""
+
+    try:
+        f, path, (suffix, mode, kind) = find_module(module, paths)
+    except ImportError:
+        # Module doesn't exist
+        return None
+
+    try:
+        if kind == PY_COMPILED:
+            f.read(8)  # skip magic & date
+            code = marshal.load(f)
+        elif kind == PY_FROZEN:
+            code = imp.get_frozen_object(module)
+        elif kind == PY_SOURCE:
+            code = compile(f.read(), path, 'exec')
+        else:
+            # Not something we can parse; we'll have to import it.  :(
+            if module not in sys.modules:
+                imp.load_module(module, f, path, (suffix, mode, kind))
+            return getattr(sys.modules[module], symbol, None)
+
+    finally:
+        if f:
+            f.close()
+
+    return extract_constant(code, symbol, default)
+
+
+def extract_constant(code, symbol, default=-1):
+    """Extract the constant value of 'symbol' from 'code'
+
+    If the name 'symbol' is bound to a constant value by the Python code
+    object 'code', return that value.  If 'symbol' is bound to an expression,
+    return 'default'.  Otherwise, return 'None'.
+
+    Return value is based on the first assignment to 'symbol'.  'symbol' must
+    be a global, or at least a non-"fast" local in the code block.  That is,
+    only 'STORE_NAME' and 'STORE_GLOBAL' opcodes are checked, and 'symbol'
+    must be present in 'code.co_names'.
+    """
+    if symbol not in code.co_names:
+        # name's not there, can't possibly be an assignment
+        return None
+
+    name_idx = list(code.co_names).index(symbol)
+
+    STORE_NAME = 90
+    STORE_GLOBAL = 97
+    LOAD_CONST = 100
+
+    const = default
+
+    for byte_code in Bytecode(code):
+        op = byte_code.opcode
+        arg = byte_code.arg
+
+        if op == LOAD_CONST:
+            const = code.co_consts[arg]
+        elif arg == name_idx and (op == STORE_NAME or op == STORE_GLOBAL):
+            return const
+        else:
+            const = default
+
+
+def _update_globals():
+    """
+    Patch the globals to remove the objects not available on some platforms.
+
+    XXX it'd be better to test assertions about bytecode instead.
+    """
+
+    if not sys.platform.startswith('java') and sys.platform != 'cli':
+        return
+    incompatible = 'extract_constant', 'get_module_constant'
+    for name in incompatible:
+        del globals()[name]
+        __all__.remove(name)
+
+
+_update_globals()
diff --git a/vendor/setuptools-39.0.1/setuptools/dist.py b/vendor/setuptools-39.0.1/setuptools/dist.py
new file mode 100644
index 00000000..284d922d
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/dist.py
@@ -0,0 +1,1070 @@
+# -*- coding: utf-8 -*-
+__all__ = ['Distribution']
+
+import re
+import os
+import warnings
+import numbers
+import distutils.log
+import distutils.core
+import distutils.cmd
+import distutils.dist
+import itertools
+from collections import defaultdict
+from distutils.errors import (
+    DistutilsOptionError, DistutilsPlatformError, DistutilsSetupError,
+)
+from distutils.util import rfc822_escape
+from distutils.version import StrictVersion
+
+from setuptools.extern import six
+from setuptools.extern import packaging
+from setuptools.extern.six.moves import map, filter, filterfalse
+
+from setuptools.depends import Require
+from setuptools import windows_support
+from setuptools.monkey import get_unpatched
+from setuptools.config import parse_configuration
+import pkg_resources
+from .py36compat import Distribution_parse_config_files
+
+__import__('setuptools.extern.packaging.specifiers')
+__import__('setuptools.extern.packaging.version')
+
+
+def _get_unpatched(cls):
+    warnings.warn("Do not call this function", DeprecationWarning)
+    return get_unpatched(cls)
+
+
+def get_metadata_version(dist_md):
+    if dist_md.long_description_content_type or dist_md.provides_extras:
+        return StrictVersion('2.1')
+    elif (dist_md.maintainer is not None or
+          dist_md.maintainer_email is not None or
+          getattr(dist_md, 'python_requires', None) is not None):
+        return StrictVersion('1.2')
+    elif (dist_md.provides or dist_md.requires or dist_md.obsoletes or
+            dist_md.classifiers or dist_md.download_url):
+        return StrictVersion('1.1')
+
+    return StrictVersion('1.0')
+
+
+# Based on Python 3.5 version
+def write_pkg_file(self, file):
+    """Write the PKG-INFO format data to a file object.
+    """
+    version = get_metadata_version(self)
+
+    file.write('Metadata-Version: %s\n' % version)
+    file.write('Name: %s\n' % self.get_name())
+    file.write('Version: %s\n' % self.get_version())
+    file.write('Summary: %s\n' % self.get_description())
+    file.write('Home-page: %s\n' % self.get_url())
+
+    if version < StrictVersion('1.2'):
+        file.write('Author: %s\n' % self.get_contact())
+        file.write('Author-email: %s\n' % self.get_contact_email())
+    else:
+        optional_fields = (
+            ('Author', 'author'),
+            ('Author-email', 'author_email'),
+            ('Maintainer', 'maintainer'),
+            ('Maintainer-email', 'maintainer_email'),
+        )
+
+        for field, attr in optional_fields:
+            attr_val = getattr(self, attr)
+            if six.PY2:
+                attr_val = self._encode_field(attr_val)
+
+            if attr_val is not None:
+                file.write('%s: %s\n' % (field, attr_val))
+
+    file.write('License: %s\n' % self.get_license())
+    if self.download_url:
+        file.write('Download-URL: %s\n' % self.download_url)
+    for project_url in self.project_urls.items():
+        file.write('Project-URL: %s, %s\n' % project_url)
+
+    long_desc = rfc822_escape(self.get_long_description())
+    file.write('Description: %s\n' % long_desc)
+
+    keywords = ','.join(self.get_keywords())
+    if keywords:
+        file.write('Keywords: %s\n' % keywords)
+
+    if version >= StrictVersion('1.2'):
+        for platform in self.get_platforms():
+            file.write('Platform: %s\n' % platform)
+    else:
+        self._write_list(file, 'Platform', self.get_platforms())
+
+    self._write_list(file, 'Classifier', self.get_classifiers())
+
+    # PEP 314
+    self._write_list(file, 'Requires', self.get_requires())
+    self._write_list(file, 'Provides', self.get_provides())
+    self._write_list(file, 'Obsoletes', self.get_obsoletes())
+
+    # Setuptools specific for PEP 345
+    if hasattr(self, 'python_requires'):
+        file.write('Requires-Python: %s\n' % self.python_requires)
+
+    # PEP 566
+    if self.long_description_content_type:
+        file.write(
+            'Description-Content-Type: %s\n' %
+            self.long_description_content_type
+        )
+    if self.provides_extras:
+        for extra in self.provides_extras:
+            file.write('Provides-Extra: %s\n' % extra)
+
+
+# from Python 3.4
+def write_pkg_info(self, base_dir):
+    """Write the PKG-INFO file into the release tree.
+    """
+    with open(os.path.join(base_dir, 'PKG-INFO'), 'w',
+              encoding='UTF-8') as pkg_info:
+        self.write_pkg_file(pkg_info)
+
+
+sequence = tuple, list
+
+
+def check_importable(dist, attr, value):
+    try:
+        ep = pkg_resources.EntryPoint.parse('x=' + value)
+        assert not ep.extras
+    except (TypeError, ValueError, AttributeError, AssertionError):
+        raise DistutilsSetupError(
+            "%r must be importable 'module:attrs' string (got %r)"
+            % (attr, value)
+        )
+
+
+def assert_string_list(dist, attr, value):
+    """Verify that value is a string list or None"""
+    try:
+        assert ''.join(value) != value
+    except (TypeError, ValueError, AttributeError, AssertionError):
+        raise DistutilsSetupError(
+            "%r must be a list of strings (got %r)" % (attr, value)
+        )
+
+
+def check_nsp(dist, attr, value):
+    """Verify that namespace packages are valid"""
+    ns_packages = value
+    assert_string_list(dist, attr, ns_packages)
+    for nsp in ns_packages:
+        if not dist.has_contents_for(nsp):
+            raise DistutilsSetupError(
+                "Distribution contains no modules or packages for " +
+                "namespace package %r" % nsp
+            )
+        parent, sep, child = nsp.rpartition('.')
+        if parent and parent not in ns_packages:
+            distutils.log.warn(
+                "WARNING: %r is declared as a package namespace, but %r"
+                " is not: please correct this in setup.py", nsp, parent
+            )
+
+
+def check_extras(dist, attr, value):
+    """Verify that extras_require mapping is valid"""
+    try:
+        list(itertools.starmap(_check_extra, value.items()))
+    except (TypeError, ValueError, AttributeError):
+        raise DistutilsSetupError(
+            "'extras_require' must be a dictionary whose values are "
+            "strings or lists of strings containing valid project/version "
+            "requirement specifiers."
+        )
+
+
+def _check_extra(extra, reqs):
+    name, sep, marker = extra.partition(':')
+    if marker and pkg_resources.invalid_marker(marker):
+        raise DistutilsSetupError("Invalid environment marker: " + marker)
+    list(pkg_resources.parse_requirements(reqs))
+
+
+def assert_bool(dist, attr, value):
+    """Verify that value is True, False, 0, or 1"""
+    if bool(value) != value:
+        tmpl = "{attr!r} must be a boolean value (got {value!r})"
+        raise DistutilsSetupError(tmpl.format(attr=attr, value=value))
+
+
+def check_requirements(dist, attr, value):
+    """Verify that install_requires is a valid requirements list"""
+    try:
+        list(pkg_resources.parse_requirements(value))
+        if isinstance(value, (dict, set)):
+            raise TypeError("Unordered types are not allowed")
+    except (TypeError, ValueError) as error:
+        tmpl = (
+            "{attr!r} must be a string or list of strings "
+            "containing valid project/version requirement specifiers; {error}"
+        )
+        raise DistutilsSetupError(tmpl.format(attr=attr, error=error))
+
+
+def check_specifier(dist, attr, value):
+    """Verify that value is a valid version specifier"""
+    try:
+        packaging.specifiers.SpecifierSet(value)
+    except packaging.specifiers.InvalidSpecifier as error:
+        tmpl = (
+            "{attr!r} must be a string "
+            "containing valid version specifiers; {error}"
+        )
+        raise DistutilsSetupError(tmpl.format(attr=attr, error=error))
+
+
+def check_entry_points(dist, attr, value):
+    """Verify that entry_points map is parseable"""
+    try:
+        pkg_resources.EntryPoint.parse_map(value)
+    except ValueError as e:
+        raise DistutilsSetupError(e)
+
+
+def check_test_suite(dist, attr, value):
+    if not isinstance(value, six.string_types):
+        raise DistutilsSetupError("test_suite must be a string")
+
+
+def check_package_data(dist, attr, value):
+    """Verify that value is a dictionary of package names to glob lists"""
+    if isinstance(value, dict):
+        for k, v in value.items():
+            if not isinstance(k, str):
+                break
+            try:
+                iter(v)
+            except TypeError:
+                break
+        else:
+            return
+    raise DistutilsSetupError(
+        attr + " must be a dictionary mapping package names to lists of "
+        "wildcard patterns"
+    )
+
+
+def check_packages(dist, attr, value):
+    for pkgname in value:
+        if not re.match(r'\w+(\.\w+)*', pkgname):
+            distutils.log.warn(
+                "WARNING: %r not a valid package name; please use only "
+                ".-separated package names in setup.py", pkgname
+            )
+
+
+_Distribution = get_unpatched(distutils.core.Distribution)
+
+
+class Distribution(Distribution_parse_config_files, _Distribution):
+    """Distribution with support for features, tests, and package data
+
+    This is an enhanced version of 'distutils.dist.Distribution' that
+    effectively adds the following new optional keyword arguments to 'setup()':
+
+     'install_requires' -- a string or sequence of strings specifying project
+        versions that the distribution requires when installed, in the format
+        used by 'pkg_resources.require()'.  They will be installed
+        automatically when the package is installed.  If you wish to use
+        packages that are not available in PyPI, or want to give your users an
+        alternate download location, you can add a 'find_links' option to the
+        '[easy_install]' section of your project's 'setup.cfg' file, and then
+        setuptools will scan the listed web pages for links that satisfy the
+        requirements.
+
+     'extras_require' -- a dictionary mapping names of optional "extras" to the
+        additional requirement(s) that using those extras incurs. For example,
+        this::
+
+            extras_require = dict(reST = ["docutils>=0.3", "reSTedit"])
+
+        indicates that the distribution can optionally provide an extra
+        capability called "reST", but it can only be used if docutils and
+        reSTedit are installed.  If the user installs your package using
+        EasyInstall and requests one of your extras, the corresponding
+        additional requirements will be installed if needed.
+
+     'features' **deprecated** -- a dictionary mapping option names to
+        'setuptools.Feature'
+        objects.  Features are a portion of the distribution that can be
+        included or excluded based on user options, inter-feature dependencies,
+        and availability on the current system.  Excluded features are omitted
+        from all setup commands, including source and binary distributions, so
+        you can create multiple distributions from the same source tree.
+        Feature names should be valid Python identifiers, except that they may
+        contain the '-' (minus) sign.  Features can be included or excluded
+        via the command line options '--with-X' and '--without-X', where 'X' is
+        the name of the feature.  Whether a feature is included by default, and
+        whether you are allowed to control this from the command line, is
+        determined by the Feature object.  See the 'Feature' class for more
+        information.
+
+     'test_suite' -- the name of a test suite to run for the 'test' command.
+        If the user runs 'python setup.py test', the package will be installed,
+        and the named test suite will be run.  The format is the same as
+        would be used on a 'unittest.py' command line.  That is, it is the
+        dotted name of an object to import and call to generate a test suite.
+
+     'package_data' -- a dictionary mapping package names to lists of filenames
+        or globs to use to find data files contained in the named packages.
+        If the dictionary has filenames or globs listed under '""' (the empty
+        string), those names will be searched for in every package, in addition
+        to any names for the specific package.  Data files found using these
+        names/globs will be installed along with the package, in the same
+        location as the package.  Note that globs are allowed to reference
+        the contents of non-package subdirectories, as long as you use '/' as
+        a path separator.  (Globs are automatically converted to
+        platform-specific paths at runtime.)
+
+    In addition to these new keywords, this class also has several new methods
+    for manipulating the distribution's contents.  For example, the 'include()'
+    and 'exclude()' methods can be thought of as in-place add and subtract
+    commands that add or remove packages, modules, extensions, and so on from
+    the distribution.  They are used by the feature subsystem to configure the
+    distribution for the included and excluded features.
+    """
+
+    _patched_dist = None
+
+    def patch_missing_pkg_info(self, attrs):
+        # Fake up a replacement for the data that would normally come from
+        # PKG-INFO, but which might not yet be built if this is a fresh
+        # checkout.
+        #
+        if not attrs or 'name' not in attrs or 'version' not in attrs:
+            return
+        key = pkg_resources.safe_name(str(attrs['name'])).lower()
+        dist = pkg_resources.working_set.by_key.get(key)
+        if dist is not None and not dist.has_metadata('PKG-INFO'):
+            dist._version = pkg_resources.safe_version(str(attrs['version']))
+            self._patched_dist = dist
+
+    def __init__(self, attrs=None):
+        have_package_data = hasattr(self, "package_data")
+        if not have_package_data:
+            self.package_data = {}
+        attrs = attrs or {}
+        if 'features' in attrs or 'require_features' in attrs:
+            Feature.warn_deprecated()
+        self.require_features = []
+        self.features = {}
+        self.dist_files = []
+        self.src_root = attrs.pop("src_root", None)
+        self.patch_missing_pkg_info(attrs)
+        self.project_urls = attrs.get('project_urls', {})
+        self.dependency_links = attrs.pop('dependency_links', [])
+        self.setup_requires = attrs.pop('setup_requires', [])
+        for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'):
+            vars(self).setdefault(ep.name, None)
+        _Distribution.__init__(self, attrs)
+
+        # The project_urls attribute may not be supported in distutils, so
+        # prime it here from our value if not automatically set
+        self.metadata.project_urls = getattr(
+            self.metadata, 'project_urls', self.project_urls)
+        self.metadata.long_description_content_type = attrs.get(
+            'long_description_content_type'
+        )
+        self.metadata.provides_extras = getattr(
+            self.metadata, 'provides_extras', set()
+        )
+
+        if isinstance(self.metadata.version, numbers.Number):
+            # Some people apparently take "version number" too literally :)
+            self.metadata.version = str(self.metadata.version)
+
+        if self.metadata.version is not None:
+            try:
+                ver = packaging.version.Version(self.metadata.version)
+                normalized_version = str(ver)
+                if self.metadata.version != normalized_version:
+                    warnings.warn(
+                        "Normalizing '%s' to '%s'" % (
+                            self.metadata.version,
+                            normalized_version,
+                        )
+                    )
+                    self.metadata.version = normalized_version
+            except (packaging.version.InvalidVersion, TypeError):
+                warnings.warn(
+                    "The version specified (%r) is an invalid version, this "
+                    "may not work as expected with newer versions of "
+                    "setuptools, pip, and PyPI. Please see PEP 440 for more "
+                    "details." % self.metadata.version
+                )
+        self._finalize_requires()
+
+    def _finalize_requires(self):
+        """
+        Set `metadata.python_requires` and fix environment markers
+        in `install_requires` and `extras_require`.
+        """
+        if getattr(self, 'python_requires', None):
+            self.metadata.python_requires = self.python_requires
+
+        if getattr(self, 'extras_require', None):
+            for extra in self.extras_require.keys():
+                # Since this gets called multiple times at points where the
+                # keys have become 'converted' extras, ensure that we are only
+                # truly adding extras we haven't seen before here.
+                extra = extra.split(':')[0]
+                if extra:
+                    self.metadata.provides_extras.add(extra)
+
+        self._convert_extras_requirements()
+        self._move_install_requirements_markers()
+
+    def _convert_extras_requirements(self):
+        """
+        Convert requirements in `extras_require` of the form
+        `"extra": ["barbazquux; {marker}"]` to
+        `"extra:{marker}": ["barbazquux"]`.
+        """
+        spec_ext_reqs = getattr(self, 'extras_require', None) or {}
+        self._tmp_extras_require = defaultdict(list)
+        for section, v in spec_ext_reqs.items():
+            # Do not strip empty sections.
+            self._tmp_extras_require[section]
+            for r in pkg_resources.parse_requirements(v):
+                suffix = self._suffix_for(r)
+                self._tmp_extras_require[section + suffix].append(r)
+
+    @staticmethod
+    def _suffix_for(req):
+        """
+        For a requirement, return the 'extras_require' suffix for
+        that requirement.
+        """
+        return ':' + str(req.marker) if req.marker else ''
+
+    def _move_install_requirements_markers(self):
+        """
+        Move requirements in `install_requires` that are using environment
+        markers `extras_require`.
+        """
+
+        # divide the install_requires into two sets, simple ones still
+        # handled by install_requires and more complex ones handled
+        # by extras_require.
+
+        def is_simple_req(req):
+            return not req.marker
+
+        spec_inst_reqs = getattr(self, 'install_requires', None) or ()
+        inst_reqs = list(pkg_resources.parse_requirements(spec_inst_reqs))
+        simple_reqs = filter(is_simple_req, inst_reqs)
+        complex_reqs = filterfalse(is_simple_req, inst_reqs)
+        self.install_requires = list(map(str, simple_reqs))
+
+        for r in complex_reqs:
+            self._tmp_extras_require[':' + str(r.marker)].append(r)
+        self.extras_require = dict(
+            (k, [str(r) for r in map(self._clean_req, v)])
+            for k, v in self._tmp_extras_require.items()
+        )
+
+    def _clean_req(self, req):
+        """
+        Given a Requirement, remove environment markers and return it.
+        """
+        req.marker = None
+        return req
+
+    def parse_config_files(self, filenames=None, ignore_option_errors=False):
+        """Parses configuration files from various levels
+        and loads configuration.
+
+        """
+        _Distribution.parse_config_files(self, filenames=filenames)
+
+        parse_configuration(self, self.command_options,
+                            ignore_option_errors=ignore_option_errors)
+        self._finalize_requires()
+
+    def parse_command_line(self):
+        """Process features after parsing command line options"""
+        result = _Distribution.parse_command_line(self)
+        if self.features:
+            self._finalize_features()
+        return result
+
+    def _feature_attrname(self, name):
+        """Convert feature name to corresponding option attribute name"""
+        return 'with_' + name.replace('-', '_')
+
+    def fetch_build_eggs(self, requires):
+        """Resolve pre-setup requirements"""
+        resolved_dists = pkg_resources.working_set.resolve(
+            pkg_resources.parse_requirements(requires),
+            installer=self.fetch_build_egg,
+            replace_conflicting=True,
+        )
+        for dist in resolved_dists:
+            pkg_resources.working_set.add(dist, replace=True)
+        return resolved_dists
+
+    def finalize_options(self):
+        _Distribution.finalize_options(self)
+        if self.features:
+            self._set_global_opts_from_features()
+
+        for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'):
+            value = getattr(self, ep.name, None)
+            if value is not None:
+                ep.require(installer=self.fetch_build_egg)
+                ep.load()(self, ep.name, value)
+        if getattr(self, 'convert_2to3_doctests', None):
+            # XXX may convert to set here when we can rely on set being builtin
+            self.convert_2to3_doctests = [
+                os.path.abspath(p)
+                for p in self.convert_2to3_doctests
+            ]
+        else:
+            self.convert_2to3_doctests = []
+
+    def get_egg_cache_dir(self):
+        egg_cache_dir = os.path.join(os.curdir, '.eggs')
+        if not os.path.exists(egg_cache_dir):
+            os.mkdir(egg_cache_dir)
+            windows_support.hide_file(egg_cache_dir)
+            readme_txt_filename = os.path.join(egg_cache_dir, 'README.txt')
+            with open(readme_txt_filename, 'w') as f:
+                f.write('This directory contains eggs that were downloaded '
+                        'by setuptools to build, test, and run plug-ins.\n\n')
+                f.write('This directory caches those eggs to prevent '
+                        'repeated downloads.\n\n')
+                f.write('However, it is safe to delete this directory.\n\n')
+
+        return egg_cache_dir
+
+    def fetch_build_egg(self, req):
+        """Fetch an egg needed for building"""
+        from setuptools.command.easy_install import easy_install
+        dist = self.__class__({'script_args': ['easy_install']})
+        opts = dist.get_option_dict('easy_install')
+        opts.clear()
+        opts.update(
+            (k, v)
+            for k, v in self.get_option_dict('easy_install').items()
+            if k in (
+                # don't use any other settings
+                'find_links', 'site_dirs', 'index_url',
+                'optimize', 'site_dirs', 'allow_hosts',
+            ))
+        if self.dependency_links:
+            links = self.dependency_links[:]
+            if 'find_links' in opts:
+                links = opts['find_links'][1] + links
+            opts['find_links'] = ('setup', links)
+        install_dir = self.get_egg_cache_dir()
+        cmd = easy_install(
+            dist, args=["x"], install_dir=install_dir,
+            exclude_scripts=True,
+            always_copy=False, build_directory=None, editable=False,
+            upgrade=False, multi_version=True, no_report=True, user=False
+        )
+        cmd.ensure_finalized()
+        return cmd.easy_install(req)
+
+    def _set_global_opts_from_features(self):
+        """Add --with-X/--without-X options based on optional features"""
+
+        go = []
+        no = self.negative_opt.copy()
+
+        for name, feature in self.features.items():
+            self._set_feature(name, None)
+            feature.validate(self)
+
+            if feature.optional:
+                descr = feature.description
+                incdef = ' (default)'
+                excdef = ''
+                if not feature.include_by_default():
+                    excdef, incdef = incdef, excdef
+
+                new = (
+                    ('with-' + name, None, 'include ' + descr + incdef),
+                    ('without-' + name, None, 'exclude ' + descr + excdef),
+                )
+                go.extend(new)
+                no['without-' + name] = 'with-' + name
+
+        self.global_options = self.feature_options = go + self.global_options
+        self.negative_opt = self.feature_negopt = no
+
+    def _finalize_features(self):
+        """Add/remove features and resolve dependencies between them"""
+
+        # First, flag all the enabled items (and thus their dependencies)
+        for name, feature in self.features.items():
+            enabled = self.feature_is_included(name)
+            if enabled or (enabled is None and feature.include_by_default()):
+                feature.include_in(self)
+                self._set_feature(name, 1)
+
+        # Then disable the rest, so that off-by-default features don't
+        # get flagged as errors when they're required by an enabled feature
+        for name, feature in self.features.items():
+            if not self.feature_is_included(name):
+                feature.exclude_from(self)
+                self._set_feature(name, 0)
+
+    def get_command_class(self, command):
+        """Pluggable version of get_command_class()"""
+        if command in self.cmdclass:
+            return self.cmdclass[command]
+
+        eps = pkg_resources.iter_entry_points('distutils.commands', command)
+        for ep in eps:
+            ep.require(installer=self.fetch_build_egg)
+            self.cmdclass[command] = cmdclass = ep.load()
+            return cmdclass
+        else:
+            return _Distribution.get_command_class(self, command)
+
+    def print_commands(self):
+        for ep in pkg_resources.iter_entry_points('distutils.commands'):
+            if ep.name not in self.cmdclass:
+                # don't require extras as the commands won't be invoked
+                cmdclass = ep.resolve()
+                self.cmdclass[ep.name] = cmdclass
+        return _Distribution.print_commands(self)
+
+    def get_command_list(self):
+        for ep in pkg_resources.iter_entry_points('distutils.commands'):
+            if ep.name not in self.cmdclass:
+                # don't require extras as the commands won't be invoked
+                cmdclass = ep.resolve()
+                self.cmdclass[ep.name] = cmdclass
+        return _Distribution.get_command_list(self)
+
+    def _set_feature(self, name, status):
+        """Set feature's inclusion status"""
+        setattr(self, self._feature_attrname(name), status)
+
+    def feature_is_included(self, name):
+        """Return 1 if feature is included, 0 if excluded, 'None' if unknown"""
+        return getattr(self, self._feature_attrname(name))
+
+    def include_feature(self, name):
+        """Request inclusion of feature named 'name'"""
+
+        if self.feature_is_included(name) == 0:
+            descr = self.features[name].description
+            raise DistutilsOptionError(
+                descr + " is required, but was excluded or is not available"
+            )
+        self.features[name].include_in(self)
+        self._set_feature(name, 1)
+
+    def include(self, **attrs):
+        """Add items to distribution that are named in keyword arguments
+
+        For example, 'dist.exclude(py_modules=["x"])' would add 'x' to
+        the distribution's 'py_modules' attribute, if it was not already
+        there.
+
+        Currently, this method only supports inclusion for attributes that are
+        lists or tuples.  If you need to add support for adding to other
+        attributes in this or a subclass, you can add an '_include_X' method,
+        where 'X' is the name of the attribute.  The method will be called with
+        the value passed to 'include()'.  So, 'dist.include(foo={"bar":"baz"})'
+        will try to call 'dist._include_foo({"bar":"baz"})', which can then
+        handle whatever special inclusion logic is needed.
+        """
+        for k, v in attrs.items():
+            include = getattr(self, '_include_' + k, None)
+            if include:
+                include(v)
+            else:
+                self._include_misc(k, v)
+
+    def exclude_package(self, package):
+        """Remove packages, modules, and extensions in named package"""
+
+        pfx = package + '.'
+        if self.packages:
+            self.packages = [
+                p for p in self.packages
+                if p != package and not p.startswith(pfx)
+            ]
+
+        if self.py_modules:
+            self.py_modules = [
+                p for p in self.py_modules
+                if p != package and not p.startswith(pfx)
+            ]
+
+        if self.ext_modules:
+            self.ext_modules = [
+                p for p in self.ext_modules
+                if p.name != package and not p.name.startswith(pfx)
+            ]
+
+    def has_contents_for(self, package):
+        """Return true if 'exclude_package(package)' would do something"""
+
+        pfx = package + '.'
+
+        for p in self.iter_distribution_names():
+            if p == package or p.startswith(pfx):
+                return True
+
+    def _exclude_misc(self, name, value):
+        """Handle 'exclude()' for list/tuple attrs without a special handler"""
+        if not isinstance(value, sequence):
+            raise DistutilsSetupError(
+                "%s: setting must be a list or tuple (%r)" % (name, value)
+            )
+        try:
+            old = getattr(self, name)
+        except AttributeError:
+            raise DistutilsSetupError(
+                "%s: No such distribution setting" % name
+            )
+        if old is not None and not isinstance(old, sequence):
+            raise DistutilsSetupError(
+                name + ": this setting cannot be changed via include/exclude"
+            )
+        elif old:
+            setattr(self, name, [item for item in old if item not in value])
+
+    def _include_misc(self, name, value):
+        """Handle 'include()' for list/tuple attrs without a special handler"""
+
+        if not isinstance(value, sequence):
+            raise DistutilsSetupError(
+                "%s: setting must be a list (%r)" % (name, value)
+            )
+        try:
+            old = getattr(self, name)
+        except AttributeError:
+            raise DistutilsSetupError(
+                "%s: No such distribution setting" % name
+            )
+        if old is None:
+            setattr(self, name, value)
+        elif not isinstance(old, sequence):
+            raise DistutilsSetupError(
+                name + ": this setting cannot be changed via include/exclude"
+            )
+        else:
+            new = [item for item in value if item not in old]
+            setattr(self, name, old + new)
+
+    def exclude(self, **attrs):
+        """Remove items from distribution that are named in keyword arguments
+
+        For example, 'dist.exclude(py_modules=["x"])' would remove 'x' from
+        the distribution's 'py_modules' attribute.  Excluding packages uses
+        the 'exclude_package()' method, so all of the package's contained
+        packages, modules, and extensions are also excluded.
+
+        Currently, this method only supports exclusion from attributes that are
+        lists or tuples.  If you need to add support for excluding from other
+        attributes in this or a subclass, you can add an '_exclude_X' method,
+        where 'X' is the name of the attribute.  The method will be called with
+        the value passed to 'exclude()'.  So, 'dist.exclude(foo={"bar":"baz"})'
+        will try to call 'dist._exclude_foo({"bar":"baz"})', which can then
+        handle whatever special exclusion logic is needed.
+        """
+        for k, v in attrs.items():
+            exclude = getattr(self, '_exclude_' + k, None)
+            if exclude:
+                exclude(v)
+            else:
+                self._exclude_misc(k, v)
+
+    def _exclude_packages(self, packages):
+        if not isinstance(packages, sequence):
+            raise DistutilsSetupError(
+                "packages: setting must be a list or tuple (%r)" % (packages,)
+            )
+        list(map(self.exclude_package, packages))
+
+    def _parse_command_opts(self, parser, args):
+        # Remove --with-X/--without-X options when processing command args
+        self.global_options = self.__class__.global_options
+        self.negative_opt = self.__class__.negative_opt
+
+        # First, expand any aliases
+        command = args[0]
+        aliases = self.get_option_dict('aliases')
+        while command in aliases:
+            src, alias = aliases[command]
+            del aliases[command]  # ensure each alias can expand only once!
+            import shlex
+            args[:1] = shlex.split(alias, True)
+            command = args[0]
+
+        nargs = _Distribution._parse_command_opts(self, parser, args)
+
+        # Handle commands that want to consume all remaining arguments
+        cmd_class = self.get_command_class(command)
+        if getattr(cmd_class, 'command_consumes_arguments', None):
+            self.get_option_dict(command)['args'] = ("command line", nargs)
+            if nargs is not None:
+                return []
+
+        return nargs
+
+    def get_cmdline_options(self):
+        """Return a '{cmd: {opt:val}}' map of all command-line options
+
+        Option names are all long, but do not include the leading '--', and
+        contain dashes rather than underscores.  If the option doesn't take
+        an argument (e.g. '--quiet'), the 'val' is 'None'.
+
+        Note that options provided by config files are intentionally excluded.
+        """
+
+        d = {}
+
+        for cmd, opts in self.command_options.items():
+
+            for opt, (src, val) in opts.items():
+
+                if src != "command line":
+                    continue
+
+                opt = opt.replace('_', '-')
+
+                if val == 0:
+                    cmdobj = self.get_command_obj(cmd)
+                    neg_opt = self.negative_opt.copy()
+                    neg_opt.update(getattr(cmdobj, 'negative_opt', {}))
+                    for neg, pos in neg_opt.items():
+                        if pos == opt:
+                            opt = neg
+                            val = None
+                            break
+                    else:
+                        raise AssertionError("Shouldn't be able to get here")
+
+                elif val == 1:
+                    val = None
+
+                d.setdefault(cmd, {})[opt] = val
+
+        return d
+
+    def iter_distribution_names(self):
+        """Yield all packages, modules, and extension names in distribution"""
+
+        for pkg in self.packages or ():
+            yield pkg
+
+        for module in self.py_modules or ():
+            yield module
+
+        for ext in self.ext_modules or ():
+            if isinstance(ext, tuple):
+                name, buildinfo = ext
+            else:
+                name = ext.name
+            if name.endswith('module'):
+                name = name[:-6]
+            yield name
+
+    def handle_display_options(self, option_order):
+        """If there were any non-global "display-only" options
+        (--help-commands or the metadata display options) on the command
+        line, display the requested info and return true; else return
+        false.
+        """
+        import sys
+
+        if six.PY2 or self.help_commands:
+            return _Distribution.handle_display_options(self, option_order)
+
+        # Stdout may be StringIO (e.g. in tests)
+        import io
+        if not isinstance(sys.stdout, io.TextIOWrapper):
+            return _Distribution.handle_display_options(self, option_order)
+
+        # Don't wrap stdout if utf-8 is already the encoding. Provides
+        #  workaround for #334.
+        if sys.stdout.encoding.lower() in ('utf-8', 'utf8'):
+            return _Distribution.handle_display_options(self, option_order)
+
+        # Print metadata in UTF-8 no matter the platform
+        encoding = sys.stdout.encoding
+        errors = sys.stdout.errors
+        newline = sys.platform != 'win32' and '\n' or None
+        line_buffering = sys.stdout.line_buffering
+
+        sys.stdout = io.TextIOWrapper(
+            sys.stdout.detach(), 'utf-8', errors, newline, line_buffering)
+        try:
+            return _Distribution.handle_display_options(self, option_order)
+        finally:
+            sys.stdout = io.TextIOWrapper(
+                sys.stdout.detach(), encoding, errors, newline, line_buffering)
+
+
+class Feature:
+    """
+    **deprecated** -- The `Feature` facility was never completely implemented
+    or supported, `has reported issues
+    <https://github.com/pypa/setuptools/issues/58>`_ and will be removed in
+    a future version.
+
+    A subset of the distribution that can be excluded if unneeded/wanted
+
+    Features are created using these keyword arguments:
+
+      'description' -- a short, human readable description of the feature, to
+         be used in error messages, and option help messages.
+
+      'standard' -- if true, the feature is included by default if it is
+         available on the current system.  Otherwise, the feature is only
+         included if requested via a command line '--with-X' option, or if
+         another included feature requires it.  The default setting is 'False'.
+
+      'available' -- if true, the feature is available for installation on the
+         current system.  The default setting is 'True'.
+
+      'optional' -- if true, the feature's inclusion can be controlled from the
+         command line, using the '--with-X' or '--without-X' options.  If
+         false, the feature's inclusion status is determined automatically,
+         based on 'availabile', 'standard', and whether any other feature
+         requires it.  The default setting is 'True'.
+
+      'require_features' -- a string or sequence of strings naming features
+         that should also be included if this feature is included.  Defaults to
+         empty list.  May also contain 'Require' objects that should be
+         added/removed from the distribution.
+
+      'remove' -- a string or list of strings naming packages to be removed
+         from the distribution if this feature is *not* included.  If the
+         feature *is* included, this argument is ignored.  This argument exists
+         to support removing features that "crosscut" a distribution, such as
+         defining a 'tests' feature that removes all the 'tests' subpackages
+         provided by other features.  The default for this argument is an empty
+         list.  (Note: the named package(s) or modules must exist in the base
+         distribution when the 'setup()' function is initially called.)
+
+      other keywords -- any other keyword arguments are saved, and passed to
+         the distribution's 'include()' and 'exclude()' methods when the
+         feature is included or excluded, respectively.  So, for example, you
+         could pass 'packages=["a","b"]' to cause packages 'a' and 'b' to be
+         added or removed from the distribution as appropriate.
+
+    A feature must include at least one 'requires', 'remove', or other
+    keyword argument.  Otherwise, it can't affect the distribution in any way.
+    Note also that you can subclass 'Feature' to create your own specialized
+    feature types that modify the distribution in other ways when included or
+    excluded.  See the docstrings for the various methods here for more detail.
+    Aside from the methods, the only feature attributes that distributions look
+    at are 'description' and 'optional'.
+    """
+
+    @staticmethod
+    def warn_deprecated():
+        msg = (
+            "Features are deprecated and will be removed in a future "
+            "version. See https://github.com/pypa/setuptools/issues/65."
+        )
+        warnings.warn(msg, DeprecationWarning, stacklevel=3)
+
+    def __init__(
+            self, description, standard=False, available=True,
+            optional=True, require_features=(), remove=(), **extras):
+        self.warn_deprecated()
+
+        self.description = description
+        self.standard = standard
+        self.available = available
+        self.optional = optional
+        if isinstance(require_features, (str, Require)):
+            require_features = require_features,
+
+        self.require_features = [
+            r for r in require_features if isinstance(r, str)
+        ]
+        er = [r for r in require_features if not isinstance(r, str)]
+        if er:
+            extras['require_features'] = er
+
+        if isinstance(remove, str):
+            remove = remove,
+        self.remove = remove
+        self.extras = extras
+
+        if not remove and not require_features and not extras:
+            raise DistutilsSetupError(
+                "Feature %s: must define 'require_features', 'remove', or "
+                "at least one of 'packages', 'py_modules', etc."
+            )
+
+    def include_by_default(self):
+        """Should this feature be included by default?"""
+        return self.available and self.standard
+
+    def include_in(self, dist):
+        """Ensure feature and its requirements are included in distribution
+
+        You may override this in a subclass to perform additional operations on
+        the distribution.  Note that this method may be called more than once
+        per feature, and so should be idempotent.
+
+        """
+
+        if not self.available:
+            raise DistutilsPlatformError(
+                self.description + " is required, "
+                "but is not available on this platform"
+            )
+
+        dist.include(**self.extras)
+
+        for f in self.require_features:
+            dist.include_feature(f)
+
+    def exclude_from(self, dist):
+        """Ensure feature is excluded from distribution
+
+        You may override this in a subclass to perform additional operations on
+        the distribution.  This method will be called at most once per
+        feature, and only after all included features have been asked to
+        include themselves.
+        """
+
+        dist.exclude(**self.extras)
+
+        if self.remove:
+            for item in self.remove:
+                dist.exclude_package(item)
+
+    def validate(self, dist):
+        """Verify that feature makes sense in context of distribution
+
+        This method is called by the distribution just before it parses its
+        command line.  It checks to ensure that the 'remove' attribute, if any,
+        contains only valid package/module names that are present in the base
+        distribution when 'setup()' is called.  You may override it in a
+        subclass to perform any other required validation of the feature
+        against a target distribution.
+        """
+
+        for item in self.remove:
+            if not dist.has_contents_for(item):
+                raise DistutilsSetupError(
+                    "%s wants to be able to remove %s, but the distribution"
+                    " doesn't contain any packages or modules under %s"
+                    % (self.description, item, item)
+                )
diff --git a/vendor/setuptools-39.0.1/setuptools/extension.py b/vendor/setuptools-39.0.1/setuptools/extension.py
new file mode 100644
index 00000000..29468894
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/extension.py
@@ -0,0 +1,57 @@
+import re
+import functools
+import distutils.core
+import distutils.errors
+import distutils.extension
+
+from setuptools.extern.six.moves import map
+
+from .monkey import get_unpatched
+
+
+def _have_cython():
+    """
+    Return True if Cython can be imported.
+    """
+    cython_impl = 'Cython.Distutils.build_ext'
+    try:
+        # from (cython_impl) import build_ext
+        __import__(cython_impl, fromlist=['build_ext']).build_ext
+        return True
+    except Exception:
+        pass
+    return False
+
+
+# for compatibility
+have_pyrex = _have_cython
+
+_Extension = get_unpatched(distutils.core.Extension)
+
+
+class Extension(_Extension):
+    """Extension that uses '.c' files in place of '.pyx' files"""
+
+    def __init__(self, name, sources, *args, **kw):
+        # The *args is needed for compatibility as calls may use positional
+        # arguments. py_limited_api may be set only via keyword.
+        self.py_limited_api = kw.pop("py_limited_api", False)
+        _Extension.__init__(self, name, sources, *args, **kw)
+
+    def _convert_pyx_sources_to_lang(self):
+        """
+        Replace sources with .pyx extensions to sources with the target
+        language extension. This mechanism allows language authors to supply
+        pre-converted sources but to prefer the .pyx sources.
+        """
+        if _have_cython():
+            # the build has Cython, so allow it to compile the .pyx files
+            return
+        lang = self.language or ''
+        target_ext = '.cpp' if lang.lower() == 'c++' else '.c'
+        sub = functools.partial(re.sub, '.pyx$', target_ext)
+        self.sources = list(map(sub, self.sources))
+
+
+class Library(Extension):
+    """Just like a regular Extension, but built as a library instead"""
diff --git a/vendor/setuptools-39.0.1/setuptools/extern/__init__.py b/vendor/setuptools-39.0.1/setuptools/extern/__init__.py
new file mode 100644
index 00000000..da3d668d
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/extern/__init__.py
@@ -0,0 +1,73 @@
+import sys
+
+
+class VendorImporter:
+    """
+    A PEP 302 meta path importer for finding optionally-vendored
+    or otherwise naturally-installed packages from root_name.
+    """
+
+    def __init__(self, root_name, vendored_names=(), vendor_pkg=None):
+        self.root_name = root_name
+        self.vendored_names = set(vendored_names)
+        self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor')
+
+    @property
+    def search_path(self):
+        """
+        Search first the vendor package then as a natural package.
+        """
+        yield self.vendor_pkg + '.'
+        yield ''
+
+    def find_module(self, fullname, path=None):
+        """
+        Return self when fullname starts with root_name and the
+        target module is one vendored through this importer.
+        """
+        root, base, target = fullname.partition(self.root_name + '.')
+        if root:
+            return
+        if not any(map(target.startswith, self.vendored_names)):
+            return
+        return self
+
+    def load_module(self, fullname):
+        """
+        Iterate over the search path to locate and load fullname.
+        """
+        root, base, target = fullname.partition(self.root_name + '.')
+        for prefix in self.search_path:
+            try:
+                extant = prefix + target
+                __import__(extant)
+                mod = sys.modules[extant]
+                sys.modules[fullname] = mod
+                # mysterious hack:
+                # Remove the reference to the extant package/module
+                # on later Python versions to cause relative imports
+                # in the vendor package to resolve the same modules
+                # as those going through this importer.
+                if sys.version_info > (3, 3):
+                    del sys.modules[extant]
+                return mod
+            except ImportError:
+                pass
+        else:
+            raise ImportError(
+                "The '{target}' package is required; "
+                "normally this is bundled with this package so if you get "
+                "this warning, consult the packager of your "
+                "distribution.".format(**locals())
+            )
+
+    def install(self):
+        """
+        Install this importer into sys.meta_path if not already present.
+        """
+        if self not in sys.meta_path:
+            sys.meta_path.append(self)
+
+
+names = 'six', 'packaging', 'pyparsing',
+VendorImporter(__name__, names, 'setuptools._vendor').install()
diff --git a/vendor/setuptools-39.0.1/setuptools/glibc.py b/vendor/setuptools-39.0.1/setuptools/glibc.py
new file mode 100644
index 00000000..a134591c
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/glibc.py
@@ -0,0 +1,86 @@
+# This file originally from pip:
+# https://github.com/pypa/pip/blob/8f4f15a5a95d7d5b511ceaee9ed261176c181970/src/pip/_internal/utils/glibc.py
+from __future__ import absolute_import
+
+import ctypes
+import re
+import warnings
+
+
+def glibc_version_string():
+    "Returns glibc version string, or None if not using glibc."
+
+    # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
+    # manpage says, "If filename is NULL, then the returned handle is for the
+    # main program". This way we can let the linker do the work to figure out
+    # which libc our process is actually using.
+    process_namespace = ctypes.CDLL(None)
+    try:
+        gnu_get_libc_version = process_namespace.gnu_get_libc_version
+    except AttributeError:
+        # Symbol doesn't exist -> therefore, we are not linked to
+        # glibc.
+        return None
+
+    # Call gnu_get_libc_version, which returns a string like "2.5"
+    gnu_get_libc_version.restype = ctypes.c_char_p
+    version_str = gnu_get_libc_version()
+    # py2 / py3 compatibility:
+    if not isinstance(version_str, str):
+        version_str = version_str.decode("ascii")
+
+    return version_str
+
+
+# Separated out from have_compatible_glibc for easier unit testing
+def check_glibc_version(version_str, required_major, minimum_minor):
+    # Parse string and check against requested version.
+    #
+    # We use a regexp instead of str.split because we want to discard any
+    # random junk that might come after the minor version -- this might happen
+    # in patched/forked versions of glibc (e.g. Linaro's version of glibc
+    # uses version strings like "2.20-2014.11"). See gh-3588.
+    m = re.match(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)", version_str)
+    if not m:
+        warnings.warn("Expected glibc version with 2 components major.minor,"
+                      " got: %s" % version_str, RuntimeWarning)
+        return False
+    return (int(m.group("major")) == required_major and
+            int(m.group("minor")) >= minimum_minor)
+
+
+def have_compatible_glibc(required_major, minimum_minor):
+    version_str = glibc_version_string()
+    if version_str is None:
+        return False
+    return check_glibc_version(version_str, required_major, minimum_minor)
+
+
+# platform.libc_ver regularly returns completely nonsensical glibc
+# versions. E.g. on my computer, platform says:
+#
+#   ~$ python2.7 -c 'import platform; print(platform.libc_ver())'
+#   ('glibc', '2.7')
+#   ~$ python3.5 -c 'import platform; print(platform.libc_ver())'
+#   ('glibc', '2.9')
+#
+# But the truth is:
+#
+#   ~$ ldd --version
+#   ldd (Debian GLIBC 2.22-11) 2.22
+#
+# This is unfortunate, because it means that the linehaul data on libc
+# versions that was generated by pip 8.1.2 and earlier is useless and
+# misleading. Solution: instead of using platform, use our code that actually
+# works.
+def libc_ver():
+    """Try to determine the glibc version
+
+    Returns a tuple of strings (lib, version) which default to empty strings
+    in case the lookup fails.
+    """
+    glibc_version = glibc_version_string()
+    if glibc_version is None:
+        return ("", "")
+    else:
+        return ("glibc", glibc_version)
diff --git a/vendor/setuptools-39.0.1/setuptools/glob.py b/vendor/setuptools-39.0.1/setuptools/glob.py
new file mode 100644
index 00000000..6c781de3
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/glob.py
@@ -0,0 +1,176 @@
+"""
+Filename globbing utility. Mostly a copy of `glob` from Python 3.5.
+
+Changes include:
+ * `yield from` and PEP3102 `*` removed.
+ * `bytes` changed to `six.binary_type`.
+ * Hidden files are not ignored.
+"""
+
+import os
+import re
+import fnmatch
+from setuptools.extern.six import binary_type
+
+__all__ = ["glob", "iglob", "escape"]
+
+
+def glob(pathname, recursive=False):
+    """Return a list of paths matching a pathname pattern.
+
+    The pattern may contain simple shell-style wildcards a la
+    fnmatch. However, unlike fnmatch, filenames starting with a
+    dot are special cases that are not matched by '*' and '?'
+    patterns.
+
+    If recursive is true, the pattern '**' will match any files and
+    zero or more directories and subdirectories.
+    """
+    return list(iglob(pathname, recursive=recursive))
+
+
+def iglob(pathname, recursive=False):
+    """Return an iterator which yields the paths matching a pathname pattern.
+
+    The pattern may contain simple shell-style wildcards a la
+    fnmatch. However, unlike fnmatch, filenames starting with a
+    dot are special cases that are not matched by '*' and '?'
+    patterns.
+
+    If recursive is true, the pattern '**' will match any files and
+    zero or more directories and subdirectories.
+    """
+    it = _iglob(pathname, recursive)
+    if recursive and _isrecursive(pathname):
+        s = next(it)  # skip empty string
+        assert not s
+    return it
+
+
+def _iglob(pathname, recursive):
+    dirname, basename = os.path.split(pathname)
+    if not has_magic(pathname):
+        if basename:
+            if os.path.lexists(pathname):
+                yield pathname
+        else:
+            # Patterns ending with a slash should match only directories
+            if os.path.isdir(dirname):
+                yield pathname
+        return
+    if not dirname:
+        if recursive and _isrecursive(basename):
+            for x in glob2(dirname, basename):
+                yield x
+        else:
+            for x in glob1(dirname, basename):
+                yield x
+        return
+    # `os.path.split()` returns the argument itself as a dirname if it is a
+    # drive or UNC path.  Prevent an infinite recursion if a drive or UNC path
+    # contains magic characters (i.e. r'\\?\C:').
+    if dirname != pathname and has_magic(dirname):
+        dirs = _iglob(dirname, recursive)
+    else:
+        dirs = [dirname]
+    if has_magic(basename):
+        if recursive and _isrecursive(basename):
+            glob_in_dir = glob2
+        else:
+            glob_in_dir = glob1
+    else:
+        glob_in_dir = glob0
+    for dirname in dirs:
+        for name in glob_in_dir(dirname, basename):
+            yield os.path.join(dirname, name)
+
+
+# These 2 helper functions non-recursively glob inside a literal directory.
+# They return a list of basenames. `glob1` accepts a pattern while `glob0`
+# takes a literal basename (so it only has to check for its existence).
+
+
+def glob1(dirname, pattern):
+    if not dirname:
+        if isinstance(pattern, binary_type):
+            dirname = os.curdir.encode('ASCII')
+        else:
+            dirname = os.curdir
+    try:
+        names = os.listdir(dirname)
+    except OSError:
+        return []
+    return fnmatch.filter(names, pattern)
+
+
+def glob0(dirname, basename):
+    if not basename:
+        # `os.path.split()` returns an empty basename for paths ending with a
+        # directory separator.  'q*x/' should match only directories.
+        if os.path.isdir(dirname):
+            return [basename]
+    else:
+        if os.path.lexists(os.path.join(dirname, basename)):
+            return [basename]
+    return []
+
+
+# This helper function recursively yields relative pathnames inside a literal
+# directory.
+
+
+def glob2(dirname, pattern):
+    assert _isrecursive(pattern)
+    yield pattern[:0]
+    for x in _rlistdir(dirname):
+        yield x
+
+
+# Recursively yields relative pathnames inside a literal directory.
+def _rlistdir(dirname):
+    if not dirname:
+        if isinstance(dirname, binary_type):
+            dirname = binary_type(os.curdir, 'ASCII')
+        else:
+            dirname = os.curdir
+    try:
+        names = os.listdir(dirname)
+    except os.error:
+        return
+    for x in names:
+        yield x
+        path = os.path.join(dirname, x) if dirname else x
+        for y in _rlistdir(path):
+            yield os.path.join(x, y)
+
+
+magic_check = re.compile('([*?[])')
+magic_check_bytes = re.compile(b'([*?[])')
+
+
+def has_magic(s):
+    if isinstance(s, binary_type):
+        match = magic_check_bytes.search(s)
+    else:
+        match = magic_check.search(s)
+    return match is not None
+
+
+def _isrecursive(pattern):
+    if isinstance(pattern, binary_type):
+        return pattern == b'**'
+    else:
+        return pattern == '**'
+
+
+def escape(pathname):
+    """Escape all special characters.
+    """
+    # Escaping is done by wrapping any of "*?[" between square brackets.
+    # Metacharacters do not work in the drive part and shouldn't be escaped.
+    drive, pathname = os.path.splitdrive(pathname)
+    if isinstance(pathname, binary_type):
+        pathname = magic_check_bytes.sub(br'[\1]', pathname)
+    else:
+        pathname = magic_check.sub(r'[\1]', pathname)
+    return drive + pathname
diff --git a/vendor/setuptools-39.0.1/setuptools/gui-32.exe b/vendor/setuptools-39.0.1/setuptools/gui-32.exe
new file mode 100644
index 0000000000000000000000000000000000000000..f8d3509653ba8f80ca7f3aa7f95616142ba83a94
GIT binary patch
literal 65536
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

literal 0
HcmV?d00001

diff --git a/vendor/setuptools-39.0.1/setuptools/gui-64.exe b/vendor/setuptools-39.0.1/setuptools/gui-64.exe
new file mode 100644
index 0000000000000000000000000000000000000000..330c51a5dde15a0bb610a48cd0ca11770c914dae
GIT binary patch
literal 75264
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

literal 0
HcmV?d00001

diff --git a/vendor/setuptools-39.0.1/setuptools/gui.exe b/vendor/setuptools-39.0.1/setuptools/gui.exe
new file mode 100644
index 0000000000000000000000000000000000000000..f8d3509653ba8f80ca7f3aa7f95616142ba83a94
GIT binary patch
literal 65536
zcmeFae|%KMxj%k3yGc&SCTD>S1PQP}R5YmQ5=~qJi^+zl1UE)DtPsG8blp-*!#RLg
z0>QIub24npZS_`f<yJ2Gx%RfbwfBl*uV6xG0{-MjRTOJur8;p@W1&fqnDc!<b2dM)
z?S0+v>-)#|`^OhvIcH|hGc(UT^E}VYJoC(K^_@E<yCg{t{F$aC?Zcb?`Ni{pesFxw
zo%Wkt>DjE;rth;Yer@_4k$X3I);E0Tn+<n;+jI9__ucm$)$@&eJPq1?o_p`}RNPkU
z`Sy3#+;eqK&X~ef(Wh%$Pd;(of3Tsy@11*-?Gf=`u?u)lX)Iw+;(cKCl`JOSKK7sD
zeHA+<-V4}nyl=nv?g*9f_b?6yBx$kDF4=y~YKCCCB)cu!mL*9qBV~z|I{q@eUHI#w
zxZet=Nm4pR@o(rY`E3@_kcQ7q0+8}iX7L_=QKB^Wyd=#Mq5o%(=5t@`n=ZtG%HR8U
zwR+EH6(2u6f(PM6ZKcj0_0J<otFLZYbC-ITBt;MrZJ&Yn>-Zb>&yT9Ew!oxAMfl)C
z#Z+d`C?Ev=lGJ)}%Ksnx|0)G)SVf_n2-;d?f9!~MzIJJ-=wKb=iHfW2QCpC29wSNm
zA=ztsPZ<@3t`2ENV!bW?>DIbrM&c*bCbqaRzr~R~Z-r)Gl=RG-p<NO;x4P=0D?)s`
z$m_KCdCiWD6_v>}ugUHp=<&@N<(0nQZ)pc;t^f@UfdU)Xs*a2q9hEj|W&QGS`}Q+V
zaO>`-aSJ8yAtP2OBNk%M7Utt!$6gfgmQ40WtW_PKSW_r1oOg}p=vZj3XtBjwwJ#E}
zLMNCsnAlP1f|%AM?kIHMo~S5v2kZEcbEs|ZrY(iCq{N>@V-R$%P-2fEhzyjmCh@Sy
zXyr*PE_By~_)26%86IRFp<L0yrY(-_6^RN*wl=1!sbqzkNBE#Zr|)1xR)-`}qV{=I
zsuT5#vQT;fwD0ZwJO~iAMI5M-JD`zRj|c<(+4vp|@n?~!ADWe%G6eO$3}GdB)>9Ya
zkBHB1hGv2=t60ZM@2flwcy2#L^lN{0=%0Q@MjzL)ErkWFb2Ro*N07ImOt!9YmgwvP
zqh2yflmnST)@Q6JEa3kv=;e&Js^gRcx7ile@Me+Xh_`B=wJ3|47Z(=9j;P;M4jj9k
ze|zYYnyGIobV=&smWsjxVw3XZ39!ke-gcWd&f8i_T!k-^@^CA0*s%-oQ>v?$_-7%o
z(GNN8XT7J;F$I$PlNQv_oLiavAq4>E7I2dQhlE)vSn!y;BSSI+5(`L`#@q*i(+$dj
ziMR82oKzstr3NgrEei6^p%m@2rUhVv>rK-H3%XZ<_rUh;c(a2dG)%uOg$_v@w_EZo
zlu%GsR0^7TQkP%ahpqsf^)t)7t<j1g+Tx`4;LnY}eDrxiuoH=ZlK9$8(KPhsobi4M
z$psZiHuGF42=%W3b2x}s^KXwz;=hfa!6-nS00F@ZB2Rzdm-tMKM|!J2$OpkDB&e<W
zp=IqLfdhi+jGDI_IfSX1CsWBNHQ^`>)|hz?tCY-06G}<$V~#?~heoED!!4L2akG@t
z3k(cUbnpdgqwk%>`n0WAC7vv#rU2V~=4eiAwpse1#pRD3*UlGpF7&;UP%~^>-Uq9>
zqqY#gDuX1JM-HRLrTl?x<n8>L1RW6Nzt8%&-UwXtnfuqbCmh#A4k1U7-%L3c7Zx(d
zuhG+B-K2d4zoLVczO#ufnYJw*t5&k#)-NC8`0Z!%(?;tLH)1SS=)o%@p*m1Hza}bC
zH<@{EP=$nZv|K=--J~^q2RFJ=UsK7|s*{A7<k#1>>2riBOI3;<EmbyBr2Q;!)*t;6
z%bAU*;bM7n=w0Oq89^D~`RGjkug?ON9(0;MXlio>B9VN6@g>xk)TvhhOKNMSeI?sb
zNT@@qXG7GtAEH*Z*I7+?xX^=^+#cd{e*xu~c+oK%QC`k~8T1Fj`XSd4etuu)23Ly=
znHbY_evF#lbUsH*M$@PjpbB6kZlDn4%Pfry7Wc9o2a;HxjOT7A9>$Ks0zkIpxF}-P
z4%J+UwB{X!v+x4J<l9l;41|Nc`2wVB4jNck69S=U@yowNLO-xFpm5`+mK}<8p^v+1
z@>vU3b1r4SD4dNJCLBe`P~a!!^eLzUU1z9JMV04G)5v%Ur4xPh4u|g#Tc-(r0PB00
z<2OM*Q-Cajywm3kTRsx?bLZ%s;?w6_FF__SF*1GDPvs6}`fAHZ`iq5gfrnJz3GS7o
z<!S&dC^NOtiE-fBC#iZl6nPcM^GAV==(P<NR;%_=#!(%&0YabZIMPv&92tc<Zx7b+
zhXzbD$Xkg{J4C}ln^mO37mVbwG|+Ar#F^zd@x=IC!wbGLO_1QAONu%pJ?DT&$271>
zuc4jxwz7KJ_rCH-tFJ@z@NXc!Q<?yrLiCS+GL^7*>xa$m*N_NRtT_d&`a7duuH`>P
zd%}h`&|B{GYny6$%@oA-ep8*S_YbNQ*wMBx)7fGDgK2FaWZ0dLJaOehDVhGlqZp`r
z7Zz^Qt{~7!1nOpo+s>!!UDMjSGVG3o1-MTD`U{)X0)7~njK(aO!mRqVS*o4ZX4diz
z7)@AzBH#*!OwC!#-^rCEBXGL5j{ilBGX<T2fkEhQ4%vX(Kg~1H*mhHs`C@8C`##CF
zP-@@Z>RTv<qVAQ@pPBn4bWbwF*U^~CI`+^PVzL7sfQR?ISVY=gn;M0{7SlKW)I}fC
zqn9jO+3r350+pLg-%ap_Gfi*v=m#C!&(myW%O}ynm4I*oqK+MG>rZEnIJKR9see4J
z?c)sQ$RrZUz7CZ}&@|&(WWQ<q`Sr-K<@HtG)|Ku2_)JVn%I2W6B{iM@WID!(VycU$
zAsB9F=2CVh#57s7&)3s1WBcH0)V=8v_Ii;ZdYh|;kGm9nx5OzmAxm<M-r)(EdHG#_
z%&)8hSU}eM-Hj9UR#%Y!30j>6oZG7`cz^_)daDP69Az2FAzJQhYnWChD$L)$+G%bx
z&7w9mR1|a&sE6y@t-J-J@>a|Gc{fUJ9G}Xg6OuprJK#0?Jp<5bfq@`8o;q|BAqcJM
zjQ48!rGWu;JZ~<LXe=JXw;{l)2MihWpCi@?07-K~${g|I>b>4p%t2&K3ny&<l5~GV
zu3pxR9szB;9|4i-*m?a+N5i#!@8}=cRcFz$=1jfQrgz)4Ua)YNY;U8N3$K^;Kib>6
z)6|T!KS#l1EVxey4i&6w$J3D-fJnmY;zyL&4<!g*Eqe#L!`;_mM+^g_OUp(vN<5Be
z^757py~8$Cr&@$5?KKvp_9ylZ;IzB+5AEvs5img9peJqGr>M}ieC4Y4zD_DwoiJ30
z5_=SJD^>f%DnzwDB3tkBl@`9nM7`62cB()9jX5~Dm1WqE>OH3SAe#W)`7_C8+pfMB
zJFd=-^{P|*4uT0K)k$y3)D9UFllj~KNTvgXauGr@LJse7Q7R@RDA(z2H9$+ML+eE&
zl=voVrX{czY;0=zrsg&^7y3DBQcnlbCHkTK6wlSv)Ot^a>WupS(t25KWYtdJD_Ul0
zy-WLUG9529T3YX>gnVr^CFHB&()t2Q@MyPDf=8_?tuNH(m)6hH=0j$@t^Sg!YDQJ1
zuYFT*)BGE?V&5z3C3>UFt~~e`G$NV?B%)>wUwRqg;i@z=IXRJXAM6bDgMFlKS|1}*
zTJt0-&ot@>P~uYMKt_<u$P@-s+AEV2S~BKcqvp(8p=QmyT9cttF;Z={RhCTEe&@TO
zUJAU`$*i*|AeRR6H#UONQ7ve}-xCCI8I5u>iv`@icGQ&50s{!#;tR+P0W?sZB=UJS
z28Qw#@F%T&Xsr_aIZ!Op21>PA8)rgy4p7O3{6Pz%JAtoM$hIO)F4a7n)<P~(I+1mw
zsEaBknp&{}E9S9cg;s19#kgY<l_YBuq7zou(m!JkZ_XDZ4C_c<Sz6z({V6&l4AE>$
z761{^!~%XE(hS<N02PLEysfKNE<cjeOV#;(?@T_jk3@Cm;TkXqt9DZgBCHyGl8OLl
ze024loZPB+*+B-OCpyKzSXkfg%OQ2FrJZf>ewuU#=}f4+5c{H|(n(tWZhp^o;Mq!<
zRjo5}SyjYX;$XSHob{6zO6oY4v*QvB236~|OfFpmxC~b5@TKpZgpU&#G7W#1xq3O3
z<3MV!e|?(f)~nX1p%Pni43kl^-$5TcR@NVMSZL^H&<bawx`(eNaR~J2`!Iu(Y+J`C
z0zJW~Oj7XExkMpn(#4t%;~T4%mFFE*dY9bPI3TH+th!&nYyDR#lIdl<5c*6ThX%5o
z)o1{K7XrAx9cu@a7Dqi{sAWL~{fq}PRa)=Vrtpf1n0nDaYar&YVxnNp4wBU<488MS
z$Ov#F&_$zgEukIg3U&rgqrh#QfipJ&H-3{?*0{{-)2wH6CJS^m=O+bRE#HY|gu`h3
zQ11%GUd!rT@l#r+x3&A9Q9zx3!O@^49vFz58}EaJqv95q-s;fX98f>E-&ixCRksAc
zLU`VdHD75rv;+qczU;=DL2Y_V&_vjEBUm9@4-7a;8wVN=CKo8r`Ay}yo6Te;LW2km
zCg&ma6+&MnuR~}6p@HNqtG1-l;zB9z8^>xc|3Wh`P+C9Ga0W~Xtd-{^<+-e)w&b4$
z@#<dU(6x1DULnRdkk-ueAh5lYQn#C{Kar$Ow9<TkRf^br*Y%_?W&Q~$VHP)oC;9HH
zFyAJHX&yxvrvM`re?)<zG~~~V%taK#?<|y#csf;eGzCh<9i|=?_0I;xt5KQHpov;L
z0t+x44o?z#lG!W+1*D-aOo%nPp=W3UKr;w$Yf^zMxL9ud2w;v07-z$oAsD^vS<E{m
zby9@hJWyh(w=tq-N(%FBH=s4EKk!SDDm?gZ!D=Y;rpVJ_#J@uO_xbUq(@|JK0CxjG
zFWX1OhSkXt3h+-+2B}Ra*1Ku6+@(}+E7&(b;`$3RaW^!x%;!_nXlmd+RbD!!1QR4B
z_FE9rm@*gPmVoPDY0{)OI<ctVMFcMX1r<MMHnOpPqw!?iR5zQ&PgCM#k=SEs?-`A!
z4XsQ6%z?14uc40j6+x?IsGlNoi+Mf&0#Vk_Kfue#FyBrUdP=0G3VR(9^kr$|X)V1p
z(52>5nT;nQH;igvjVF^ojjTuW_pKostir4{9NA29mEyNid}uN|4TxhrlC)WdXd>FZ
z?h-VBx_toZ4Q;2-s*De{^r4;Sf;^URlfi%h+fm{Ob0O76slOabjS9;G-(|(y5k&(3
zek#h$5I=h*8r>7(VIL+i{Pd0V+%%S+M@0Bp@q8Q%5#q(@z7U^EjPS`!G$(+(`k}%-
z#O*6nN~f#>J!8|-`3^7o1-QI(ZAuFG<!BUXr|7cC9O~=~<E*93KqBxcL|`r$JUY0_
zXdKvAeWxU?Elnp|vsSWu9$wq`QH0F=+T|}~+vqdKAAFvq?^E&4-RSZjDSd_`s65hU
zRG&`TX^nKMyq3SQ0JH<6%FzP8jJTHXf?$dS7hfb2>L9cj-g!Tk8}ZggIXanNhBaH*
z%$w8Ym-akCd{i@ElJ?9)<M@uU6qL**g5q}2PGrmCpJS01uI2wm>6rRw2KnzPg>MHL
zWA%sB4CVRi!%2H|Ot>Z(icp)l{Aa9616{Nh!pveS`i2Ma03DLWEO3U&EX$~V4~xO)
zi_s8B{5_ln-a`((@w7x)Y?Ng>9x2X(W=@XB{D&Y@N&83*@i)+~?fi2zq<b^Kg`y+v
z5aP88t>nK&lp^`u!hZ&&FuC{jXb#dH{4o*tBfc6Xo9PY^qOa0PMpSJ{ZCzqsyow}p
zf%M<BWuSR#dCqtgW@LiS;}ezcXc|UfBV(CSnU7I2nZp(sTV-Ruu`=IS>A><O4X8m8
z`<KIx+&Zk48f8hn92h!L6_u+_3i0uI(7<b*=4U`~ZN8*mCh2QsDU3Y53!Q#7L%$!H
z3eB4xo3q*2<}}l$JlC3ZDhFC?g1j3YAEs5VX3xrKH#01r4Y8i&cuYB30<u}{<a<eR
z%{NgJ^vkx7hmh%A<n-49l)a-~r*D%bZ8pX)TSl^|#co#1><!+CeC5cfjpuKIoO;QX
zn!?_AW&vMA1)?e2-dwpnrP{Zj*_<|HxB9IS7{EyBwDfcxYouv%BJm`o#n}5SJ@>yy
z&-gy^>=Dmb#gmKYQSodQ&%=1~zFyPB`l*;#0}pG&_qGP<A3uSmH3t5s{m%eUQpd3P
zFA&gIum6fH1&3i4>aB!9U}cE=Aq(N(&^msURe%fvtfy@-U04P7ip72!ds&zS{&BQP
zfb0S1(?^*E(%8XXe_@jn|0by6J>q*uiPa<2GTum>1O`T;OFUo1v-y$F@r)f;V$*<6
zxxSwOBxBbhyp$c;NNYJb+cR(3rm@O_gUW%XWq<TbdY9tu#j>Q=+o~LhwQWXHG_$SW
z5jNrvBb%>H`Q9&KJunO7*<L^=h;ktBPP~l0f^>TYN%sn3?(GrjM9l7u$cB1!?on^i
zxm~?p=dyZfRh62Dm=dqUXFWmia`&ynVMq6Z;jpdSi|}><(*!Z>E*$=p)}4=V)0bCj
zv$1@#`k8GT@C_RK2^%GGo{Z!or=xEdC3Sy{6c(r8w_3+22VPE8$VUwk?|v1ZjJ?#d
z?luIe*vr0NEPYiH|0;?VH0b^(Q6Pm!7br@3K$LQ`y0q!bh+5I~<vKOL>B~(@{BERM
z?U4}bzJtJg>$C~wsYFPs)mz=A_+;Vl>b`0??CGA4aEpE3_1cuC2W)e-iRD9CL7-ID
zLCiMic?H0A0^lhkGFc%~0KX@IHA?JFdf%(WUZeMSFj1hlro{Hsd$SVTOYdb$?3Z{O
zdx;woaT2be^4!6ovG*{7T!u=A;%kW$=Y`c7EJ1>o*h`$ppM(Z)v6oxb##)uwlhE!L
zK|BbE?rM}zjMBeG`2mMsRATo-#`XSM<p+O8w<|HUP15;7)dl8RhCjKgN{Rmvqg>NL
zPiK55szNTw;(m*0{!-DMiCyRLQJA!hU8fN=;!ohIB&twBXPo+q?3dk7A=(!wGR*;f
zmH4Ab9Mw+-q9dQRF(aRtkO%#|sinU_GzQmLfG(6X%$CM}s#}Tu+JSZPpq9P+VJHV9
zPKiuBJL5!5YDD)oz~~%Qe-}8Rt@jtTDY45@HnsU*=;L2kq0UjBUo;Smkm)WFrzQsz
zaZ(FGek(>;EF>{BP3w%4xKbs_@hyu6ngw8|fTKh!qlHy>F)CtYnXuY`0oli@9KP4p
zxmNRteU+CaBSCFY-H#O=Jk~#|5j}R|7;01ZpAg)=bGW@hevqcf-LE5A?_aO{-~#Ga
zVjtqE_ur%Jcu}N(Q~CZ}jI(<Gz3O-M{`=HfdjEHn_!IcnD|)HPLK{d(>RqYcK--f`
z*$u-u^BYl7987l&tm;-akLp~@;>4P3jf|vh1&xdm!gT*1BCt>!eya-TOo@qvzBZ|e
zQ2iNDWtptbp?AvNZz7_NZTj+?+C3IKAuc7urGmA#W*FkVeLpeU9(>ulfC;|b-cb+0
z5TB6^X%<Qw>XtM(`pIQ=fw7l3m7PqEu?nW_-d^ex*@!pOr$qxsd<Oz4p)`d~h8&rq
z3ajISrYI&Ma?}RR;$;Pxhb{D=3(TWzKXJT%s9^iYO(<RUSVE)ar%J3fi`NkNI14-+
zZrV>${!Og_Ogsu`H35A(O_T{B-&NY!RG*-ckbdHk+HO0|vjjb;+l<6Mq$Ue>zCnpS
z2ekn9jv3VFG&VekjGbcGz8tU@^*K}|I^kYGwg>=6O-KB9C~8h~{7t+%<45rXFG$@q
z7euEagA%`$O73*@wt3Wii!!}!nDQtuEgDEVNO&H@L}t+dCE6duOzQXu&}83R+a_*t
z_&PR>?K`O-m-^lvX<SMec7h|`W&K*3_mnRBT55ETVuwp~p@I8^9=ez{SZ8*-mN8u*
zozTuQK_62nm3Zs64En5I#e|GLc6$(Z{nJ=O=xuZK^QFcv!65zY-K`mRLCxmeCCUAX
zz}cdX$`oRtgCQ~-dxfCh1^&upuQ!#>QA4JXT_&C#wmJUf{F~PzJ;U$!y{?@r5_;)a
ze{z;kSR(>#DXe7X%}ph+4-@QPELf`|eLpD~P<#ctkO^UZ+OJ**V<{Lc%j&ADlKD^D
zh9X7D?5ESzvDO!l)qQ}Km>9K-c6Fh+qFvOf78^LViKdv`C4?Z?Mm>D}Ux<sHrkH}T
z{bB$T9}@}U489THt;{kO)K<u$jjOAT&an#NS6e0M`$=U1ZK_mV8*knE4JHVe8aAHK
zFcU=dU^F8UI0qg3C?b`?O8zG-Foc%XW|fLW)no3Zk5>7K>T~>yb3k%G<(9(Q-eiF;
zW^X3gPV@i@BfZ3523R;XaoaM4t4g?fQV<VPLD<~ePx?Yq$D4a8z-364{**`yGcn_9
zu{VoRIR+OHmUtLIOw5N{j&^^5_Wq5TtfdgKQ-D3T*Ov2llcss3edmNCzcld*zqAN{
zPvP$i{0-pmrYrr@dVGuC5m`p7(tDsgVeD<hs`T;Hsx-BTiu$7-OpNcxSQ`%eI+Yl0
z+3uk^uu;4d&qOngC&@V-eut#XW`{q0jImkn@E1xQ{!7Pn_%B1Wq{Ba#_7PbQ<=fsy
zIk3<2>e|xA*Ok~9;<mt1D%&LHDM>8Dmc9>rVFv`@;FdHt*cs>|&PpyPe0UP`2eD=g
zvFfgbQ|!MPHa(pX@+5W&jIJDok-l1%npPJ!4WXp3E&+NLPGjwF!I|Z_iN$Cc<=?U^
znZZOzzo$!rJI}YV`NpupW2zzj{GeLXVuu9W`n0TN!|A}^<;Os!&SP2^>!5w2kEXSK
zlwqH1ZHplztSactN=M`gEK3rV&LEFnX(6w~j-W+mrHrb}^}uPE_qw+H$a{*Nr4ow8
zzFGz?FS2RJF{5dTqbb?YQR&zY>tcGecNr|O?N!1;-1-;v**su^4QMcbISfGyV8u(}
zHrJScDG^rhPt&Lre=<w&w`&dr<q@ntyCOx>8-P)A48e6~K=WdCcfqdgpaqO6I^4`F
zK}}d6kG*)cjinU7J8j5RgJojK+lx)wDSSUVPHfMn%&-B(Q)XB@^Sg$Yn#i#yh~@O~
zVsRFx43?7=Ef)2sPGY2yYNLx2@%IoSZ-cY2)IzclGvc!#BZ>GNJRx94d^Q3p^_h5&
z!jF)M8oNlT7}k16tTxu}c%&amYj-5hh}SOCB5QZV4~f@Pt>X1d63xedAT%NiI1<&4
zPEnH$n$emj7>RQLVK)z0v#L&k)I^8W+9{AF*2UBSh?;rJK)tBMPMUdlAe0b@qx*u0
zz--_|=gQGEUJdhoI6@_ud5iH05LI|VzDc?VJ|^iFrVO)~h{mtX2Rs<jUT=0GdoE?K
z@BUA8pnw8#vHWzrb`q00b^Jp8{8bHKB&t5u&yU@d8_ih;nmb;558vwB(<^{vG&k%!
zJh^pdo8AgDJAVQjA;2wTpWlrwXQZ|B#86U&mE=rW6*#udOc?ZQ44FTOV3_sr7x6ac
zpr5hbACXG@(i#&w7m{89U!rw|t_1#yx@tppqPMRN40wMVH16RhJWc`wDK%sSuvOl(
zhGtSQ23Gg1ffEq^g;!y3h5f0%X2>^&JPJgM^)vaFePM&_EvDU)I+oE9Fs07GIqHqX
z11^%P9Ja(^f5Yo6;XnHbcrS5cpTmkjM)3ePJsfM5_ylButt7FO8?^&$xs!Gcs?X>b
z2Gv#YpGi2Dv&9d&6BQ4+j6e@0KF|+?vzxumV=x1vQd_)ri+|f97U*XuQLFZPQzNv0
zA%k>}M&Ys)3L$~QjeLSY;hfdNb|6kIP96bux0l|%;oDvCM=09?jfL4?gx*}APLf3?
zdW9{Oqqf`4JW7W@2etzE<v<4eN~O!3>bQtSkrV7NztT#^ri)SK{5ncM`jbVKA(V8A
zqm5NETDO0WB>jd|L}{&4iQSGss@PZfoA}gSfE3HzR_E;{tLUXvReu=XF_)L7-vPGW
zI1T&ug(L<K(H?`(O0+|jU^^TJtCv|P+|^R7g+j>uD|W&H7y!uIhCFTlmu0not*lf@
z%PpJ;soA9gr~1Dvt?jQ$qirwINSJ_!P(z8X|80r;trDZo$YvUmPe56~N*V7}HN7l`
zUbJiFQ3s!dfm&=5g!m1pD2!1O-JKPJcN0a2?d;iL6=5p90XQYcAZI!V9BvPRgvII=
z<UY6B(l`@%0aevw=B*$-!(YX+-pB~^A0xFr>WVx{*aQ%P2W9=~sEz*<6$Ha^)DE+C
zm#>U`NgC@|U)x7%!fC|bQJSw-Fsaw?)Kw+OUnVmHjbnB*a9TIrTV@F`=E$%dDJoE{
zNHOPT@UOs6VaxZVAY)PTUsB>f>;z*ISlRduY1A6QU9eATGOKj5!%ZL9;a7P+P4oXu
zhQz9+kmfozzo;Lh`0P4(oZbabsc?{gTtRZ;^mW2kS?P?m-mmCgUm2CoWTw8v>Cs;?
zS0SUm)`78mC2JotUs5$NFlJ#(0K^R^uL<!j;BeBq>EPJpG_u$FQLQ_~`{8sI<jY~X
z5BHr6Pi{>ac%$yfJ|br?mbEn9!Zyl#plAg(29qyxaq993=Nu)WqY^=ggyWgg5_M&Y
zpdmD4((h4i*n9jYW9dMOmd~&%XK$OXUQ@bM*2V_;Erb~neJY5aoK)H<Ywq5*H0qCQ
zQlDTBhDE(`fMYf$RVHI_W!Ab<9q|m-x1tiL9m@*|+ZJFb*@nrGYKJMFZ$cZex59sk
z57?Ts@o7{px+DZaeQ6n_Tc7ur#TXrI+SG*OFI5N`C1So|&e1#bc_WmSn8P_M^})g|
z$1$5&wX$6=6p%E(_=1_WYzlEl=m6zLPhw&-Uf=4lsX2A#i8_81%m7n(SnrUx4@UAZ
zcY9Ajt`fU~Sp=zJ^Zdlf_m5UCx0nX1-JJVdD%Q-iJb55^UDP*sf=9gOB6JS+k*AQT
zX!-nE40q9~JPo6)*xcm752*{l5sA41;nJz9gLNkFi{|qz2oN^pd>1r@w}B5jB_~LP
z2GvBz@Gwye!c#g`n=Ob@$5oF-2yJ2=AEdmT4d;TyC9{qB$;>+bA$=O^jVu&HK4E_b
zWIKwTm7;yh4<KPRO`k7m<AZz#eH2?iV|fL}=dgMGu(uRi4MCOo8We<q#cTTB*m!lc
zYnk_W-xt1sb8@R+o5nBn4Yi_<{&5{~%;2!Y{U-2GeuZ7_FW^by>(lJs-b$e-^uex8
z_YNtpTlEe_{|I}9wEOK#Uk`1z=?18z#e^6*kkn=swo*x(4YhC;wXpuQ?+@x&e6FkI
z8K=b5&i4oHt`OV^Qc7$M*n^!!;^NY>CiIo+4e=k6IRn<Ccmv930T-<-f(Tk2(H%gL
zc-;vM$cPedNA?^6r)F3%teroKHnxMD`WXi>WQ{b0wsmK&RX%S`$|=X#ookhCNZGc?
zMGp@>=Fr1Wk03o((_?+&r6#oIX6-0LNq?%hiiHo%0Lbwe>-T<H1phgOUKoYuVWPo~
z>3`g2EIsFYSshpOGWKvb0B0J;;R3Pr9Ne=4_JFJCASN1ch-~a<)#uLsJH92a?)!t@
ziGq7585s9aau52IEp^!s7afJ`bq(Jt%A&4Fp#vW95D%=z4hro*uT^HX!3zQ!R7%dI
z%{YlkWf*Ybj#f5>UUqM5dusBp-*XyMDxo5XAHRVjECJKc!11LP6L%wU4tUl+zKk7)
z-t<VpU60>cbWELAvkSWx|4Lu$xv}(&QQafl&5^VedHR?41qOhCL(SzYfG{apR7rXi
zehd6DB<&$TH((+Lff_Licu&>&&Z=;Xa&GeQ02a#831Q&@0{)cwt77%-W*x#g6dew3
zZ&xR^NH?~t<D+S-N*kTZL%UFEb4F!H#*LM5&0%fuh4Pn7Qs*V@M6IPxD24&wmmBVH
zaWzk<^q1so9GjG9{ICT=o53f_1)nJAB449(Lr9zu5!nLysAyc$N}t~%!{MK@_OJlC
zA6?!e-}s6;z3KebYQD%>(2;R<WeOUO%|p=iZR1$<8+?-@XiIcP_f*iKdFp5nBjJA|
zlmE>}5E$jTfD_!&veX^B!!|{mD)!dLfiakI7!4&)nwbF?Q56J6xBCB<2Ts%>w%swm
z5p;*KBsC>VeZc1WcEMA_>6oUa+}=pE|FnRHTlYl^yFJg$z<7}J3wq`~P0uM$(zEyp
zdX_zo=h_{4hs7)BMe&;QsCcD6EMAxH6tAmx;Pv<q(p&Mu*@!*Qinn9WKD-lHQ68dr
zybA+GXS#&24gYu3$34$ZUnq5^KaFP=t<%zffe^90ScDj20k=CQY~QrpwAO8V`T>NY
z?pKA-Fd&Lp!bN`fM?ZqJfYZweK*9>n#u>pxsO*bYa7Ws&dJ+>Tb%xFz>O`IAsLm=O
zQ2QL1+O_W+C!P+B$?f~bQkVu*9G$TNH?NtfET{|e3vWV$wJOgaW^Kk+2kj|ub+&!r
z%5F<+b^ZM3KYxLSLd<UfT=e=&l(EHaYj*i>)A|w*O+oYkHMGSoBW;P+hf!CE(DpM0
z5b}`~H#WHA9D{t&+~_d#B52-Al#k5v7eFU(YjZ4}1Rw7A4d+_op8>QZP6-}Zt*%b&
z`Wy+$bBC4Z?7qXBCKR>#gNcW8=zG+2J1;>KfMPkenBcs6613dtOvDF}1+@iHGXVyL
z<Hr4%MR`xvA|0vF*LB06>yW9I-&s!VRgnTfUyT5WT@?XTEPx7$YC8f{O>dh`&23to
zF~!xgBb|y(j-~lg9wm7w2?aIp$RKhh<&KyLNYvB=$&f|G&iHAR^HX5#J#vKzvqvZ;
z5zD1q_M?eAJ^F=7o19IHb5YANY<MLV{mV(4P;D;iIM(!ur`eUXcSzDg-y01F$#zGJ
z`)Ma>aSx^JC#C#K4-ABlVk?97?-pKri`J`C^lj@Tbt2mo!F*JPJ?y@BF^sVe{vm+d
zqdEL61~0Kn00=xne8s}G?|LjIF2RCpJ-QOp0mYg#shJ`Ey|aMdO+dz?2ouoA2GDf?
z9U76r98&W8OgoJV_Ce35rr%IF@VKibjibJerNfk0;jX6-4r)_7(<um2Ksq*~ppyCl
zoHekV`;znY!LPJ&qd`=FBv0vs1LW%01JA;dkI6%n7v6XMv}w;eh8*tT?Kg^FQ|<(H
z!uJ5fYA?J@VFAy@X#PBU6VsJlKt`M*DBbrc8mq+qk&wfxq;*bN4}uLJZ#Vf@v`MiZ
zklW2}5nh9^@_Z*uFk1xWu+~LNBEW+%vXNYnNO+MXgfvlJK&!FisPOnrU~%IChq1v~
zx|Ayq^`nZW#?Mgv8we$|&s%b1aHBqmi1J(|gyl&0|3P?EF=J5-t3HilzI9{{76*x6
zKTVyaolaiaQfY&n%~GD5Pre=?SyxNb!}usy_@<yV+ah28#!oN{sH|+lH1HVu4R%J%
zg!RTQ_=25o=w_Wjt+Sj~N)rDjW|z?nquiM&cO{I+QO=!f*|iJT8gmx<{kLFu<1Bw0
zAl=VHESnbFr#Sq+wvD|gdn;`i%!Lpn%BQ|Ch@zTg*?+Tko|QZJIOIT)My(9TB-mjr
zm1SwF2S`&TpDryX9#P`UP%bU|hwRsvKtDhT+>zBJ1RbB^Yju~&e}L^~@^yQUlTv1@
zBA9`54bp31Vp;A`Vs+FFo;0-R!Oux1PR36uu}UPq&<xxl4(!6&r}UW;ygg;Uk7j?E
zbav5Xk!BlAd(Ye$8J3W-tTIwY%9LE1?uKlIjg^sFRz^}`zTI279&YZRAX{%bNv2JS
z{~i%Yhl;`362EfCp7+o`Rxa=95^v|8(|E&m98A}r-soD(7MHu$8qUB`B>R(Gd?_QH
z-I&v|IKQB|xp^Xe=(awPG&MqF<&%bKZr+(s-#&t279BQ>_IM%5!-)So5yF^4AhqV(
zL(&Wq!D<g=Km9X4w<j+pdy8lL1*^HWT%}yxc7~?S6A0Ep=5TNs--@($z3dtIhrug1
z`V|kM@4}twlmM)Tr)1W;{Gk^q3G=dc^*d!%Q$WiId*~UYAz@`{zIG>jXrC3Eh!|EY
z7vSS$K1aFuPf!CESr0vX5x~160L22pe2&WF2S?JMN02hMS{W-)vY$P42(hb(MT7jG
z0Kgu46=5+oFX{|(T_hbv62&x8SSw;YiXi4Zi37hwjAfQJW6M;XSo$borC~ii8Pgl{
z23`)Za5%9Q4#YA!CT!o<zY|=cj%Ar>YBo>+6HO(c(p3ZS!CvGTNzSBX%-rEqrFFu3
z0Co?<?3bD`fsn<-a`2Lp>&&;<_o%rvUkg%%s5cxToQ5N<Bay_aVYD8w(8^-=6rlb9
zoUX?}UWelC0uK~T4Nj*bQPBuGghm`55oDks)Mz;Qe+?~Ie>>rh48y<;K;Ii;b9{a3
ztU9BFw-Hxj#G4%AwBo~BI7~y{qtquD^1>whtP>}mT4}6p>h;5OwHsqC9ZqIF)>vD)
z9`m%V7;6i79wo0|ml|-tf?lQpw*fhjoj*v*f!0om%5|)ayzKeCsC3kNR>)f$KpTZ#
z(oS2Gu8>(A12ijc0u{}-(1z)|n~*@Jn~B)-r;p}a=23i*SyMmcD|z_=^+VW1hTN%f
z(vZ(5bO4ecS%Xg)sAi!w$^tEC9))hiq5*bPOw_*ztWpE_|GlaQ{!Z2H$A+rj`9D={
z=EZ=LI3$p&*UY0PvmQ`%vRUl96ePQckb_@ts@ZwX1kkaveV8H>K#_cc^bsVyzH^9H
z=5C@AQ7jit-+@eej-XrjZy-qM+$X4WAH<%?*C+=za1i?FCX6GUl`D33`!UI0WNdYV
zc!d@**%TtCdBS*zs2`zLnixwFCz2Rj*LOTbOR4gXhi*l@yt6VwDin(KJ|WcL2{ELQ
z01xS2_@d%yBd;a^VFhp+mFvhrvzs^vVRPd;PL|GLdruy6@N~4G9q0j96kkkAf_QJX
z2+%UYGU1xVL=^aR|05&-o+3oyB@x=T#j51j9Ez_8cDG*jM$lQ1uh>l_<s=Y-(QuMC
z#D7cT17F~WiJVIuFbOAN`CJKp4|{u2(@vz*nS5HG@NK9_)FVe-{DU_DLtmnD<S<cQ
zrhN>uohmV!0kO(LP#4N@EEUEoXInA56`O0t{sKJlZJrhT*oyhB*gICN!iv3O#j32>
zek-=3jJlF4`2{6_TwNHotTB0O1lr;fG+}riY+8d}9p6U4L%mdI_0qplMx>#0CAM`P
z^3JT|XEDzY`-GsY?(L>fDo!{8YcSNAFr^I_G8MT({BkOn2e5fU5+J&7BR1$EhzL7*
z)C!{q|C&MXejRWO7HlQ95-6}@;>JkpheGE@o~8F5C;HEPEAq66kR&1Ugosejns4c4
z1cAIHP<u##)CqbS0ZM9)UPeHYIIvl`n`Ckiec4TN)R|5hAHL0xg*icqyp|~MNy(fN
zqfyinU<?y975;A|@JEh<CyFUMACGCE1t2ixb`cll39%<)T5`RI68VRSW55-a@n3)~
z(6#qOnrk3<R)J+G0Ia%aNKsY|arX&OIK|y_FXrwsRu+^rnYjC7ieALsWL(PRKSVlN
zQ!M2S8y4n?u0%EGkG+hN>*Ykbt&Ao)n-mt{*6AhKP?jY%94~Hblx12JK-Y@>_8|Ya
z@ic!yo#WtT9ZhQv^f%X^?+AQJXI8yOn(O;J0_UZLC<zA`*1OI14muNBlL+(&Q4U>I
zvK2;A{g4N$!BrACM+=}HS^&Y8>{gx+49pBTn;Or7&0)~d?^^%W(6Xq8yvIX)Ll=!e
z*wS={pMFrA$mhcL+bNOhSZs5^_4yh!1ui~0e3JMy1D}!~Vl@W`hY4^|f7+$QzK1ln
zMAo|oja+PzpfJ7bbNw(p+ns=bCHrT>9ey@n*N$Ez=Xur1SBo$?&gYQTNOpk^Xaw}_
zR6l~)D4|tHof2!J(sAHyexk~T(_~BXi~4W&UBF?rtyAjg)El2yL=?b=>p-$vKkPxR
zwAFGyjIrd9F_|1PCa^X*UbAC3yDeO=Q^&Sbr?DL#6@K`&wKcp2YIo*AFcyszm!j5|
zYPnfXPJl+OgQ-YV_ZoaNtm<&qO3g~q3GRleK3%mOhj1-}V-2>KW!mcyelxy;ubQEC
z)hx0P>gL3T&+t(6O=xD+&fle0>-{z*HrGlxLJ6P<q;CgoO!zPvAGTkhMTinxh;U>*
z6xe^eG3%&($pfjV<2y?PZeXVz>$Lmt-X}S6iyKo8lmZ5udmZUzmo0=mihCbW!DW$U
zC?|3ujnvSR;S!V~*Z7@Q8ITD0$oqlgyp1Ix{w_Jpf9A7yMC~ukowZPk+<`)h4#N-~
zx`B|O;c=|D*FvM(Dgs8t-bfH|@N`=*_|`ds>J=6Y_VcmpvIB$y(5+twa-`bh^4O%v
zER<BoOVDTNkK}dHb14s(lfL)WLj8iNPK#m*4oR8&6_tmROqT-baL~NI*35epx(gFl
zEFkTCC8p;@do>S{8j64{(^7QTCPawj{E9(rUYit}h7g@Mp(B+rD%YhBM7<1yhjko^
zmY)OsH;9v_@%1SW(nOfOU-XAWxkK-FG;FHl#i#~n`^z0+U;l=xeZq~Ye?uDUw0FXS
zq=3~1_=XRtBH%J1u?Slf4StbYpGsA)ZM%?$#y!g4gc&=$hmLyDlC={t181roA^xKH
zK*znnonf-!iY8+`hF#XfJ0bma#_17&frO%jJp_&EKzcMEXZ^8tMkn$yLF%Dl`Yw>4
z?>r1>nzNv;ej>%FDeTauQzHP|`F8+mk%?fR2YJXB3A>$Dv}_6O>pJI`4$z|xdtn_L
z6oykV;-p@u!#CLQh0w8~eVm}^@jpS;!SMOKAImQEat9glJ8{GzLpNtNa1>+tdtj3z
zb%M&K;`9!1SUAt#w!K80p86b@7Gy)H)|OV~D-R!J2Zb++b^AohUj#H{RrBnJmFE|_
zYeUNO-_7tI$E`+ke!O?%WY*}!{;KbMLl#>m+u!kBXc%*o-a5<oRs$C7Vr4W`*0BFc
zbTH!TgX9T+m)+nHDM<Ge4LiB?!^vgXqXphBm|+l51X2iZ9#GSA<X8&4uA($}h|`y#
z_#%UpKISiM<J0<%>Rq<flx4JEjBty=O$T(8%H};T_HRVfM;(yDF3~7Y8Y>4TZF7J(
zuYC{P;2|#eZ$@ns1XCPM;#jMHR0+Iqo+R;gfNhVIEl0M?$&$E-bVmD-o(%ETU_qK5
zT9z0VTCrP2XVN;7y<A&bs^+qj-#X>g+nn}yeXlfp_N`W@{h;sg2D!9UbKq>XwL38e
zq{ncRI$BE>X#GOE<|NlX;M7fa82thi>H7$<C992UY>PRKC9C24uAi5c_&!R{iJ)Q_
zaOio=e%|+XW8t@sIN8<}`Wl?tU}fU-6#9IV{SQFMcVf#QS^WTZz_zX_`#$!*w5-m`
zH6-xKm1R4J;@c^{qzuMH>wApi^UHoT6pvH<>axU8{6UIOE&IVx{2_|xmi>_8nJB*n
zadYDu>~fw68(Y`FEdh<JF;Bq$88#|cV+35jYG@n+f9xp%x%bSYho2r5c%)1R#ML=O
z>`-aY0k5DhzSZlrYqH+z^mR0xLDTKk@=9OZhIIN2I@h<G#Z(4=_Y3r6d(;yN5;Ii7
zzMS$`IEhhDzmUCcv6{!)qiNxyHgyL6Wc;luYSSwC25>;?I4VwyW0G+f1n&T$xSJly
z)#j!Z>;$g|Bg4t3LuMJtJ6XHV6?LA@Gt{CgEVf(T88SN!jZ-e9VBAUm#{oibH$9RQ
z4p5tS(<3?N0JVBIJyKhjK|TR(Falj++}F_91<p7LvX%zAv`h>H2Y(B<CAczRh0p;-
z2^jJ*ydbM%&^Y*WTySWU*=^vW-x-TmBOUgm+twJ>M>`j-*@0px<!XzYa7>Zq2!_fd
z?y<jITK!(*Bv$<%F;?9Qqhc%^Jl{*6;#*-Oz<~v8vy{_{j!KzkZdy}oF6{~@CxNm!
zOG{omIQ}Z}JN`gjAiiCU7`6b1u*!hrtg&c~x0Q438dwrX9I+U57-4}u%Px+t5K;K{
ztf$Vs7db7JPyS10-V<Gz?!#&1n$*@WNa#IMHWAFJJlw|GNcy)oc2OLQ7r@g>@N3(^
z%P&G^^+@ezF-7<mvVlOWC{*E53eo0nJ!~-}NHb}BiSTl}Qs3;dYlY13F7u@SXp)*&
zHl1F%Wi#lNStj`(qocRwV(L!!5JV2F!csx(&57+{Ow!C!VXq`GthHD%9d4y@@W3}d
z^h>zQ!m|l?sHj(CaaV|o+_Jn!u--yr&%?AH<Sz2{0FJiGO5F42*_2t?l7UUDzli1U
zkRddkcYk7<Fo)4;SyYJ9^NIVPKtInbQ*DbvJcb>VFkK)fvVRhFEUM$v!Pjt!3mawm
z$cOr0u}Y{--h>0H$iPmPH_a~#tJg+twfrpT3RoIRmxOAAyzy!<5uD&a$ss{`>32d<
zFhttVlHvaaQ((lOBmugVkdySwv9Nm*6o6ntcZQ)%Aof&0-zuOeDA7Fov^5QaM?$T)
zHDqM6KVt{HldRJaBw5WOT@a8R#&`%%)BG8l3pXwW2L5XXF21XzDf>J#6V3{9OGa}V
ze3hInQ<dl1;d1{HO>%(rcr%lZo5J{5?QF>~1I}h!B`QF5u~Rs2ipwChpEX_Z;6|?t
zS=vuglB44$6TCJcp=C;}8)#79sg8MBT1I8^?2_b%;sY6R>Fg;G#63WSpv$!3ShV*@
zGOco9)BF|cdBXNG>;YmXNOw+PuhiC5G6Ta+Pcp~b3eTUw0Nvgf7&z7qU(Rtii^|hh
z+=K=l(Y~OzfCbd00!JAr+&V8yU4-lV%5dg32;iCgT~aG(WKK&4nrAi6#7b?brO6!r
zd<w)~X=dWnQfFm%2x<}8Gdt2Gq8Mdxb?1_<gavOoinHq;$+QjKjd8|_)mo^obP5^Y
z!QJqhHLdkP1acOtZJx3YPBGSMU^g+nQ9KKs3(IpR+6ET{92kdJ1Kj@mgSEAZ#&diO
zCVjNecF0+VS{H1%1?~e_YHhfQ^|yVTmT)L=+`m4^3*Q1*PZ-`7SERDr2kSyqz!BJy
ztOBa`(3M_Bu?tTuS;?(4HABVRdiQ!DrUQS7%(KuSb>36tj-g!*n>Ku>RA*;8K@h7Y
zXIh3Wy??VdCYrWv4}HK5RiXqes^Z%LMDA8rR&n*l%Sd9KYfGo8xqkmz7~juZuRpWm
zXHXlQLW(+TkM;Y5b-30gaL#-SE+?SMHSnB!6a5C_AU3@g%m04N%g+IdY#Zd^Il#kc
zJNa;7VgM`BFHjt7Pp*J_y$X}Q_Mn;fG$r-;&ML76&=B|Mj3IB23-stM>hK3q7yl4)
z3c&~3PMC6^L=NGYg!)2t{NIa&T&F&eW9ZP*o&*eo19&q+r=wu++=r}t$W0CCrI8Bt
z?;&^5lp@9Mtk@yd@97tUQ(O1al8^lV4HFH{2Y0GD@pd(<@8}+KbV#noom6OT-m8SZ
zHsICz&Ah`1dwVQ1AiWQXI3})uYbChAId7oH+XLUP%mcTf<YadItcL5yaH&*wk0Cs-
z``$8&se+ZOhFU>l2|s9s?}qu+GD(o?7bga`z(b7AVKfwQ9bd&7(*ohyh+`4}Ub+Og
zv~|&8Yi1q(z`|cSP+@cEU4GcPtrj1);c|rZ&7h1mZVgY->F%t)Hmt1SgWY1&+h`wk
ziIt#zPP^Pv%D*f1Vm5JwRO$jLT-;(^AH~_i0pz?cc3Lg`8R!Yedb}i4O-sI(SZGo$
zMQ!bgg@ePPuZBYdsgTgG=p#sh=EN=;YjpX}YHr_!jV{m#ESP4%jjCI$Fh$&sGdARG
zV{Y3xncoc?+o-#V&cN^r^5AYFTt<{n8}c7wSq7U?=`yzxe;l~sE+qF0w9H+L-P`LS
zyb5Z{uB#34r~ixcI=Kr)c1o~<NIV@uCN}MdZsZYch+NnCE^M03|AgwIGlp+Qy3eW|
z8}&E?3<Oh~_1)h_xEb>lY7N}$NT3DGrK4abA)Kgo*3{O8qP9e}yQbEtcfuZK=8>=>
zqZ=+=N_-_{sg~iAwcoHMUl`H~|DeR_&;rTZH|c#rd1w{h)U0FwDVo)N8{&f2<jFM3
zHE9d99Y{7JEU-Bd;r{(O;X6exbR(Wpmr6~vfB)B46j7lve*tySO&_m@aInFh-Kxz(
zC%X`Kk~1YciI9wU4{PsRgY?6!gWmRI$wdgSKnh*!2AE^r$4(vl<k-pVBigyXv#bYD
zxNZ<%Tzwzek2U1_0JlkQP<(*hn6;z`A134OMeiwuWQ3f3@8YoIyApeuoxt5}sAnav
zQq(VPf>4QDbFm0TU4)q%80Ig<ZH+aNXYL(7mtnb79KtP?@*3k(^cS7fn1kgPpl5q0
zvGq>4cVPW_N8w!k%Rwl;KX1G`F?VBP#ecb2HVzT!58yi4SA`b?HokcpJnUbfZl{PF
zk>oRLejvmQH=%*0+DR7r7CLCtbRWUtdQMc0GX~zneB53WmY7JsxgPxBf|Zod2bsaC
z^#TUXFw*vsD8s3eZn3<={BD8y-F)-Avv^(#5HmvD4qVGVp>f@NoD6p6G0b_;>7TGK
zSQ~alR?VS_5WXJ4chmd`;}eKP*Ud!gqJH>H{<sD=5YvY2Qrsmh-(G`xqMJV}n8#Uv
zP^OD2chX#X%4<OGp3_jDvaeY9xz2!>=^E&IvG)+-cV%M^_&01SS0H0MKv$grs5Or#
ze{;CeD&O0U=GE4*vNezey^K^nxg<}=whvsAzk~U#Wx3i9o(+e0lk$hTOUuO;4{qj4
zl2>04XBKhf3p<6i#H3_&!u-@$Y5C=joC$cF{3W!jqt2D3>B5^fj~M$Vm|SQkqX41q
z2T%b2<P|Js=I{^2YZYANlkj<;Okn&Cqz!pI)0U$v@(dBi@hSwcUPkG;WY(QbXmr1d
z-iF=-DsbbnLw|(3pGQ*4ZCHu_2obUD6l7>Y3>2D36oLt^mS3MHXxT;nz5fClr6_(g
z&5ZNmC;~14*6HL!T?_*!%vVHtjCz-|@_{NWfYVq9UHf&K-&hC=^N&yg7CXr8M9E-I
zy78zABU=W%n&G@W?8Qu0LFxuGkGjMv)ARK*Kbna$O|6T+L`^#69$NTe%8totm!w@g
zstZths1|A@RqXFjEbE6;4?L#pWi+}9BOlnJ@if*Y@t06S%G-H%h(Gyfd?E*y<6uV~
z#6AVi5o+s34s={NLIlf5uA;m&lJFu6NR3z>mHe*2<gXEcH*zS&2y;W+XH}$5LvL(+
zEyRl`&i{bYhx(h}je^_xt4QkJf*wZx3H$(JBgou`7*3bKRsOip$CwXe2J3re<E&_x
z_xLh$I(Ka-;0C~i<E~XSAB#9>h>?FG+|6B3U|-OciP^-Shp#}#vXgWHA5YNa6U!+q
zq};yuH@J$<g1PN~sO5)$A+&~=N)4?sb0QFx-Rto9))BY;aB?gTO%(;5xJVOItA;GS
z6_+75B!}0e7^caSdZCNP>N+-9bU!#^pzU+qcXRI%2RJ6N!&X5ogfS!cW}_M>(lIwZ
zfe*Ebf@|4$_;a(+fU&e6F5DR2dJoz(we3sCE&7)WHrk^L?qs(*e7DNlO|*U1q<`tz
zFp0f<BAHm6=IA>yeZ{_t!7Obi5STtGS&+D;Yxv9K`^c{aAF<4kr-vQzf@8HZTke1_
zmA(3$ai@cpRCwMl!x0N;(N4*zTI>7u4{b*MIVBEz6z)~*XZ8JU7aY+A;K^H8`rhA|
z#@@HXm?m-|yYDTeyybfrCsN?||6PagyRzmxAaK6m*)Wm4a^kbTx2CJWcd^}}O(&$T
zO<t0?wM(QwYhg>D1is$|nkYqPH#_KxLQx{SSvHo)AToTevB1O*7qscSN~{T$U_eed
zkFhYIW!is2{v~+Ic>0#e+UgdNtGQYkY->h<h<IsJqawiv@MS^P6G`BcHA#d8bu0E&
zWaTHX5I`=Fbre+Cf%tEzVJALG#01`1n3W9}8Ain%xbF9uuqvL#_uX5>?AtOhv79Yn
zC|3L;L^vY(C8_NL#a`w7Z<;&Q)?kGqzKblWva^D+h~g})^-+JanYz>}7pa3)<rYAd
ztLgr7Nz2k#I|fCHz8M}K_mJYi@c5QU!YDbSM^*y~SgDB32}iIw%Oid-I-FQM_DoHp
z%8f0ZPqEmb2{}&T3s7G=!ESWu-<I7%I`*j4B3P9u-6*5>3H#&j%?M%nM&-lef!)5j
zxF+{ot!{W}P%Xn+lGGUvThXOjoAq?c<+5_^5yIE&whQ>kp@q=!7ai>|DzP=9c19f$
z$s>&8F1nuZB+A21Ac`DkZgdS-L#<8zL|-DCxMORp!%Qc{SfvY7W`--&hwRbd0Jad8
zc=lZv7M)4Ey|o<on4M?s_qGZtj?Ez{2LA{8?=<|f;dkJ~>n+;3sDoV)i>|hh75n`-
zH-jEcA%g)`CS%Vo^jhM_(t0R?r8p(9shquB^hR5^6FWQ$^{ReTZ$6`7g^<`efS2LI
z`*Ubd|3D8#gO1K7jsQi{X>oV6_6pY4m`A6R=Sku=CoWqz7RrfR5Ri?94t>qPR0wyK
z7ypI$rKPgG<?vuztQB3=yrdk*yEZ!ni$Nqm={r6>C^KCCKePnH(pwNhEInLUcsSYH
zMK#c96Wcyf*vntjXy@2%131BRv+s+<meK(>&8T)^0jzv~DG<Z29w_ku0@xTitNg%+
z5L8dwc?Wc0zkYtf#*FBKFqz|5Iee>Rt=!UY=RF%PA!+PSEVc;+x04jyWuz`9C8z0a
zP;et3AKyt09HrxKlTn%hWp|r{ZIg}rF;RCFy>6=>AcKtZ{igs;$2D+d$8_A5SbQzE
zWQCGl#p=%`3N9G+E+|OKU+*%)vT>_}G|H_qp1!cG)wL|ngccc3S|rn<o1P5?O^xG8
zi@Y&PKTJwg?5tpKBt7DrD{<S`lt)Y;jpQLYcM03pK%(M0T<2^ow&BiPq`>lI+%#ZR
zT-V<{52V9tuLLh8L3{Ji<yXM}V2RDRbs(|AJHRwo+n{3!Mh_(DgQ7_*d*Pd+#G9ze
z+5mkX`T*kiZW|s@25CTf9m9s2F+}g&kpX3i7*NEQzalmU6wrH<P_~<7luG(mgH3k8
zu<#kKu=-rW`31Y5NJ(zbpzp1C%BhhJWX%{-&KV9J2!X6ZIloR*nx+$<lX5N<WPP2;
zif?Fq*Qk&8I}$0fE*VAEfXlEO75M|0>5gV__imv8s%5AodpfBay=|iYK@SFKaA)n!
z`gu>Nt}$DG-8}J`UfpjdbHH}`%ci&Y#3wXN=Lo&`4(0{54(6M=w14Jc_S@PRz1<CO
z58ufK?mMY%V^gT$zXS6QVBXP|C$S{L-FYK9dyw<mRL-o6zP;1XgB*GM3HZRUlc*=P
z-<6d{Gt?Vl;|{Z1U51U7yYv!M{gW|8AX)BWE~p&+OU!%N4#9YA%g&0K)r9jKI4BOA
zDYN*os)CgcwIvtV!Lomhf%vd$BtIr?^VgEUcxQ#zocTJu@~whVXw<U`dh^Jl_z~#M
z>T~Rl^A0wq2=ksVQv3&T--<cSN^FnE$Xv{BarkbLwH1&hAwi9ou{TJ-2NGLKz>P-z
znVBn^D-8S%Dw>y7pTWRCJv%uY(qn<`5JRE`J$=%kf*e{lfB-uER!3^0(2sg#_74u@
zeg`UK|3HdCiDBCf3TcQlZ;=fE)DVDCBd73MX>n%uU>mry8C=>pv#Bv#(y|5XL25qF
z^05&n9mv|!TtSltfaHuYXx0NX=SsY2p}M3?Oo~o?mUROZ8H~u;#u#JqSQ2{ZLaoPs
zjN}?g*Fmh$vE0P{He)`F%a{13&^QZnW3DA83tFarDJ79wHRQxiju9p&yOE5s7iX5S
zPAT9u2VnQ0f2q4R-q|na&DrhAn{dUUuHF#hhY!*=#Yui>7P*An_97irPU5O2oo*Uy
zOh-vz=E?#LyJLd<zBXDrY%Rb6BQbbjLFbGdr3IZAHR<>@1MDHwJ>lqR{3b&uuKRc$
zRa&(RM0m(TfwmKzbj_mbq{47k@OqTc9^%<gP!){>A+hT{dTmTLg5;Yh9^SeHWDVf^
zPG5p0ObJX>BS$}QtpRL@Mtm;(zl^;l;yDM;Qq3i-!QHSe;4YHOc?FQc!u3kLQijC|
zsD%F~sDR}K4dDj>ip4gzraN(+OJc5dkxPd4`v&&TmSu%$r;c7Q_Rd1_&ATqgv*|(_
z?NHdXIT(ccj?t#VW&9LM1V(fCO9+gvYLQh{cRA|8<q{rsEL{q0S&;6=DPwd4Eo9!r
zW)iLHV!I&tETgv~)6t~Fb|S(Vncn^DVBD;7C*lRb0QSuw%P{9=8VL`gW?mO&LX>$m
z-~lI6RXK*E5J9AvdGFyn+a;(a3c&7Xd>(S*x&q~)n?QFXUV&&!oZ5%W|Ki_-47X%6
z(Q0oier1I=N8(f&F4phVH{(93yq4hH=B4MFtN%i`>qOJ&mZjva%7L~Zf16w=u@t|N
zC8*A#SM1f;Df0UcD-S(|f&m-%BOMFxd0<LRMB$-j-MCk73Ph5VvHN8KVQD`KCgGqF
zGZ>7f<DRA(*bWm^Pz|n5Bf6w=TUJEN0bvC)z;Q^lHVAw7xgd*ES279YvmA$ra903~
ziK<zG7|GsNx|axK#EH3-9eMb!@2B=lxPuWaG+ZWd7*%LT;9Sl{1s{d2O5aaK*_0h`
zAY#U;d{dMw?7Z{fzcMdPo31?X^&VNP4}#Qf<>k6SCe7GO?X$W$1$etD()gv9Vi~;F
zCn%}JBUFzlG%bavdIc_e2^!)%?=Kt;>=SrU%PeegG`3XKr#yK6E3D-&$9I<7GTy?n
z`3_|+%QY&LlI~o5@E#!+04sw(UjlbAOA19tfaBt{6O-buYH*haS#ZIU;3SqHLg-Hs
zuSrFMHxltGM10k*4W;Z6`f7@<Y8kh%>B}+rAq7FL4k^cPF$PXBT7m8RsSpzmmpDjw
z(ki70#|jhi*+>t9d8k}VN=CZ*CV?+O*aWS7?aGcDMH*FIBw7N4g!15Gl-=#Y7fUc8
z@=E*|8dge8sz&-qlL!y}Da!v>O{!#%h_6;(D$kEwxNxnGW=+sVv(lnD%hwwDe!ni-
zoR)g6HC%rGcEK}))V{s{`}Tc<hF(E|k@npw(g=@H?OQ<Y^W%$X&=vwo{8d9pPOHwF
z=1S_Gc~)D{2-{wQw7)Kzg4=|s4fYP3kQeKT7T7zi7Ca5L*YJ|JHx!C2&B3B3(F6Ns
zO(H?%7PX1HD1)pGw?xy?yOiLb#1H<&ew-3A(VeWls3Vw&6;tNFCBUlFzLx-f?{9l0
z>9qC<EY3&D3QMr9)>{HC`gjazkX!(kNl;e$`2}+?sVj5N5W~RbMG#Yeilh*{Kq7N-
z`TBlJleBgEegUIi6-{4RDkK!Ye(|3$(WdsYeuJPfC%GUcy$8s6o4ht97ee3rVQ>{3
z*i>?fSUVT;29du2q~QO6pzaa7^iC!aDH2SyYB^>J-q%+0le@$TI#;BJhU*x>X_1dz
zx5<3Im6y*H#lbF0#fZf#2J+6~4Y=t%4*)nya{)$p3vFvi*Ad5XiK~d{2YC_&;{G)_
z^N738ShjLt@wE>91DpC%ke8C8!RXHHy%lqCamNHAt94P%)%{coTzgL^C-6sytKd%{
zXq3?0V#s7l7}AWv0d&MKAn8;p*_K`XXxr1skZRj_e%o+C)TVz&PM8<lhud@szj_!z
z7#R6;&svQ+YBgrw#f?$Wm|W4Ajv!w*lNy7K-^|{M3^e9i8mYTxAQ8Kvr@Ls()v{CE
zhE~~Oc`mI#txn>vp$=Ak8g~#pgOEkaztzB*z)dvpU#TW*zC*i%^otfUrgsg<oidAx
zdCQmoC2)sbB}zs~Y#m<0mwXN8Eei%e7lYqNAQKEO>xN5v5AXO1A$2ZMX_kg%wV(<c
z%bUh1&$)Ul#!PYGZUX$=5<0QyizTeXI(=)M+#R+c(40lwc(fEUf{q;CM01l*0;X;B
z<2AIM>7t+Gz<}TVG4u+y55@fqQ~6UsY}D@M)fS$(ouQTV5b`>jrzVexEzt|w)aI#N
zy*R^HVsFpgJqzGszw-<~`_IG)*zc4z>|D6(fMAI483X=4<m#rM&C+qtIIY4vG^Isp
zmi>!x@xnA5Z%tk@9F=du4^mXSwa*9zdvm_ucS4CD1|OA7qubHlHmx|ZnXXEN7wgnS
z;0*lz@p~IMQ+O2fS>f%E3)S)CGy@y{NI!rx@H7_Z?IdD!#rd6>sbX_x<Bf?e8G}Zn
z8)Zzl%5aM^c8n^+U8=cJ1|0a`D5}QgJ(w3XPfI$QS7ewa_5E}h;2a$Whz6I5-@E~V
zYC(}vJF@TnT5!i`VC)C2VTX%e*UzVIsZMN8p^$2Zg+kU}qkv|(aU`Iic^dCQne1@%
z%4LR)%AH8wAvk%E%pG0JuqQJ1(IA+Z`HjQ<;oD1okMpr~3NjyTKJtSt?vZ(XZHV^3
zzbKs&qZLp|Z7uocN7j5ord0GEJiB{@l&P{&Mj*+&p*>)DhIFP=QW{8&p4&QuZtn=V
zZZ64JWj}sasaHP&)^HcKRrvz$Mw{OVxOWpg+%}ZhFHktf{@9bmBIHp*J5%CknLM~!
zDg$THjev(0pF!ntz^E@IzYsSTJS0hu-vSnn7@Eg&KT%>oK*H8?Yd@n8<u}}rs91o@
zwlQbiG@gGSqRkFrPrIN~dKG79l4G&ogo_NrNXqJzh(@qC!Y76F$GK7%=410wAb9zl
zwRKIuc7eKRn))GXX2nF4+FA=hxbVHj4r2lCd&N3h-WPCE)#?@aRU{?$46^vD3zQ%H
z8v>?Q0LdAhvwJ6fe`RYRwH-s~!y=QFLVp5(V+N``2PuwrW)S-D;7ncuuNm@@yQl^5
zq{4{+04@|hEdqVZ!7$Z_Giqz;*Q^}1waE+%5ds8dJ=VAn`)kNLqK&-#SD1*x6dLXh
zi>|>AN)PEo(K~LOaHQYF8ty96%N`FY>%bYTCBzzVI`a7f9wl}PErhQVybREN)Ngz~
zK(XBinxh53W5rw$6x7C7i=e;-u05IF-tOm-duy5A-?ga(-DGv@1pdNwP-OsaOTX{T
z6jbRHRG||$U!zJtr~(%S^;t9)hal$sQ0PuX&<juy=;P5f;%@)sr63L*bI?(^Zve#6
z&hW%EREPVNdVqD``;&WTB0EnEpt9s8L!?Ausgc&qqXse1>ztZJw0smo9EP4mYn}Lg
zE^>m6i=>XkJzX#^h#3U`@gu{ROkxZINommdM<klsEClhJTLK&6Ad4}9I-dn3aAN6i
zc}djNj0pPfW{938?dL(*8_Dqqo2(%r>u`JO2f|PrvQbQc$+@G%oE*SJV!9|q$nP8I
z6q4UgyoLO71cdzNgDEnF{N|6yuZQH<CFIvRBER`V^80h@;(6Om`0H-lG<US@9w)kg
zO?HFi#CI|0V-sDyH{n=-AGfXLOLmGLuA?eJA(CFygvQ}sD>rRF!-bZb3l^*8N6734
zE>CLSUJ?$0JlMN{egkf}CFo+la0=L)c$<dwMLzW6RAOounA#ac75rWR(2ok{Lj>Q$
zUfysYQH_xMymQ19{rHMwSr7e+IHEIg&za%wfAmLxqx*k|M0C99esJQ&eLrE4S_+%)
zUwg>Vbb$Q-w?hbVkqe)I`pk_o&lPVc&k%1HAN&tWck^EH&gY-e`+EMdh<f-R#JiBc
zE#9;E8{$2icZxTRE#f_wKQG<|{8!>#!v9UY=kcH7tsnB68~yxYkyOEVh<6o_iT7f@
zMZAMt74JLvI`Lk{*NFEDzCyfL^E<?Q4PPwY5ndtQ>-aqJUeD)>x5{UW_hw!w-dlJ9
z-h{$)P2e(~OR3MrC}<bKW(xNIl2XafoPR2Uq?Gv|Metz?zAb`}Qt(v~B<C*PCW22;
z@Hr8Dl7c@M!KW$s1cLgZ+2r{$^edZi5-DaGzI1Uj1N1;6KydCBzXrFM?rK2Fw?xWD
z__G8>3XE}-^0h*?;$R@I?@Z;n!79b&OJ9~sxztK=`_fmWQpQ^;`M&hksT7-)Qs7Hp
zlS=s<yY|4w<NLqbI~TyH$}92TWF}+?ff*Du$iqP%Vo{9pkPv7SlR!`c1A&CB28d)Z
zi6M!TdwH}35(aFNF%?^D)!J5kl|I(mt;I)cOMoVTu0rvFO50#rz3H$TD?+G|`Tx#$
zXOc+->u&r1?|-{HaPr;z-S7Q8-#O<yC$1#y^E>6UW^C%za^;g}z92r4(tvF!fmr5a
zJS;8b)P|e0exUHohGYxhZ`mP@AX0KDZ5H&@jzzaO0|%#HqT8=uV2JGLdyRwY6Rw{P
zZfILze29pq3yoW+h-X>*`ylx9UblY0a`M9B*I1homJT+iV-t39e{gq<^GEivs4|2<
zxIctH(uR%w)Tfph=Ogy9)$eh8aj!dan?uoa!GU_A&X^QuR$}#!sT!$NiInD|WsypK
z@cl@oUX5VR2hjPJdRQURhZNc?IBx<t@AcGc6!i)Y>wa}Ch{Aa>SxA)w3SZ@#Yhsy4
zP|l_8>ll<EneUNRq#ZVgWjMl({z6ar_DQIo@-6HxUvi|;htcSVlw|m9^sjX{^f0q2
zDud=;4IP%?MDR>Zfjds`wlS(vm=`-E#+XE-j-OE!V~k5Uu8(XsT{F^SjbV5Wo>62o
zT<|wAW1Dc?K<tD|0o#V}I@IRh6|?8`ZdN2sPil;%uSn)yI*3R|Pw$Qu|3_B^_#o-O
zgl~(a{~OYO-rpP>td9tk(*OB#{DS-|bmL}j7PX|FWyW+mHw#8tcSev`A9oJxVHI)r
zIzJC}fBtuzsb`lhHyq2B7q(vsO*?GTbSPF)F~!QACEpi5d@MBfo5$}?)3ya#pOeb^
z+wDFs;M#2aFzVB}Ee+c~O(*3$?mBTD{FwqQ1;$A8#-k^weojo|>{!yRpA+kEvH4q7
z>MwSu&baIjt3t*2TVnmKu~LS|yF+cW!eGx;N{A6zzSehtC5^Ypb04q^cm{Y9*a18Q
z+y?|QzjnMK^RDB#Ca#Hl0`~-N2W|)MN!*jTow%L2@I~+HYO)IpN3(U<I>XHo2uY>8
z0LRzUv=IOkf7x;r-b;<6pRL-5ePmunw+PJ<3EQM!11~D2E8GcVdpcp@Cm%l6MZUG)
zAeYeTH)!c(9!V?GCugianJ9g-g|ZMr0&lyA=VyR6pmDZs%%S=@HvfC7_1;&l_b*XN
zOWDF<div_USpWN~7wV%zZi@;>4X9zb&)&27-<O_sZq8$>M#UiQDHLcXkO|BK76Uf}
z#lTvCwjM!SkHAgBO~M_5i$(9Rxo{B{{aPX}0;*qg;5u;axG3t6?i;I(wvpa_zz*P-
zl6ItTX4`0isJ>9|)HbRgs2gD{zg~S8nQXY9Z@mqK)Iy6ygSF6p0HGslrCqpCm`1G2
z;9Z;(^RWclWeyq46nhzTuGJW9#yt`t)dX4tuLo}cfojU>0>2U&dF`0O*a&!`g`0xV
z_4k;kA7(QOzN}0Egl%J6RIw(gU$yQ}!0lkN%H_SXAtlK|yb2Nn4zyTm#DsuFp&Ma7
zD86p=D&kt?qCiXFwf2KdgFYlWA0Z&oE$t3yk?7jCs|_Kz@3TpCaH_7c61cce0^hR|
zfE^y#9lXh7R=MOj)kDYw_3Jrdm_JacpQ{0d!b{qMmzevB9VT=h;!((XN0kPz2uUxI
znxI8Eu%ykLM9zxn_0N)pg_>Bl_LQ`Z`7HfVfMfuoFEsK%|J+1JYkHCh$OH%TVsA<x
z!Y90B#YVEnUxec3m?&x#7b;>A&K4fHf7Uk66I`ltZsj&7R0VDxhlW0=Fkw-#@dXy@
zu!@b7A95+hI%W^S*JI9mhC12D9vA;dB$?1_9`icO^Puv)C+vBd<@uEIyf5rI5YK`~
z9^#E!3@LfgO5S6Bgp7W{BM;)gUH*W%EJztC!Sp#EGnYuAsq%&%{n?U&=mI&VUx|R@
z1a*oS)|At^uneK~6R^KLq1Q>g-zjw58~y8YXd<^3OxZ5wBHd(<X_F)fGETGtb@4D_
zyOfWQ7kbQhq$K!pJm^y2(JRJB^QEvq#}_%lsPh8><X$d#N%$%f9VFK`UfM7U+R{d}
zGuVtF+cVu9-X<ugVW4^$Za(q7-VD)cyj#3iOI+9^v*J}e;Vc&lXZa5i&a#eYG-tW%
zyOEf|+=!~-=?Key^f>iksOFkOUX!ORB!u+=f$A>*d;LXqo()}ik#PvqOcQxo7xa^`
z@U5Mxjg)?i`Azae-;PKbp!Cpg?s<&Vxbtd;>g7S<K6NK1urK!<Y){2)122uq;|6Df
zc^Ecxf%(I|FtKRWvWv_g^H^X7f$C&&#>8Gt!{6CPg@Gm!dqdbrnApUK0RyqD<OR~Y
z%HRTuNg>O0h8WWLVO``+2=Y<3G|DjLB=$9ia`_xPL_ArhHO^tYf=jil8$%&$eMWkI
zi4vc`?|vp2)R?@>G_6q1mZ(4el)V47>MBBZ*W`WXWm}cJzboLGuqfaeyGU%~LYr}X
zO59&AF>v!?iHD2!50OdOri9fKdp%8<tGBF05Nd+lU65M~A$^8_!`Le^bD64-y>iV}
z+*$}E{;UCe_Hu1u!_T<4aItl7A@gSrbFQo>^01tT;L}p<V$19Vr)uiLU8~{%Oe`?G
z^>!%(riK?L1{NizEOZ!g>MFyY+=aimhXD~B5Pl#LWVaj*8TN+T5|=FWEG;N3xQQDI
zp@R`>{}80hh1PPy9JfV?0WL60S@XFHgl;qAN^|vty=6Q;f{xDws;%i1O)wTw7-IVo
z7Oj+;A$lT+eC&q({2jXq%NZwf8%HrWFxKvW_Qw=GX5+;|faYRmnZsj>B|O3~3NX%n
z_ddS!0S!0TV{e-=9M^d1oM3D1$5$Es{5eUnLBt*=8a6zktU`~x^G5O%`pcH<)x%il
zT`4@k75PH#$H`DPvxY#6hn&+GKXV<{<CiKghj@+V8_N|Jx&56k<3fTPgH$N{%%z5X
zj%4vuDUPg%DAqg;`E}<D&ZiUSpK7-24(G34@V6%ihjWRG{Pb%YU#M*_sy#Cd|Ft%M
zyW8KqKQ(7a^)L$U;AW@qa>Jf_V9jV=?aCN2TCS58VA02|^dqCPIZ-x?;7#1{bN-}o
zi0uuSK2r4nwDHiU9o!Ay5o65qx5euH>!5ZZySBDJwVVjmf6aLFMYs^BvXWw2H3q!~
z(;%lS6m;T)pvO`cGg}L5FC9yR#x_hBf8BPvu&Y-G!c+(*MZzTa`h*7T?%V$yJG&R<
zlsGYzZp4?Y8_s}3d(e-V;|z>mx-JBb`a7IgHZbhZcV4;YyWqYN+&KEYvg11nH-1#U
zgCkE6_Zj?-0}fug&mf<5UXj$nXS>6m`@EvcaNhGuIE?^Ftplon5?}?e6z~Aq066a7
z;k+W51wvBk9|O+-FN#kDC;q>7UP*pP@>S=Rw(p(yyfTGPa-t#dwoIN&fNenJjB(EM
ziiG}r=M|N1B&}|&{<F?2;k1uah7-U^pbM~*Wg;*HxE!Ew{to9A$t(~`<8L;w6et&;
zNZ<S|=ap^>TYjGTJnR>t)#{$@V%5uk7VPX)tx)}9i~;_$vBro~X_@fGK`p*c(6Shm
z_ccfy4kG%9JhMigIdnL{Oju?TtP=+pgkUA)nQwrAeEPsq(87sB6bdBfn??76cEAp|
zFgA55t4gq}O8mn|j^XANy!bhC48jd_s9~TBmfYvWp%H)+$2)KWtZ>$eqk?x<o6jQ@
zFjndlb(Y{tn8SR5BZNr*1)XM~JLz*V$<OjtoflNI^pG;4K<@DCqjos-ON6xiv-?6J
zOlF@(WELF<T-v}C_iTHFPzXn(2WbOwO_}<n&=VJMziw2zc9yI3Z?jcxmlwrAV&7qN
zs>*}%En;RExS~IXSp9J;Iv|J~YrNURrg*tQC773oWE%2dA{FNFz}RpRg_uvaG0X<4
z)KO#ha9-1rjzt~`h)KCbm8#yvWnIKul`Kc%2BF2HVwY^#;84=0h8L9xUmS)sI5efu
zrMsq&67AV?*ESC6u?BQ53x=+at{vtpUy=Tn>%hjPRv@fb>>NZei@|TH*Pe_fyaRH>
z+qn}v>wgrKRZayp#0=C6%HTf}vvC}PLL1zZe+v)J`OV#n=)i?}W&PEaUEz{$-9>27
zp&VDLisExmUlyYe57bJ0b^X`NPKqF`ALem;0ng^WuokSF$I*omA&wcc<->L*C)w^$
z#@105(>pikRtXe*PBn`NCWH?v<}230wAUWEut~0FW8dub!7=*+d&g-odQ$iK5(3Qy
z_h7xtK6cMla=P5A1>046G*w<cCcFx)i|N%1)tOq!yEKKxMVy%I^Uq`)PYo*;6We2$
zTQD^YA7k^_xG=ZuWYCdY_EFH5TXqWbD|B)ozF|Z^c5}pE?uQK+J}++<j-Xp4a=J}l
zakf&I<nr=2+>|;{F2`5r2AUC14SawNdSxguK5Tff1wp(ReX7WYCr5Ogjhy&`?wYGR
z=ANe%{=|N?Z*Zu2VNWTB^VlE?Ocdog(hMR#lw^kPwpNPcxZNv7<o5n$;YK>g4Sid)
z6wVlH{)&i*#y*M@7L64NAM;8{S4rUpV*{F;2Dw!$>r^WrA`-cQ)8U#<Q56p>`$0fv
znZuaInX8j&uMF()eo2pcLnnx>(zYf-IaoN1od1%^SY&iYDsf*+$~R27Y08`qCv9kw
zOjU%BzDgnXV4bl>PIk|Hi{z}OM`r1#lo2###z@=|#HAWZB~MB<G^wA6Od~yVv}}Oc
zD2cG1tE)pIs)t{SDt=8@1B!q`Y0f6O5)zp5y!5f~&z_^WLMO5-pE#vhuEXgU;kZ+?
zY1^Cq8@XtZLJ2!0ade)5xhlUAJ#C?g0Fp6RV~+-Hw1!~2<^&S)*Bs>t)U+%SQ46WK
zB&rYRMQY-2Nega9LlI`8$l&K}0|k3jgm<t?8RH)mnrIcY`7Fk7o7>`SaHx-?&M0K8
zpVK~(`KfGoUd_k~D_z%%ni5q-x@~s`2G{LYmD*i>aUc7g{$0pyv;}|H{B9h!nN)WL
zUiKfmwE0-SaEG;II_xp|W(#Pq)Xsjc&7=7)dXaWM%_h<<V3pXj6<F3`OYF>lRvOXO
z85-I}-KDi;2ThPg+FW5{1GBi~x37s}lTPVLNDgi}h!h;*XoQB5g8>Z+<530+()tZK
zFJd{Zq2?7VEIGF<moA=KLMA90Wm|bIFw$B=^=1AVGsajdN=1e4B242Ol~)#u>RYp3
zk*$D3t&n7nnB$*kl5`ZzPCdQxrn<9=cb(gmIV~)raJ6}nWV089VtQEa<f?oQnn#H$
zENN7Yp|Rw&!I`%G5XpMXb<MO8!J}nTM5e9gIM<@}BTe>cB93s}thilfElNyKiX5FB
zh20b=d=UdqBPF8|xe|g0#4%;}<MWD!!ZyxWBjq)v<`v|%_;rU;<<V!N5W?)D)6|fm
zI1>rNMjB4)Fa%gu-8S<#aM?jA+JXZZks&=UkaMtsY8^M%zQqUB);D>DSY`Fu^Sbnz
z9EH?R_5+6qyE$#m!}kwpE@*%Aj0mNMed8m(d-3J$gc?6^mj*7%!t#ONljFiJRIp#u
zw`n$PCsp<X=3^16GSAJQWnvLZj6^NKYg0a6o0j8Mxhjo66(0VqS;3!;ReZP=zfG0+
zZCZ=prcG5%ic1_ZAN5FpJfXlwEJ%%Ls5wb7L?DqXT6^wC)dOZe4@^8jO~mPKS}Jge
z%S$)FeG9zgKenkM$4vb|zi{FQa#{Xz<|bVzD_M@oO_jA=i-V16J3R3amYHlvCUXAm
z2pA^<H5~-_@KFK=b5mb7rk;Mo-|TA0L3_5<636+L<FMgD>?OyU0~523dloHJmcFbU
zP~8$~Hm(%6$A0)&fb!Z@qM~U}s(4aSiKMN|60DmM&JR=xyNS9Y5{cTQLKM`#N~?$Q
zo0C4SFd!5($($SLEhu>i$`o5mG-d%t7uwW*Kd}{0RewR9?YS|sW`dc}C;Hbv9UcDh
ziZCuU5_E%s?J)f;3)E6_$qeH*!BiRx(LTW&J?5NP%1SGDICsWdK2z~QIB`xW$E7>K
z;_T?p{nv?5AA`?EQ&$y+s*d;QL_}$vSwe}zd#92F?PyRHRFw)|o?;~GN9$@_QpL50
zmld|RlMRz5f)(wwup+itb$P<(DYKQ(5NRdz6g_+d$jKvuobFKwFjsu#<RJ$b5g=A}
z2ewyPm~oF!L}&6W(JUs{f<=p%l1^EfkA8vSDO25e=(%PKt;BMAgB1c|cAC=FHA7mk
zhzdaA4qlF?S$RxtT{A4uuXg72S;k;#Vs0c^ZOroFL<_1I`ZEqoOEEP1v17*sPa+n4
zM7G<zX_B&d^IcgPxQc^9BOxdwOU^~57MgIJe7|UU!*tb-<`WQg86vE2?VD+fhRN`U
zQd@-T2JWe(g?Kwa8=6CCRz+2A(U*G6C!S{A?VMA_&NHf9jnW1i>0fOAh6Kav3!dXq
z?80KUg~bXBPJ0m=Vx*8_SeLKkt19<Mp3~VmBPdEl`nezF-9v?D%4!&)7ADEE3iaPK
zPgjyhp+nhrLiNF7W@?1OH$-+2(H}P+3byz|-WwRG6MC9xuSS8WG-sghMe*2aPilXJ
zhp=X8OXGB4Py2)Tp{m;dj72rP=A0U@e=eOSr-g{d>#q93Pg=6hqVamD`4n}uFnm#d
z-PMxyNw@NAd()E6GTWks!eGk_RjC4-b#F+Uj1@sg>J}2h;?As2y}xs3&Y9*m$AIQu
z%CF^|W3A_kzLm?mJYc_`1BZ|K{dD@z{%NOMXcprWjyJ~Zm&45;17{F6_KbIZ{bu}e
zZEWm2Gg^7t!&A$QHqPbkF~*_E`)9Q2{lOhWAz$q2Hv-K!375J1@D*NnHdIKnx<rqK
zabfft!)E#mn$231ett*qHE9;_=UkKORg^^iU-Q(Gl={+|OU!kBB5PLU;Floyinuep
zIFV-*=8VbhaamJ>(>RWaAK)m75saoPQO<SdcQ}8;3PteF6<t~u9jAZSS<CAj!rqb9
zLu|B?et0onh?Zn50t9Bs^cHP$@r-J(wX4g_Dhqk?@-UZx1Z9i9ShSj7CF~O>P!}E<
ze1oA{77AS_p%^*SP=cQ4F^^FR8A&yRA*$-stIIql@yG$)hLVY~J-k8+UUo_X?2-UM
z<Oom%gzBXM`-IwV^yl4v`WQNpa!(%%t6?f0JH%!wWIAR$d=sCn6HbmJ7(cg`%WVD9
zxQY4ET-I&`hP!v2E2Ggnv;>371>VH8VBt}wcFL?3AnC^RvY2N?V43;m0q+?)mX(uQ
zq0UY|3&z$*Xj!~joxy-y8^^P}1W>JPEimlCNvW@I9L4Elk$Dq-frAANOOk>YK&1}V
zyv^VeAr<cYZa5hjD9ONib8b099;q)ow|s!hQ9gB_@fwGTlo}Bx93*Nsaz>C9o6YOa
ztq(}POI+yjj9uDpkXY(L=UuCDxd^z?US<onTev6Ef`Xq?k47ox6(FIpzBVys)s*#~
z{(7S)X3KB&gN*}baKm86fi*u(OQR7DGx&T;P145c5?ZW3rL|u`(vev2Td_>;MKty&
zqGQGZ=N%wsAuIB+;7gXkrXY{5TxbhO8@?u2qF;d{xFy6G{I!TRZ+&ZHnkB3Jp~xyD
zt~uP1+KQa@_)|34UWyzgXZ`3-1_)l!IBlC{*+^9KIJfK|Swu41)K-aUUX`gVK<MV>
zj-MbS2)iEdE)9a7U)gwlRQ}V#`Cnu{{t@|iL4f<GULwJxKUD;ajz_?2M21@>AIVq0
zSiD|Q1yX!hHJmt9<eT3+NL2*$y_bhT){%ntpHsxiSZNkpzdd5ns^2XMc3Acfv;T(#
z?<nBdz-f|`QmQdRM^2S%Pgx=ieU#}q!n{fX9f8Xw*0b&*locR}09b`1K%xXdNn{c#
ze$d@C2d-T~`)vf2xgaM#sfN{v)}n;98YTjFFyGP#<(d~0KHnTHv9J`<<lWbenqO8L
zb(~_sQ9{Qf@I>k~u!L34tz=Iv!Bbg~%oQ*tDag5`PK7=eUZUS9p}<RIi9Y<PC0eA0
zttI*b_@L4EYaXaQ&k`+CnA~dVUZP)PiGG#9(UA+S$iW+haF*?2Zx|}8FSIhXN?*(P
zkX8Cip(@NqbcnZ*(bPf>s(3~%va&`GH@`wk7UTQ#F4tl7D>yozE_0YEh!wNxgDVXT
z^lP-oqmXtastbojFsL^IEfeDeUu*7+J$*!Qsh)S%Q^CX+qM#iF>Sf01?38#!8=LKE
z{uIqPotIW-_m~Bn)v%J~8DuZ1tiSmtofaH~-8AOB(pWEA+eHby5gd&=z^<r`l#3cd
z;NrRi)g5Wxxv6(U4&j}RQkMA&3_RtN2bgkh*{nSCVz5D_KDXusa+_(`ewsOX*YxEv
zN_T7LcBxWo+z9>}3FcG=(Id)dkFi2JZ*0m)g_4diCv&o6S-8O*OjcG)lN*C_|DKe>
zPUqJ9SW6KAxSHWn5Kcn>eM6EJ-?)%Z7=huFBnRnrPXof{k`og8l=P{IV&b^VyoD|m
z-KGT_7GW-We$$j+A=;cs!xfMT>ZV1t5G~P=q!3VqaOJgQPSccUuom4x2BMF(tjvz2
zf+TKk!b_0IJ^GU1d{xf38J4LZ*TkOwL(`mC)S}%vjX1L;p3^S`7*Cl!95*8p*SX~a
zK8Oz2#Ag}?i^>ipZHB2zN*k?1rwGJWr9UgJAPqSn#-g-1&3$uTp7|uwx8k2~e(-8|
zjOha{LEEVit?4$=cF;Pp#g=t~yHuy&7{34Xp)vawvNKLlJEP(B=bXgCWlaP(%s0=F
zg*1uI$-c`BN`@FXpiQ$*wwKU`;wzKQ@?{&$m4=l;${>=7EF$sgij8i%C|{sscAoiz
zCwZ{SeHl{%nV_`31>ORATngM8mTc+X_hl7PSLVJ^ta6nbg~kN)I2DYZ@a0y8qvt3E
z(GfB`Dbz_0IEfzfF1o0o05xVi51q=qcBEauB(2dk<FNik=hOS0JAd1J%rO8B;)%w9
z?BGb}(}z-)B<cep3+#08eHCj+E3SO!!c~`Czfu%*xqj7SAJd}ws|M-5qjxRM##m8w
z@TTiSH|>e2I4vFvme2^slp8n#QjKhFSgw`}{Rtuy`-1-Rmi_v|u&`}#z>)mGp5{Ng
z@&+6UB>Xyb_UuLkUQbVc0qM*${trU_j?m<nC$}JLTX#&0iK#P2j1xycEKZE!sC$R{
z*BX1#1uMF_ukS+kcN$C4`!oKiUydf#cSUk{k3JNyqj>eh>y_ZW%a&VZz8-;Dihlhk
zmctry)1J_{gP<lB{<cKX$q%!JWYd??eRJ^3s&8ctaU<#d2UG*0M)XJ^hS~F5?ufmV
zyKs?tA)1$Hq=?-;|A`T786qQCc6KQ@i5iw1N5|E0GbCxbHS;)bH~qW49)wk>^dEB9
zbgEKdd%5{4AsUj*U*LobqX^v@l7L#!+7}W_G4Jv}Magf>wu>%_A?96HDh7^~U9ha~
zFZAc8wI1j)Tu<EMAQi0FI=6<vh-BJc*O)docGtnq`mD1kq|Pq07jVH7{YAS^ALJt6
zF#p?U8<wEUjLWwt+w15N>w_`c9Ao9xU*#o~1#2$fy<U|#I3=+Akcsjq6yw<%ve<uJ
z<|T}Jka=0UN12BR7e4d8p&lJ1L8G^qP%uuQa^1z;@EWto*^oJCf=H|Ebu}y=bY;M4
zd+AiVJzLis=f<I5LN6C~)~)r9fHMu+NNZLHOR(0GIVdh+df{1pe!$r{Z_qdim>~hb
z7ztQga~5kD9qc(0cw7QlgM=I}A%{uGA(4=TV)Kwt;}f_zV{%Gzc>?jFDg8o2uT)Eu
zbIVs`dx28+g7eNQ9=Z4K{OYaZ7axNjI_?0U(rTSsL~kVdf_q;?z6`5@+={GCNigDS
z9jK<Mb$^W3DOPgZ9`sH%aP8`d(|?exIWjiJ%)G?8<q2M9VhFn4mXS{5syldu&&CGE
z#ZBobCQmRD(&bBwEdf(g80=mh%0kVXb*yj7;tqUtxg!i>w%ROkZ%zM_bzwPMM@T4?
zpg-GU8yJXh%n70CCN4NGweY0TPknd@d&?n?V)W6GSER#T%G*x(49X+gK{n4};01>U
z;;q`JNga^`YK)=m+{({7DIGu^om-`bf;kJ7;l{=RTlTN(m(hL)FB}B0bjwk*)4u6K
zGWQL-(YbR#TJ5uKkd!ptY`oC9^MLbL4f4t<Y@oSeZDel<emR}<jNNu5nASaD#%6%`
z*Ds9Q(7*A*fU|z_pmBKEjL6&gjEP5r7o0wFe_6~Tg$tcMtZK%gYGUEZLyEG_s61Jw
zg;fp+?VSqHc;Q=T9&<DWDDdZ;V8=NL$zE>7EMbB`R_1o$S?AUO1Az8v_gik@;>r8D
zjrPrE+b$Ann0HZfu!T`Eh*7c1|JlO=CNn9yoKHJe`Oh#iUgw>sfx2^5!+?y8G*}?6
z_NOEe7QdR$V!2~fQ+BLMb)bJ2w^Uta35sVg!)OcP{8=ufj?_RwBTMIb2g*%qpe%_D
zlnJZ+HJu6izo0T?RfA0iOQ#GLc{szvxIlbMX20<X!7s?*iMIl8Rig)Xgu{H`x2laT
ze~cAMA{pI7Xt)faq=2(YA7nq(PlnK-*q~!oKvSXU6;`!&WxR0c&2$C|6cjzpFe2-p
zS;J#Pa(k)Z$epX5TMKwVBUJm%xDW-zNEcMVPN4z@2nwQLDL%;J#m~z9h3=$eZ4y0A
zh_1GDD+w5Fj!+qxvEAV;8et>nQx@(%G7g<#wxK9KNU<x$2hYm#%yKb&e>w~JOGJa;
z`4o<YTn3-?n3u|pS)rGp8DTnHwu@MQ!bgLRXC#}jW`vC@mfAPuc-)YDF1FU6_@ZPY
zN+s0@fhw8(=v0=g7E#F#crEpXXIrxlCQ@4t(R%-e!XqtNAy+V=HA`d#wfe$PQ&yYD
zbRyd&hvYCCR{>F7p>eKfv|6V0K4b9dW-TpVGvZRR+H`wuPN-Hau-PW=d5%<e{hB|u
z`kZWiQno(cJX}qYli&@SJ9&z_?*AoTNw!^xRVZ5v4m;KC&>f_#k@9=3S)C-4ChR7p
z^M{nV#Lmohz!!j#fXi>D8QW88Iu)kh5gZj>&Vxh4tA8+&2dS1^qwZi%Jx9XWe|uJl
z2C2=;l>MeuJ(>OgO4v%5&JrRFhh1XK(pci1Thr*n)~pkFYr(5|Af6T+&jVkz;K*50
za@{#gL!*hlB6YWOtJ8`gnUY^CYavftTQN{K&;h;<-kX!eG8oSn34`Ii3+i%C@?@{e
zp}H}eKc@rT@(}8DTmPDqJKT})jv(5DPmrA!e0+yXkGEpE%twyVxcx*v<r1@uZn7FW
zho@F8iO^~#VDJZK2}NI4IZOXKSBRUk4ze0{Kzoxh_d4_|NoF<p<TFIvHD({{>_o;+
zj6SZ;+bN@2q7#d_=ZH8ZFzwSKNY<T)vzAbd$9xM$VS)J*{sy#moz@f*!O%2jIH*JB
zUrj)4ncXKzsA$5F;O^d&=5oARHIc#%KEg)8PL>l&3-*^SK!zr=?8iA}P5C{!_6uMu
z>r%`F28JjbfdyC%C}10`-5(>`Vn6kr&rO-JV{6^D^*Nu^dOyjo&q0H7Em@svX50TM
zBZC%-)o(A0<<dw#**pTeqb9BiUvilFS`{Kl)BQxybNJf+21<7R!V)FYKwVg>g9vVZ
z{UbHk*={a@gmH<%S=hXvoobr-5Ce<E7@T{+o2Hqwt;Bi%*{Q4$1xTg<zm}Q!td_<=
zt8p1z*J~ToYQ*)=aRqJt;Xr4(#<Zq3>zT7;c<EPQD+lK?-eRpc9C@=NIm|c2pGQKh
zj|p<Fa6J=aW4_2Z=#O7)(8ls{I*Y*>&ouct1DHajH58i8tvh((V#~ACbJv(=lGD<h
zTjZX+Jl5)KQ=6Szx2P~D*cR_t&m%pxW)KL#nq;h?JGZXF%lWIUvy(&F&Mo74$#!mC
zgwvX3hR%wkW?}m!c!@1X8e{s4(rm5)yY*HuR6H)nBVygrx#erp$~Hy3oMv8qQZ+FH
z+_}Zz1DWf$F+iMK|Cs{T)tK-9;@6r{AT@74iVxemlvCK?1a;nV3&WqXI=|}SA)Nm+
zFNE`VZppycD#Ig|C&eJEt#=c@J&ye7(QzU^HtQ^ZjA0b^53kEqcoepQx+96slVYki
zOX>=vyeyU=ORe5lh28~WP4z*#s_HE3Q}BM8M~WU^k|;Ko%bPN1fzwP=H$50VDt;~T
zZJjAKCpNvsAQzoIVY3-B9b}NljBRvWn{&4I*rsHm9G)|TV5@MtUAvCO*S@_e;Xpk?
zW1kqKnE?(2yNJ}+AP33XYaQ-DjkTl%URHx?gIZM9bWh^&vQmaIb7&mz%1Q&t6CnXv
zvM7BI7WVDcY7U<}ANN`6{PLSLYx{j46K-1IrKoBu#Y7GEL16{B+`URV18z`Bin5yu
zcd$*kd?H~6t})W=&lhW}wl@B|%cZ*&3ChQw%~oBOW^LB8Wi}xm)W9N12xL4We7g%|
zDAgQIJ*&?&pCx|7^dO3_Qj9hoIq{=N9AzCB5w4u$y@XgWIcTq?Hi#~K=PjzUhhXLa
zieqi+3l|D27#8qI(@UDFbXGylf4{A}j5i1a`1fF9g7T@gM&TCb2DU({2Atd@YU!sY
z(EiOO>@84LxMNf!ya%JxG;pD+VmqRn-8Dq1MTAU;>YI<zn(=Ss7e3W07WC@w{M(N)
zno*a7xQkGyUJVFQ>}5{bFXWZooNo>R1u454oWxAviCN5S+ge9!p*~nCs4tt5Z_aw3
zUK9hH9~#y9=G+J5jk~Kti~4sN2x6f~mBhJ4W^suQ=Nh8UZF{8LqW3?HzWf9-Bvq!K
zd_B_K=j+|p*QT|xNOA-dAlBJaThMRb!B!k9o0Mmkh`k2EhOT6wazPNGP<eH3Jwc`s
zjIGODA<K$jY#r@~)rT(g-uta0$4QZA$Vij#qDDl?dp&OjgVXiQ?mmU;f>y1H++{A5
zL^^FXodxC^4ranbMx##W#M8D8u!s|vieB!Mp=7G&>zm3>D;0{}X%>P$s#-Yxt54eN
zYEHHhvu1B_l<6i_s==KPhI0eEWv40heyc9>RxXWQ<0wcGd$`gBH{l`5L!iBM4-L4`
zsL~Ff??Jbq<eK-kFyymLwI(A)B4e&VEuNeYzRb74zA*>rdokmiu0%py6FY|g#aZ7%
z!)!tn!g<FpdHRK*L%CvRZVKxGB6XI<1+K2aVP8q_g{cioc?@WZVyhH$%PB+*MhKq~
z<JlV$HrZ1@^w}}gBt{>ohXnZXk5o;iXw&YO+}HKnba?BjwJ)QdmAXri*(wdfLrIGi
zVFf75<hRsW*8EUfd3u~Nz<iA-3lUM*IZp<kPyKk)?HkCp`ZhYjWi1!xrr$*GQ<=2B
zWb<uEA|m0POeHNds@eB5n8xhJXn-t&SD0(NlQ%c<7_q1TiP-2EW1Lj{oKuWKvZ5<Z
zNpwiBtlr=wv{G>tu}tV%dFEx3vE<+~hpHUppdnPU9AUdD@*%~N+pf$wDXN9d35AqN
z0X;L0SW32h`1ugPPsHd#n3gJHv68V0+cd<IU5yQ2kxfi)OowWf@7%fG4%Mpe-CD|W
zsI%^4L2q;qE*|>zxPr`#7Z?0xl(=9nvufwsYXb==`ySgkxc2S3+5<85gM*j%_T5~2
zAU0^$7TGri2ljla9bLOssQpH~I^q=WkuDgg?GiogWF0O$h%{@j+8+M2s`t|C<DD5>
zcG1#cLSSGqtXL&^-AzC)AueaJeC7qGEEdC|2s7xejTeE1Yy?-e8;KmnVnEmE^x$;!
zJERBQ(2o<n!Va*qku&QPj7w!y48z&ehv{)Gnmf>peX(F(S>`hIn%;+4*DG^L#ken^
zsFBQQR=0^<f<{d2VAS6D_NC2l_nUt6U<@+M&t|o4W9r=rnyA&Cy>>EanSTn;ftK5L
z#X(?L)sS_-`SdQ~;@>JA&+K}U)q9JJFsUClBnPryY|6GbZAiv4c<06xx$Ydsxxq7R
zc7=8~dhDlm!*i}5%yJeVjH@5!=j4>tnGS;}#pv8{fJCMjhV&~*Y4UI75aB;-tFZ^p
z25n`w<(O<uB!(k&eLCd{A|-PYyjU~KywYS%Sx4FL?h~~-Ecqv`6^XeFK9R_*jm(;m
z@gi3&?v@%*<No>Pmxx^uT#6tPCx~40(S=MBCG;fhgpooLJIeJ7QjoiH>cuX}6`ly9
z63$^a;>GVZQA2%Hn6<C5&I~g5!Y#0tCweS;xlD_aBf#PXV<RvBSL@ionrb>8du-KX
zSRGa3Bn>%jXfb=VEVdzQU!arL$}xq%T6m(NaPP99%VS>q4aQxoU2IAQ;!#3moM5wQ
zFkUndFj5fHrGNV2I|dAt;WVYYJmyUGC=Dlr>1vxs#X4xY6AYVQf<?(_!RnU3^CIJR
zH3H3B!Gam$!CRCB$+KT4{mwaa5V<^<Qg}i*H7CqR@w8!~w&oxPN{POpjE$5<SxQ>Z
zH@J;W8{%UE{ZvV}i!DkDmtmf`3&vddZ7QV>O_ST==AWew6nqq{pLTC7gHUP_sM&`?
zr)h#Rd_eJMw=ZGnA=3?ZF`*I3y4o|d^h@*1B=SQ-_c+!CVpL8|Q?Pw<ym8Qs7mTC$
zH{=`%PMp3pM!%|dUF;0w^4fK_S;lBal*jzt-74x4@YlG&Kq(gtcUyDq^jZ2#Fxn?(
zA@2B!4J+Wgf|shs_%RV^yADCSF9wrhS7U9=p}O$xerKyWD6(PG8DXkNpeHxLb#QLI
zR@VM$rcCOBhEe9dG;nw``>wP#P0%W$&{}&bHEhk=%U><{ln2%<%(NFhdFH0)R7dsT
zI(t^AJ_=oD4x>miDi|EWX&z360WA`1Zr@l<-Ld|-jSlP}PD?-cY<RWw4(O*@zYM)E
zf#j6JS1et}A_7h$yo^D3t9@+y7Ur3!NOxk*aYl~qbfD&y;Iu&2F6tV(j*Md{?V)G;
zly+!$zPFLDGK?xKz@<h@O5tAP)<DfcX;ZFGeXDQGx0b7VmaO<ASMl@AScJ~Vwx=C_
zVSSf@If{WvkUt=#*DJ_<RuJ217DZ;DnVO8Q$5FHEM}>!_4vqJACP_iVNErc=6xh!R
zvrzm*aX}7R947zkP3G;{-2w|?%zUi*duj%~Z!b<Xf<Dixu<Q~`P|A0P?l%srEp<Bk
zt8Bs-MQ9~IA!vc==Wl=u^gCR}Ww32Voytm#)sxIkc()4m37hTeQBgk*!S?IkaE1uR
zG5IZS5hERJ9))NRTNm!(1oLWQMDHn2TMf}$ePi%;Ht7ywS`K6FTxgat`w9vqOnyY+
z<NW-_!Ooq#ojW^EWnKpxb98#+VAz;Lojd;`vU#m3S&7Iyq=N!>1qY@SqV`^VY#0zq
zpK;jOvphOOkp_q$lb_~TDs07nLbQs)z)`yV9$+pg!HyHACUvt^ev0%|7|UvXMfEqC
zIJc}OaJbaU7PTmMhkGqrNRbr2l=?@v$M=`1u@zlBh8L2;<47hCMywNdl;YJMnsX{M
zb|mstU3y02#Z-#x6kWlkaBvCr+f@VDDEF@ld@zRqt5U06zC`|Bu(sbSTh)-@G@dW=
zCG$6F?HBO5BskXjwD90#Po<A^=>tijVI&!nM9}7Z`hcVXCmyaPU;1NA)+#}F0kROd
zZoD8;hWwr~SV2`0vQ-hXRS~jP5wcYgvQ-hXKUWc?DlZwMS21h)(;3dKLD0$Qwqg*<
zxnTG%E=Om}2PDQV4WaLLGo&M(G={jWmA&p}i3F#}Z_-DY?cN{y^Ajj!Ld^XAn8vKc
zPk3vMnI5kTgFiOV+J!78v!L(q!M|`%9C!&h4x9o8fh3LvW&(?W5}*p$3~U1)2A%?1
zfY*TIKo{WZA|8+iECYPNX5eeU1Hj|JuYlKpHsAzs7D)U=(~^MkKr)a9<N>z;KHvf1
zDd0um9iR)i2=dQZ;96iFa5LZo?gZ`w9tU;;Ex-}r1keRs09olWU<xoBSPGN@Yk)1l
zJ-`ov=YRvi5#Uci7cdr7IvGd<76E;KCz8^%x6@ItaATTwc4?ZXtpLKm8~-^?`_8bQ
z_lW<hqSA72v0JZn-|E%f-gTwAdu3&@*S*SDx!PUjt6b@=uAam}x+mO9pSMW&Mt^gU
ztJe6hWmFpF#qNqqNyocVeDN!)5RX-*6~%7PdcCBwLVYy!qFc(n1Q8trV@6l0FO!HS
z<r*`(J6>g#w?c)ws(Pibv`U{;wSF!6__8Rd$10tst=6iwm0G3d)4cqfq!nxB{L{1v
zT7_n)=PM*xZ9;`nUT!@KBcPu&p-Z#%)B44_>{(e^aq^p*ta(&m_jJ$Fc!zdfa&o>0
zQjFUz`@7~?QL=)crmd@5$In3sh^!6=j)Q;ls_ht^PA3EWVq$IfxPI}D{s{vT2M%(&
z248UDkf9e{oHXo`;Uh+ly3{@TvN2=FjlX=t6<?Tm<yDiePQK>a$y26IyKZ{QjMSO4
zzWAlI^y@P+vu4l9o_oWM^K#}d@GM-EyBG_ZOAG$#rke|wEniV|%gSQ!s#{A+%Wf-Q
zT~S$eyRTX|)~sE({>xw4P_uE9BI{;VNSAslODlA*k22k;Wifu{^LL&$S-X}N%j9XE
zDsQH@ci7qG)w6wGuZElJ)$@wV4fQ-H>N&l<ymF;P_8Ap=>1war>+@Cm+?qC!&Rslj
zL2j<)Bd=QS-1&2&UbV~xIq7rf_xLQDmOOdNz=ZS)cTrVUdFjd`y_6wSQdI3;UBs{~
z!e7_DtE+SwvgMUU4BZm1JHs8xyS(%kUy*OUyOcWneBPCM`T9u-o^o$dwU>cip%<+r
zCNZK?zr5OAZB$iN`uO54TJ2s%;a6AsyrjY7YE^<ss_>Lw$~Spn!d33{o?;lJos&Cv
zUewIdOG>NVMb*{b)wh(dcNZJJ(u!N%6(qGria|w6D@yg!qVm!&tK<_FOL*ppRM<;Q
z_btY)yt~&|8oubVPIAxH-2`1-S*^RvOK<a%x>U#Ktv1SacjYSg%A)de$&8kgGF`Q@
za&?uO;uEf3S?;^Sy~?OqsoGS{@S>hVRaEOfW2H{z`L8}^mY3%gl~$;_OTDj^daLPO
zQEA*-;;ybLTFFX5a0WmT(>bcaqTB15KJC?AcdylXixyk$t(Q>f%8HfVNuR$xBp)eT
zvgDCLN>aX_42r|wubnR6jS98uFmifAxJ$f6RaR+9=i2K&qmFA!qavz)>xnn*yz#2_
z;?IaTRpM0{jJ7qUKHVrP@97}vNtJ<=i#c(gwqIUZA<OpF3>;a#)xz3cu4_^xUQfN%
zddfVguB5w)y=zKWdV9i#+sM1Fih0APAT84~GgUiZquR$H$8ea{47*ajggv2HM!{`;
z!=Jxh!jX!L^dgEd(CYH2X{jc?&wIP!t(L;bC|?v_VCX<rvel(bC<dMMw+wfq!l;%8
zTwC;aobt4NvTDO~j(cwfy;fPV+FPMh2MMd%@SI_be771Buv#^^gjMrt6^ocI6Shj$
z=kAqAl91)it46S<<&>`URaRH7(%pHbs+JiOCw8~TJZsTodD0S?50fTM(q^)E-|AyE
zt0-bcHY#qbs9am|Mfxz@gjupik4{Kn6O~{y+!C1|CzV~0(baDx&%#KT-@Q@KO+2g3
z5Px(|bU!05+5NmN>KW!*w?DG^-Ot~MdhS<Sdq-_uEgQ1!j@mmm*A9t`V@KY)bt?r*
zPOkOT)@u%J!sXLF`L*n~Y|0)_J=wb_)YjJ$OJiFuDJgL{;@4GGt*xr+wIB2OfBes_
z_5C*i{K)#(_shB7v%!=;>)#gb)Bk#huhV+|#b}@JUvvtawVr>m5R*U8zes%d|M>pb
zKGpwjG%Ef-9sx0R-Tx3U{#?IE4~n}vrsrR5%;)<TiGQv!{U7uDYcoJ{8p6Lwj`G&?
z>=Kdc|G=+r_|I3{o=`5W=h=FSiIGWATesQ2W$PVZt#4=y+}ZTCySCl^^>5ts&3nIf
z-~A7K`@!#g_j?a*fB2C{AA9`!JAUxPAN}~BpZLj>KmC`VJ@xaQPe1eQbHDiI^S}D_
zuIAl)_Wq`&b>IF2FTD7#FTH&5&~FdF^6G1^A9>@=w~qeq_kU<R_Vyo-|Jyt7n(coI
zp7{6o-tYL}&mW%r=+x=XGk^KGi_3_A^MUC62cFM$Ao{Pa|9^G<e{=i)wFBw-zpDf3
ze|7z{vuCVcJ)>Gk6IwC9E8RK#-14xVpO%wzb#d|4Jn-}6Xj(eJnV55&Iy!6fE7x>C
zFW|H!-nrf?j-*zAbmLZ|TGzB2jB=I64dBX>R(h4MRA>@8MZT3KxU;>t_zVuJ^6iGA
z3iU`nlD<Z|lBPylk`7Qoy!DcX#Fw}dN6RhJ4PP-IBt2iLdRkm!_^QKx`QG9RZ}?>~
zXta3eR92|3xklJ6(j~4&JdN-g;UtX4ca1}Sn8uRN(X?`HuC5L};=iQY>sxS38Rvw#
zJ%?nWc<^mrQMI1V8FLLJhbp5=`C0E)GFlEarJ`HC*H^Af*OugFEt-7oq|AAcAIOue
zDFFqcJQRx>TJ1xXsW}ZmJJ1}o3XMY>(NwgUG#tN-1@jjySv*#o#F<y#BlM(6x2R<B
zUtO&HZziwxoGMl?s;ra@_+?wpf9h}T1?k#BID$5bJzdkDEY-A!?mu@@kWr!JX&N+d
z<wo9*Lc5b+<b7YC@4p<=`+I%V_rHvT-Y0<HF5Fkb&ywDqQQ=CaqB9SWUnHNt<+w1l
z_xFQQ@g?4|KHp#L^ZmA2R(uJ29na^>r{jxOxbuA<lXm{^Iq7LyDImY|#V?%G`+MJV
zPJ~7(zw^ca_WaNO{yR@k-A+V3AL-K`-&@oZ?nhD2ecRnz&^y2AbOzj%rd<liFH+v<
z?}dCT>hpb9pK?62tatqAe$8H<rY#5L7fHWw`JOH7{XIIq#5+*l`+MK`FRkzWy>I;A
z*M0W)UvKXHy>EX$_08Vj`=+0B-)Db6zP<PNzU9B^@!sG2&d<?1tnV7X!teL=dEasz
zeWG_deZP0^?)|-QJ->Y*O}qIFnS_5Aagx&7B5%Fj|K+XxZM>C5F>|~XULQoJ42xox
zq5I0S)<DC7ufsQ8xDXjaT90rdD(v}1rTXkjUoI4#a<8>RYTwi{6wf3ajBWBKHi+p_
ziDnm76qkcZd?cynR2CcM-q{ds=R><8^qX3iQ0_B)kc=S;=CbQT6xXzqvGcq|YrLQG
z|4UCQR>Jw3HqoA2?ggi~ES4OkAnC=$5RJiu;$otiDOD0TqjL3XN;I#ug6wBX47Pr#
zlU1_Wr)wQjdMjmEKGGUrw89iyo^Y)s6{*4E^;KTv-ZQ=BURtqF1+KF%j!^NsTkwY}
ze*@BeMFjcKvh7PMN>mFKXRTWavPJDlTro2)wNsY!ets=>Zgr*?TKcVCpNHy7*S#w_
z2#%siU~uYUv!Qb;CWrR0dbSuEH>;9(q{`ZFV&_T^2!YdEJhuWCm{9UGtvT8sEF|Ke
zD{<2^JeoE{T4q63jy$(f8aODW#cIre0cl^fFD|bpfW=ptDQ{tJ%9rH1o8vM|-c%7!
zO4~=3{)wpeTCB*hbHQ=GWzVOr)fm!F#m<9{7$y-inx3P~VctXE9!ak#&aEn~usZd|
z7|AfJhr*ew3m2n0UE3vje)@wp?>sT`wJrAi(qeB$Ns(`HWsXpcuV1fwwcY1Vhtc||
z>IZAqXj+jy&!Ua17AUYSG`zm`9<NVvXJ8ko@-lnMq^%d1uDmTgDt{E!HsJwA<K(Kb
zs?fj1aI4a*)i~uzd%(6xFJDrz7GziZfhxfwuhkvPA|(j-&K8w&cu}Bd?~QtA`hxLa
zA2Yk$s4kJTuQyh$^7@!*@5Ii_$SJC_+L4~P)Yjb=iz_1yq?ys7Xp1y!Zb{qAY$9Gp
zZy&<6OaAi|6ULgN+PgANB=>H%-;Y#{a!bEV=`yv9^2%y&c)H$cjh66wl&(DxRhtEd
zUS;SqdhhKODqrg-GcQ-~p7ZO&tDIzty+F9MtE-B9-tOAw_4c9EN2H8V<0!AlS1Jse
zbnV8hMf0=faV{t>=g?GPTLgPS($%zAtvJOCR$1@kr7gmpEAtpkL`ts;p)+7_G2o}s
zX8-&9|FZ>li2^!);#w4{a5-IJH_Ab<NwA&s{^YyB|Nj2B1wL;J%zr2C7e5{L>&!om
zNmFB|{B7`Sfa6oBRs<IQlRp`!7XgtmX$wEwapk&a954_-4n^w^!~=<dBkYQwyh{<}
zoABf!-y~g$D=u0vR30*2#BVTgK^P?O(SZ0*1>`+F{GJhhXJJ=y7KQzD!!FCSO1}VC
z@@5%U>8!?e11z-K2*3wOS*0FQo?1Z4To-mX<H~nGAm6tDQXaW*cLng>@cVXLDc_@j
z<oA6*!aWU0on8Xu`|E&wPohzzeIjkfWB1w+BQH_E$a}<%e2TpHb^Ctr`~KI$pYMAl
zoqs&nb>5#<SNC~;{}^p?ex`&~zw;Bt|1s(>wK(q(2=C<Q9RluuoHn2)|ILR&$x!gH
zSi9p<Hmnt!*KZyj?wrT}U_ESq%yR3#Cla)pmbS50xjP8o{K%V+xUJ8h`df$WtNhZ!
z?$1AG`1El2orHh+;o}cqqW#;$=EFBxiADYGPJiQe6+?72Eqrs?n{I9Sn`Lia8x_)e
ztUG+<_ifP8uGwhCEdO_lW|t8T8Ck<W74dKM*mg;JuN3~)cPVGzvWk7^$gd=rrgglJ
z-J}oFwE7Y0+I{3N;l-7{7Cc9OvbT1cX$r@95m)x?hj3*tci_q-KKgE&+KYdTD>z0y
z?uEEF;|fkQ7IzqK*E?z2CAfQWhvVLfE4V^2?kL<$+)HuW{w+;&<L<y6jr-*BH0?56
z7w$S-4R<|G#~;(QFXOi1%3wQ+8^V1NcNuiu&jSn}g-1!cQm62uq)Gdf(f9X#n5NwW
zYy<8D>VYjlEwB!#0!o0J0S}N3%mk(bQ-EaPN?-yo7H|V2fFxiD-~ti>JJ9)O`UEfm
z3Ezf$1ULxn1%3%U2|Nls1Uv|A12zCvK!1BrpG%)kqCT1Q`JGq%b=VaC$ry<tp2QV5
z@{@LQ$9+S(@ti*yC(*y!Dl2}+2Nplele;+j^MCl+lliyBKS;e?D5H`w9mzcUS@;_Q
z@{_Tc3j7lw<KkO@C}w>H_z)OO!z2Uq0lAnGi8F(51;AS1Uf?O<Fz{zUE>~U+<N)Qs
ffA`;C6IqGv^RtD2k$RV(<URs$Gq4!wJAVETV*lf-

literal 0
HcmV?d00001

diff --git a/vendor/setuptools-39.0.1/setuptools/launch.py b/vendor/setuptools-39.0.1/setuptools/launch.py
new file mode 100644
index 00000000..308283ea
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/launch.py
@@ -0,0 +1,35 @@
+"""
+Launch the Python script on the command line after
+setuptools is bootstrapped via import.
+"""
+
+# Note that setuptools gets imported implicitly by the
+# invocation of this script using python -m setuptools.launch
+
+import tokenize
+import sys
+
+
+def run():
+    """
+    Run the script in sys.argv[1] as if it had
+    been invoked naturally.
+    """
+    __builtins__
+    script_name = sys.argv[1]
+    namespace = dict(
+        __file__=script_name,
+        __name__='__main__',
+        __doc__=None,
+    )
+    sys.argv[:] = sys.argv[1:]
+
+    open_ = getattr(tokenize, 'open', open)
+    script = open_(script_name).read()
+    norm_script = script.replace('\\r\\n', '\\n')
+    code = compile(norm_script, script_name, 'exec')
+    exec(code, namespace)
+
+
+if __name__ == '__main__':
+    run()
diff --git a/vendor/setuptools-39.0.1/setuptools/lib2to3_ex.py b/vendor/setuptools-39.0.1/setuptools/lib2to3_ex.py
new file mode 100644
index 00000000..4b1a73fe
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/lib2to3_ex.py
@@ -0,0 +1,62 @@
+"""
+Customized Mixin2to3 support:
+
+ - adds support for converting doctests
+
+
+This module raises an ImportError on Python 2.
+"""
+
+from distutils.util import Mixin2to3 as _Mixin2to3
+from distutils import log
+from lib2to3.refactor import RefactoringTool, get_fixers_from_package
+
+import setuptools
+
+
+class DistutilsRefactoringTool(RefactoringTool):
+    def log_error(self, msg, *args, **kw):
+        log.error(msg, *args)
+
+    def log_message(self, msg, *args):
+        log.info(msg, *args)
+
+    def log_debug(self, msg, *args):
+        log.debug(msg, *args)
+
+
+class Mixin2to3(_Mixin2to3):
+    def run_2to3(self, files, doctests=False):
+        # See of the distribution option has been set, otherwise check the
+        # setuptools default.
+        if self.distribution.use_2to3 is not True:
+            return
+        if not files:
+            return
+        log.info("Fixing " + " ".join(files))
+        self.__build_fixer_names()
+        self.__exclude_fixers()
+        if doctests:
+            if setuptools.run_2to3_on_doctests:
+                r = DistutilsRefactoringTool(self.fixer_names)
+                r.refactor(files, write=True, doctests_only=True)
+        else:
+            _Mixin2to3.run_2to3(self, files)
+
+    def __build_fixer_names(self):
+        if self.fixer_names:
+            return
+        self.fixer_names = []
+        for p in setuptools.lib2to3_fixer_packages:
+            self.fixer_names.extend(get_fixers_from_package(p))
+        if self.distribution.use_2to3_fixers is not None:
+            for p in self.distribution.use_2to3_fixers:
+                self.fixer_names.extend(get_fixers_from_package(p))
+
+    def __exclude_fixers(self):
+        excluded_fixers = getattr(self, 'exclude_fixers', [])
+        if self.distribution.use_2to3_exclude_fixers is not None:
+            excluded_fixers.extend(self.distribution.use_2to3_exclude_fixers)
+        for fixer_name in excluded_fixers:
+            if fixer_name in self.fixer_names:
+                self.fixer_names.remove(fixer_name)
diff --git a/vendor/setuptools-39.0.1/setuptools/monkey.py b/vendor/setuptools-39.0.1/setuptools/monkey.py
new file mode 100644
index 00000000..d9eb7d7b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/monkey.py
@@ -0,0 +1,197 @@
+"""
+Monkey patching of distutils.
+"""
+
+import sys
+import distutils.filelist
+import platform
+import types
+import functools
+from importlib import import_module
+import inspect
+
+from setuptools.extern import six
+
+import setuptools
+
+__all__ = []
+"""
+Everything is private. Contact the project team
+if you think you need this functionality.
+"""
+
+
+def _get_mro(cls):
+    """
+    Returns the bases classes for cls sorted by the MRO.
+
+    Works around an issue on Jython where inspect.getmro will not return all
+    base classes if multiple classes share the same name. Instead, this
+    function will return a tuple containing the class itself, and the contents
+    of cls.__bases__. See https://github.com/pypa/setuptools/issues/1024.
+    """
+    if platform.python_implementation() == "Jython":
+        return (cls,) + cls.__bases__
+    return inspect.getmro(cls)
+
+
+def get_unpatched(item):
+    lookup = (
+        get_unpatched_class if isinstance(item, six.class_types) else
+        get_unpatched_function if isinstance(item, types.FunctionType) else
+        lambda item: None
+    )
+    return lookup(item)
+
+
+def get_unpatched_class(cls):
+    """Protect against re-patching the distutils if reloaded
+
+    Also ensures that no other distutils extension monkeypatched the distutils
+    first.
+    """
+    external_bases = (
+        cls
+        for cls in _get_mro(cls)
+        if not cls.__module__.startswith('setuptools')
+    )
+    base = next(external_bases)
+    if not base.__module__.startswith('distutils'):
+        msg = "distutils has already been patched by %r" % cls
+        raise AssertionError(msg)
+    return base
+
+
+def patch_all():
+    # we can't patch distutils.cmd, alas
+    distutils.core.Command = setuptools.Command
+
+    has_issue_12885 = sys.version_info <= (3, 5, 3)
+
+    if has_issue_12885:
+        # fix findall bug in distutils (http://bugs.python.org/issue12885)
+        distutils.filelist.findall = setuptools.findall
+
+    needs_warehouse = (
+        sys.version_info < (2, 7, 13)
+        or
+        (3, 0) < sys.version_info < (3, 3, 7)
+        or
+        (3, 4) < sys.version_info < (3, 4, 6)
+        or
+        (3, 5) < sys.version_info <= (3, 5, 3)
+    )
+
+    if needs_warehouse:
+        warehouse = 'https://upload.pypi.org/legacy/'
+        distutils.config.PyPIRCCommand.DEFAULT_REPOSITORY = warehouse
+
+    _patch_distribution_metadata_write_pkg_file()
+    _patch_distribution_metadata_write_pkg_info()
+
+    # Install Distribution throughout the distutils
+    for module in distutils.dist, distutils.core, distutils.cmd:
+        module.Distribution = setuptools.dist.Distribution
+
+    # Install the patched Extension
+    distutils.core.Extension = setuptools.extension.Extension
+    distutils.extension.Extension = setuptools.extension.Extension
+    if 'distutils.command.build_ext' in sys.modules:
+        sys.modules['distutils.command.build_ext'].Extension = (
+            setuptools.extension.Extension
+        )
+
+    patch_for_msvc_specialized_compiler()
+
+
+def _patch_distribution_metadata_write_pkg_file():
+    """Patch write_pkg_file to also write Requires-Python/Requires-External"""
+    distutils.dist.DistributionMetadata.write_pkg_file = (
+        setuptools.dist.write_pkg_file
+    )
+
+
+def _patch_distribution_metadata_write_pkg_info():
+    """
+    Workaround issue #197 - Python 3 prior to 3.2.2 uses an environment-local
+    encoding to save the pkg_info. Monkey-patch its write_pkg_info method to
+    correct this undesirable behavior.
+    """
+    environment_local = (3,) <= sys.version_info[:3] < (3, 2, 2)
+    if not environment_local:
+        return
+
+    distutils.dist.DistributionMetadata.write_pkg_info = (
+        setuptools.dist.write_pkg_info
+    )
+
+
+def patch_func(replacement, target_mod, func_name):
+    """
+    Patch func_name in target_mod with replacement
+
+    Important - original must be resolved by name to avoid
+    patching an already patched function.
+    """
+    original = getattr(target_mod, func_name)
+
+    # set the 'unpatched' attribute on the replacement to
+    # point to the original.
+    vars(replacement).setdefault('unpatched', original)
+
+    # replace the function in the original module
+    setattr(target_mod, func_name, replacement)
+
+
+def get_unpatched_function(candidate):
+    return getattr(candidate, 'unpatched')
+
+
+def patch_for_msvc_specialized_compiler():
+    """
+    Patch functions in distutils to use standalone Microsoft Visual C++
+    compilers.
+    """
+    # import late to avoid circular imports on Python < 3.5
+    msvc = import_module('setuptools.msvc')
+
+    if platform.system() != 'Windows':
+        # Compilers only availables on Microsoft Windows
+        return
+
+    def patch_params(mod_name, func_name):
+        """
+        Prepare the parameters for patch_func to patch indicated function.
+        """
+        repl_prefix = 'msvc9_' if 'msvc9' in mod_name else 'msvc14_'
+        repl_name = repl_prefix + func_name.lstrip('_')
+        repl = getattr(msvc, repl_name)
+        mod = import_module(mod_name)
+        if not hasattr(mod, func_name):
+            raise ImportError(func_name)
+        return repl, mod, func_name
+
+    # Python 2.7 to 3.4
+    msvc9 = functools.partial(patch_params, 'distutils.msvc9compiler')
+
+    # Python 3.5+
+    msvc14 = functools.partial(patch_params, 'distutils._msvccompiler')
+
+    try:
+        # Patch distutils.msvc9compiler
+        patch_func(*msvc9('find_vcvarsall'))
+        patch_func(*msvc9('query_vcvarsall'))
+    except ImportError:
+        pass
+
+    try:
+        # Patch distutils._msvccompiler._get_vc_env
+        patch_func(*msvc14('_get_vc_env'))
+    except ImportError:
+        pass
+
+    try:
+        # Patch distutils._msvccompiler.gen_lib_options for Numpy
+        patch_func(*msvc14('gen_lib_options'))
+    except ImportError:
+        pass
diff --git a/vendor/setuptools-39.0.1/setuptools/msvc.py b/vendor/setuptools-39.0.1/setuptools/msvc.py
new file mode 100644
index 00000000..5e20b3f1
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/msvc.py
@@ -0,0 +1,1302 @@
+"""
+Improved support for Microsoft Visual C++ compilers.
+
+Known supported compilers:
+--------------------------
+Microsoft Visual C++ 9.0:
+    Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64)
+    Microsoft Windows SDK 6.1 (x86, x64, ia64)
+    Microsoft Windows SDK 7.0 (x86, x64, ia64)
+
+Microsoft Visual C++ 10.0:
+    Microsoft Windows SDK 7.1 (x86, x64, ia64)
+
+Microsoft Visual C++ 14.0:
+    Microsoft Visual C++ Build Tools 2015 (x86, x64, arm)
+    Microsoft Visual Studio 2017 (x86, x64, arm, arm64)
+    Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64)
+"""
+
+import os
+import sys
+import platform
+import itertools
+import distutils.errors
+from setuptools.extern.packaging.version import LegacyVersion
+
+from setuptools.extern.six.moves import filterfalse
+
+from .monkey import get_unpatched
+
+if platform.system() == 'Windows':
+    from setuptools.extern.six.moves import winreg
+    safe_env = os.environ
+else:
+    """
+    Mock winreg and environ so the module can be imported
+    on this platform.
+    """
+
+    class winreg:
+        HKEY_USERS = None
+        HKEY_CURRENT_USER = None
+        HKEY_LOCAL_MACHINE = None
+        HKEY_CLASSES_ROOT = None
+
+    safe_env = dict()
+
+_msvc9_suppress_errors = (
+    # msvc9compiler isn't available on some platforms
+    ImportError,
+
+    # msvc9compiler raises DistutilsPlatformError in some
+    # environments. See #1118.
+    distutils.errors.DistutilsPlatformError,
+)
+
+try:
+    from distutils.msvc9compiler import Reg
+except _msvc9_suppress_errors:
+    pass
+
+
+def msvc9_find_vcvarsall(version):
+    """
+    Patched "distutils.msvc9compiler.find_vcvarsall" to use the standalone
+    compiler build for Python (VCForPython). Fall back to original behavior
+    when the standalone compiler is not available.
+
+    Redirect the path of "vcvarsall.bat".
+
+    Known supported compilers
+    -------------------------
+    Microsoft Visual C++ 9.0:
+        Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64)
+
+    Parameters
+    ----------
+    version: float
+        Required Microsoft Visual C++ version.
+
+    Return
+    ------
+    vcvarsall.bat path: str
+    """
+    VC_BASE = r'Software\%sMicrosoft\DevDiv\VCForPython\%0.1f'
+    key = VC_BASE % ('', version)
+    try:
+        # Per-user installs register the compiler path here
+        productdir = Reg.get_value(key, "installdir")
+    except KeyError:
+        try:
+            # All-user installs on a 64-bit system register here
+            key = VC_BASE % ('Wow6432Node\\', version)
+            productdir = Reg.get_value(key, "installdir")
+        except KeyError:
+            productdir = None
+
+    if productdir:
+        vcvarsall = os.path.os.path.join(productdir, "vcvarsall.bat")
+        if os.path.isfile(vcvarsall):
+            return vcvarsall
+
+    return get_unpatched(msvc9_find_vcvarsall)(version)
+
+
+def msvc9_query_vcvarsall(ver, arch='x86', *args, **kwargs):
+    """
+    Patched "distutils.msvc9compiler.query_vcvarsall" for support extra
+    compilers.
+
+    Set environment without use of "vcvarsall.bat".
+
+    Known supported compilers
+    -------------------------
+    Microsoft Visual C++ 9.0:
+        Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64)
+        Microsoft Windows SDK 6.1 (x86, x64, ia64)
+        Microsoft Windows SDK 7.0 (x86, x64, ia64)
+
+    Microsoft Visual C++ 10.0:
+        Microsoft Windows SDK 7.1 (x86, x64, ia64)
+
+    Parameters
+    ----------
+    ver: float
+        Required Microsoft Visual C++ version.
+    arch: str
+        Target architecture.
+
+    Return
+    ------
+    environment: dict
+    """
+    # Try to get environement from vcvarsall.bat (Classical way)
+    try:
+        orig = get_unpatched(msvc9_query_vcvarsall)
+        return orig(ver, arch, *args, **kwargs)
+    except distutils.errors.DistutilsPlatformError:
+        # Pass error if Vcvarsall.bat is missing
+        pass
+    except ValueError:
+        # Pass error if environment not set after executing vcvarsall.bat
+        pass
+
+    # If error, try to set environment directly
+    try:
+        return EnvironmentInfo(arch, ver).return_env()
+    except distutils.errors.DistutilsPlatformError as exc:
+        _augment_exception(exc, ver, arch)
+        raise
+
+
+def msvc14_get_vc_env(plat_spec):
+    """
+    Patched "distutils._msvccompiler._get_vc_env" for support extra
+    compilers.
+
+    Set environment without use of "vcvarsall.bat".
+
+    Known supported compilers
+    -------------------------
+    Microsoft Visual C++ 14.0:
+        Microsoft Visual C++ Build Tools 2015 (x86, x64, arm)
+        Microsoft Visual Studio 2017 (x86, x64, arm, arm64)
+        Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64)
+
+    Parameters
+    ----------
+    plat_spec: str
+        Target architecture.
+
+    Return
+    ------
+    environment: dict
+    """
+    # Try to get environment from vcvarsall.bat (Classical way)
+    try:
+        return get_unpatched(msvc14_get_vc_env)(plat_spec)
+    except distutils.errors.DistutilsPlatformError:
+        # Pass error Vcvarsall.bat is missing
+        pass
+
+    # If error, try to set environment directly
+    try:
+        return EnvironmentInfo(plat_spec, vc_min_ver=14.0).return_env()
+    except distutils.errors.DistutilsPlatformError as exc:
+        _augment_exception(exc, 14.0)
+        raise
+
+
+def msvc14_gen_lib_options(*args, **kwargs):
+    """
+    Patched "distutils._msvccompiler.gen_lib_options" for fix
+    compatibility between "numpy.distutils" and "distutils._msvccompiler"
+    (for Numpy < 1.11.2)
+    """
+    if "numpy.distutils" in sys.modules:
+        import numpy as np
+        if LegacyVersion(np.__version__) < LegacyVersion('1.11.2'):
+            return np.distutils.ccompiler.gen_lib_options(*args, **kwargs)
+    return get_unpatched(msvc14_gen_lib_options)(*args, **kwargs)
+
+
+def _augment_exception(exc, version, arch=''):
+    """
+    Add details to the exception message to help guide the user
+    as to what action will resolve it.
+    """
+    # Error if MSVC++ directory not found or environment not set
+    message = exc.args[0]
+
+    if "vcvarsall" in message.lower() or "visual c" in message.lower():
+        # Special error message if MSVC++ not installed
+        tmpl = 'Microsoft Visual C++ {version:0.1f} is required.'
+        message = tmpl.format(**locals())
+        msdownload = 'www.microsoft.com/download/details.aspx?id=%d'
+        if version == 9.0:
+            if arch.lower().find('ia64') > -1:
+                # For VC++ 9.0, if IA64 support is needed, redirect user
+                # to Windows SDK 7.0
+                message += ' Get it with "Microsoft Windows SDK 7.0": '
+                message += msdownload % 3138
+            else:
+                # For VC++ 9.0 redirect user to Vc++ for Python 2.7 :
+                # This redirection link is maintained by Microsoft.
+                # Contact vspython@microsoft.com if it needs updating.
+                message += ' Get it from http://aka.ms/vcpython27'
+        elif version == 10.0:
+            # For VC++ 10.0 Redirect user to Windows SDK 7.1
+            message += ' Get it with "Microsoft Windows SDK 7.1": '
+            message += msdownload % 8279
+        elif version >= 14.0:
+            # For VC++ 14.0 Redirect user to Visual C++ Build Tools
+            message += (' Get it with "Microsoft Visual C++ Build Tools": '
+                        r'http://landinghub.visualstudio.com/'
+                        'visual-cpp-build-tools')
+
+    exc.args = (message, )
+
+
+class PlatformInfo:
+    """
+    Current and Target Architectures informations.
+
+    Parameters
+    ----------
+    arch: str
+        Target architecture.
+    """
+    current_cpu = safe_env.get('processor_architecture', '').lower()
+
+    def __init__(self, arch):
+        self.arch = arch.lower().replace('x64', 'amd64')
+
+    @property
+    def target_cpu(self):
+        return self.arch[self.arch.find('_') + 1:]
+
+    def target_is_x86(self):
+        return self.target_cpu == 'x86'
+
+    def current_is_x86(self):
+        return self.current_cpu == 'x86'
+
+    def current_dir(self, hidex86=False, x64=False):
+        """
+        Current platform specific subfolder.
+
+        Parameters
+        ----------
+        hidex86: bool
+            return '' and not '\x86' if architecture is x86.
+        x64: bool
+            return '\x64' and not '\amd64' if architecture is amd64.
+
+        Return
+        ------
+        subfolder: str
+            '\target', or '' (see hidex86 parameter)
+        """
+        return (
+            '' if (self.current_cpu == 'x86' and hidex86) else
+            r'\x64' if (self.current_cpu == 'amd64' and x64) else
+            r'\%s' % self.current_cpu
+        )
+
+    def target_dir(self, hidex86=False, x64=False):
+        r"""
+        Target platform specific subfolder.
+
+        Parameters
+        ----------
+        hidex86: bool
+            return '' and not '\x86' if architecture is x86.
+        x64: bool
+            return '\x64' and not '\amd64' if architecture is amd64.
+
+        Return
+        ------
+        subfolder: str
+            '\current', or '' (see hidex86 parameter)
+        """
+        return (
+            '' if (self.target_cpu == 'x86' and hidex86) else
+            r'\x64' if (self.target_cpu == 'amd64' and x64) else
+            r'\%s' % self.target_cpu
+        )
+
+    def cross_dir(self, forcex86=False):
+        r"""
+        Cross platform specific subfolder.
+
+        Parameters
+        ----------
+        forcex86: bool
+            Use 'x86' as current architecture even if current acritecture is
+            not x86.
+
+        Return
+        ------
+        subfolder: str
+            '' if target architecture is current architecture,
+            '\current_target' if not.
+        """
+        current = 'x86' if forcex86 else self.current_cpu
+        return (
+            '' if self.target_cpu == current else
+            self.target_dir().replace('\\', '\\%s_' % current)
+        )
+
+
+class RegistryInfo:
+    """
+    Microsoft Visual Studio related registry informations.
+
+    Parameters
+    ----------
+    platform_info: PlatformInfo
+        "PlatformInfo" instance.
+    """
+    HKEYS = (winreg.HKEY_USERS,
+             winreg.HKEY_CURRENT_USER,
+             winreg.HKEY_LOCAL_MACHINE,
+             winreg.HKEY_CLASSES_ROOT)
+
+    def __init__(self, platform_info):
+        self.pi = platform_info
+
+    @property
+    def visualstudio(self):
+        """
+        Microsoft Visual Studio root registry key.
+        """
+        return 'VisualStudio'
+
+    @property
+    def sxs(self):
+        """
+        Microsoft Visual Studio SxS registry key.
+        """
+        return os.path.join(self.visualstudio, 'SxS')
+
+    @property
+    def vc(self):
+        """
+        Microsoft Visual C++ VC7 registry key.
+        """
+        return os.path.join(self.sxs, 'VC7')
+
+    @property
+    def vs(self):
+        """
+        Microsoft Visual Studio VS7 registry key.
+        """
+        return os.path.join(self.sxs, 'VS7')
+
+    @property
+    def vc_for_python(self):
+        """
+        Microsoft Visual C++ for Python registry key.
+        """
+        return r'DevDiv\VCForPython'
+
+    @property
+    def microsoft_sdk(self):
+        """
+        Microsoft SDK registry key.
+        """
+        return 'Microsoft SDKs'
+
+    @property
+    def windows_sdk(self):
+        """
+        Microsoft Windows/Platform SDK registry key.
+        """
+        return os.path.join(self.microsoft_sdk, 'Windows')
+
+    @property
+    def netfx_sdk(self):
+        """
+        Microsoft .NET Framework SDK registry key.
+        """
+        return os.path.join(self.microsoft_sdk, 'NETFXSDK')
+
+    @property
+    def windows_kits_roots(self):
+        """
+        Microsoft Windows Kits Roots registry key.
+        """
+        return r'Windows Kits\Installed Roots'
+
+    def microsoft(self, key, x86=False):
+        """
+        Return key in Microsoft software registry.
+
+        Parameters
+        ----------
+        key: str
+            Registry key path where look.
+        x86: str
+            Force x86 software registry.
+
+        Return
+        ------
+        str: value
+        """
+        node64 = '' if self.pi.current_is_x86() or x86 else 'Wow6432Node'
+        return os.path.join('Software', node64, 'Microsoft', key)
+
+    def lookup(self, key, name):
+        """
+        Look for values in registry in Microsoft software registry.
+
+        Parameters
+        ----------
+        key: str
+            Registry key path where look.
+        name: str
+            Value name to find.
+
+        Return
+        ------
+        str: value
+        """
+        KEY_READ = winreg.KEY_READ
+        openkey = winreg.OpenKey
+        ms = self.microsoft
+        for hkey in self.HKEYS:
+            try:
+                bkey = openkey(hkey, ms(key), 0, KEY_READ)
+            except (OSError, IOError):
+                if not self.pi.current_is_x86():
+                    try:
+                        bkey = openkey(hkey, ms(key, True), 0, KEY_READ)
+                    except (OSError, IOError):
+                        continue
+                else:
+                    continue
+            try:
+                return winreg.QueryValueEx(bkey, name)[0]
+            except (OSError, IOError):
+                pass
+
+
+class SystemInfo:
+    """
+    Microsoft Windows and Visual Studio related system inormations.
+
+    Parameters
+    ----------
+    registry_info: RegistryInfo
+        "RegistryInfo" instance.
+    vc_ver: float
+        Required Microsoft Visual C++ version.
+    """
+
+    # Variables and properties in this class use originals CamelCase variables
+    # names from Microsoft source files for more easy comparaison.
+    WinDir = safe_env.get('WinDir', '')
+    ProgramFiles = safe_env.get('ProgramFiles', '')
+    ProgramFilesx86 = safe_env.get('ProgramFiles(x86)', ProgramFiles)
+
+    def __init__(self, registry_info, vc_ver=None):
+        self.ri = registry_info
+        self.pi = self.ri.pi
+        self.vc_ver = vc_ver or self._find_latest_available_vc_ver()
+
+    def _find_latest_available_vc_ver(self):
+        try:
+            return self.find_available_vc_vers()[-1]
+        except IndexError:
+            err = 'No Microsoft Visual C++ version found'
+            raise distutils.errors.DistutilsPlatformError(err)
+
+    def find_available_vc_vers(self):
+        """
+        Find all available Microsoft Visual C++ versions.
+        """
+        ms = self.ri.microsoft
+        vckeys = (self.ri.vc, self.ri.vc_for_python, self.ri.vs)
+        vc_vers = []
+        for hkey in self.ri.HKEYS:
+            for key in vckeys:
+                try:
+                    bkey = winreg.OpenKey(hkey, ms(key), 0, winreg.KEY_READ)
+                except (OSError, IOError):
+                    continue
+                subkeys, values, _ = winreg.QueryInfoKey(bkey)
+                for i in range(values):
+                    try:
+                        ver = float(winreg.EnumValue(bkey, i)[0])
+                        if ver not in vc_vers:
+                            vc_vers.append(ver)
+                    except ValueError:
+                        pass
+                for i in range(subkeys):
+                    try:
+                        ver = float(winreg.EnumKey(bkey, i))
+                        if ver not in vc_vers:
+                            vc_vers.append(ver)
+                    except ValueError:
+                        pass
+        return sorted(vc_vers)
+
+    @property
+    def VSInstallDir(self):
+        """
+        Microsoft Visual Studio directory.
+        """
+        # Default path
+        name = 'Microsoft Visual Studio %0.1f' % self.vc_ver
+        default = os.path.join(self.ProgramFilesx86, name)
+
+        # Try to get path from registry, if fail use default path
+        return self.ri.lookup(self.ri.vs, '%0.1f' % self.vc_ver) or default
+
+    @property
+    def VCInstallDir(self):
+        """
+        Microsoft Visual C++ directory.
+        """
+        self.VSInstallDir
+
+        guess_vc = self._guess_vc() or self._guess_vc_legacy()
+
+        # Try to get "VC++ for Python" path from registry as default path
+        reg_path = os.path.join(self.ri.vc_for_python, '%0.1f' % self.vc_ver)
+        python_vc = self.ri.lookup(reg_path, 'installdir')
+        default_vc = os.path.join(python_vc, 'VC') if python_vc else guess_vc
+
+        # Try to get path from registry, if fail use default path
+        path = self.ri.lookup(self.ri.vc, '%0.1f' % self.vc_ver) or default_vc
+
+        if not os.path.isdir(path):
+            msg = 'Microsoft Visual C++ directory not found'
+            raise distutils.errors.DistutilsPlatformError(msg)
+
+        return path
+
+    def _guess_vc(self):
+        """
+        Locate Visual C for 2017
+        """
+        if self.vc_ver <= 14.0:
+            return
+
+        default = r'VC\Tools\MSVC'
+        guess_vc = os.path.join(self.VSInstallDir, default)
+        # Subdir with VC exact version as name
+        try:
+            vc_exact_ver = os.listdir(guess_vc)[-1]
+            return os.path.join(guess_vc, vc_exact_ver)
+        except (OSError, IOError, IndexError):
+            pass
+
+    def _guess_vc_legacy(self):
+        """
+        Locate Visual C for versions prior to 2017
+        """
+        default = r'Microsoft Visual Studio %0.1f\VC' % self.vc_ver
+        return os.path.join(self.ProgramFilesx86, default)
+
+    @property
+    def WindowsSdkVersion(self):
+        """
+        Microsoft Windows SDK versions for specified MSVC++ version.
+        """
+        if self.vc_ver <= 9.0:
+            return ('7.0', '6.1', '6.0a')
+        elif self.vc_ver == 10.0:
+            return ('7.1', '7.0a')
+        elif self.vc_ver == 11.0:
+            return ('8.0', '8.0a')
+        elif self.vc_ver == 12.0:
+            return ('8.1', '8.1a')
+        elif self.vc_ver >= 14.0:
+            return ('10.0', '8.1')
+
+    @property
+    def WindowsSdkLastVersion(self):
+        """
+        Microsoft Windows SDK last version
+        """
+        return self._use_last_dir_name(os.path.join(
+            self.WindowsSdkDir, 'lib'))
+
+    @property
+    def WindowsSdkDir(self):
+        """
+        Microsoft Windows SDK directory.
+        """
+        sdkdir = ''
+        for ver in self.WindowsSdkVersion:
+            # Try to get it from registry
+            loc = os.path.join(self.ri.windows_sdk, 'v%s' % ver)
+            sdkdir = self.ri.lookup(loc, 'installationfolder')
+            if sdkdir:
+                break
+        if not sdkdir or not os.path.isdir(sdkdir):
+            # Try to get "VC++ for Python" version from registry
+            path = os.path.join(self.ri.vc_for_python, '%0.1f' % self.vc_ver)
+            install_base = self.ri.lookup(path, 'installdir')
+            if install_base:
+                sdkdir = os.path.join(install_base, 'WinSDK')
+        if not sdkdir or not os.path.isdir(sdkdir):
+            # If fail, use default new path
+            for ver in self.WindowsSdkVersion:
+                intver = ver[:ver.rfind('.')]
+                path = r'Microsoft SDKs\Windows Kits\%s' % (intver)
+                d = os.path.join(self.ProgramFiles, path)
+                if os.path.isdir(d):
+                    sdkdir = d
+        if not sdkdir or not os.path.isdir(sdkdir):
+            # If fail, use default old path
+            for ver in self.WindowsSdkVersion:
+                path = r'Microsoft SDKs\Windows\v%s' % ver
+                d = os.path.join(self.ProgramFiles, path)
+                if os.path.isdir(d):
+                    sdkdir = d
+        if not sdkdir:
+            # If fail, use Platform SDK
+            sdkdir = os.path.join(self.VCInstallDir, 'PlatformSDK')
+        return sdkdir
+
+    @property
+    def WindowsSDKExecutablePath(self):
+        """
+        Microsoft Windows SDK executable directory.
+        """
+        # Find WinSDK NetFx Tools registry dir name
+        if self.vc_ver <= 11.0:
+            netfxver = 35
+            arch = ''
+        else:
+            netfxver = 40
+            hidex86 = True if self.vc_ver <= 12.0 else False
+            arch = self.pi.current_dir(x64=True, hidex86=hidex86)
+        fx = 'WinSDK-NetFx%dTools%s' % (netfxver, arch.replace('\\', '-'))
+
+        # liste all possibles registry paths
+        regpaths = []
+        if self.vc_ver >= 14.0:
+            for ver in self.NetFxSdkVersion:
+                regpaths += [os.path.join(self.ri.netfx_sdk, ver, fx)]
+
+        for ver in self.WindowsSdkVersion:
+            regpaths += [os.path.join(self.ri.windows_sdk, 'v%sA' % ver, fx)]
+
+        # Return installation folder from the more recent path
+        for path in regpaths:
+            execpath = self.ri.lookup(path, 'installationfolder')
+            if execpath:
+                break
+        return execpath
+
+    @property
+    def FSharpInstallDir(self):
+        """
+        Microsoft Visual F# directory.
+        """
+        path = r'%0.1f\Setup\F#' % self.vc_ver
+        path = os.path.join(self.ri.visualstudio, path)
+        return self.ri.lookup(path, 'productdir') or ''
+
+    @property
+    def UniversalCRTSdkDir(self):
+        """
+        Microsoft Universal CRT SDK directory.
+        """
+        # Set Kit Roots versions for specified MSVC++ version
+        if self.vc_ver >= 14.0:
+            vers = ('10', '81')
+        else:
+            vers = ()
+
+        # Find path of the more recent Kit
+        for ver in vers:
+            sdkdir = self.ri.lookup(self.ri.windows_kits_roots,
+                                    'kitsroot%s' % ver)
+            if sdkdir:
+                break
+        return sdkdir or ''
+
+    @property
+    def UniversalCRTSdkLastVersion(self):
+        """
+        Microsoft Universal C Runtime SDK last version
+        """
+        return self._use_last_dir_name(os.path.join(
+            self.UniversalCRTSdkDir, 'lib'))
+
+    @property
+    def NetFxSdkVersion(self):
+        """
+        Microsoft .NET Framework SDK versions.
+        """
+        # Set FxSdk versions for specified MSVC++ version
+        if self.vc_ver >= 14.0:
+            return ('4.6.1', '4.6')
+        else:
+            return ()
+
+    @property
+    def NetFxSdkDir(self):
+        """
+        Microsoft .NET Framework SDK directory.
+        """
+        for ver in self.NetFxSdkVersion:
+            loc = os.path.join(self.ri.netfx_sdk, ver)
+            sdkdir = self.ri.lookup(loc, 'kitsinstallationfolder')
+            if sdkdir:
+                break
+        return sdkdir or ''
+
+    @property
+    def FrameworkDir32(self):
+        """
+        Microsoft .NET Framework 32bit directory.
+        """
+        # Default path
+        guess_fw = os.path.join(self.WinDir, r'Microsoft.NET\Framework')
+
+        # Try to get path from registry, if fail use default path
+        return self.ri.lookup(self.ri.vc, 'frameworkdir32') or guess_fw
+
+    @property
+    def FrameworkDir64(self):
+        """
+        Microsoft .NET Framework 64bit directory.
+        """
+        # Default path
+        guess_fw = os.path.join(self.WinDir, r'Microsoft.NET\Framework64')
+
+        # Try to get path from registry, if fail use default path
+        return self.ri.lookup(self.ri.vc, 'frameworkdir64') or guess_fw
+
+    @property
+    def FrameworkVersion32(self):
+        """
+        Microsoft .NET Framework 32bit versions.
+        """
+        return self._find_dot_net_versions(32)
+
+    @property
+    def FrameworkVersion64(self):
+        """
+        Microsoft .NET Framework 64bit versions.
+        """
+        return self._find_dot_net_versions(64)
+
+    def _find_dot_net_versions(self, bits):
+        """
+        Find Microsoft .NET Framework versions.
+
+        Parameters
+        ----------
+        bits: int
+            Platform number of bits: 32 or 64.
+        """
+        # Find actual .NET version in registry
+        reg_ver = self.ri.lookup(self.ri.vc, 'frameworkver%d' % bits)
+        dot_net_dir = getattr(self, 'FrameworkDir%d' % bits)
+        ver = reg_ver or self._use_last_dir_name(dot_net_dir, 'v') or ''
+
+        # Set .NET versions for specified MSVC++ version
+        if self.vc_ver >= 12.0:
+            frameworkver = (ver, 'v4.0')
+        elif self.vc_ver >= 10.0:
+            frameworkver = ('v4.0.30319' if ver.lower()[:2] != 'v4' else ver,
+                            'v3.5')
+        elif self.vc_ver == 9.0:
+            frameworkver = ('v3.5', 'v2.0.50727')
+        if self.vc_ver == 8.0:
+            frameworkver = ('v3.0', 'v2.0.50727')
+        return frameworkver
+
+    def _use_last_dir_name(self, path, prefix=''):
+        """
+        Return name of the last dir in path or '' if no dir found.
+
+        Parameters
+        ----------
+        path: str
+            Use dirs in this path
+        prefix: str
+            Use only dirs startings by this prefix
+        """
+        matching_dirs = (
+            dir_name
+            for dir_name in reversed(os.listdir(path))
+            if os.path.isdir(os.path.join(path, dir_name)) and
+            dir_name.startswith(prefix)
+        )
+        return next(matching_dirs, None) or ''
+
+
+class EnvironmentInfo:
+    """
+    Return environment variables for specified Microsoft Visual C++ version
+    and platform : Lib, Include, Path and libpath.
+
+    This function is compatible with Microsoft Visual C++ 9.0 to 14.0.
+
+    Script created by analysing Microsoft environment configuration files like
+    "vcvars[...].bat", "SetEnv.Cmd", "vcbuildtools.bat", ...
+
+    Parameters
+    ----------
+    arch: str
+        Target architecture.
+    vc_ver: float
+        Required Microsoft Visual C++ version. If not set, autodetect the last
+        version.
+    vc_min_ver: float
+        Minimum Microsoft Visual C++ version.
+    """
+
+    # Variables and properties in this class use originals CamelCase variables
+    # names from Microsoft source files for more easy comparaison.
+
+    def __init__(self, arch, vc_ver=None, vc_min_ver=0):
+        self.pi = PlatformInfo(arch)
+        self.ri = RegistryInfo(self.pi)
+        self.si = SystemInfo(self.ri, vc_ver)
+
+        if self.vc_ver < vc_min_ver:
+            err = 'No suitable Microsoft Visual C++ version found'
+            raise distutils.errors.DistutilsPlatformError(err)
+
+    @property
+    def vc_ver(self):
+        """
+        Microsoft Visual C++ version.
+        """
+        return self.si.vc_ver
+
+    @property
+    def VSTools(self):
+        """
+        Microsoft Visual Studio Tools
+        """
+        paths = [r'Common7\IDE', r'Common7\Tools']
+
+        if self.vc_ver >= 14.0:
+            arch_subdir = self.pi.current_dir(hidex86=True, x64=True)
+            paths += [r'Common7\IDE\CommonExtensions\Microsoft\TestWindow']
+            paths += [r'Team Tools\Performance Tools']
+            paths += [r'Team Tools\Performance Tools%s' % arch_subdir]
+
+        return [os.path.join(self.si.VSInstallDir, path) for path in paths]
+
+    @property
+    def VCIncludes(self):
+        """
+        Microsoft Visual C++ & Microsoft Foundation Class Includes
+        """
+        return [os.path.join(self.si.VCInstallDir, 'Include'),
+                os.path.join(self.si.VCInstallDir, r'ATLMFC\Include')]
+
+    @property
+    def VCLibraries(self):
+        """
+        Microsoft Visual C++ & Microsoft Foundation Class Libraries
+        """
+        if self.vc_ver >= 15.0:
+            arch_subdir = self.pi.target_dir(x64=True)
+        else:
+            arch_subdir = self.pi.target_dir(hidex86=True)
+        paths = ['Lib%s' % arch_subdir, r'ATLMFC\Lib%s' % arch_subdir]
+
+        if self.vc_ver >= 14.0:
+            paths += [r'Lib\store%s' % arch_subdir]
+
+        return [os.path.join(self.si.VCInstallDir, path) for path in paths]
+
+    @property
+    def VCStoreRefs(self):
+        """
+        Microsoft Visual C++ store references Libraries
+        """
+        if self.vc_ver < 14.0:
+            return []
+        return [os.path.join(self.si.VCInstallDir, r'Lib\store\references')]
+
+    @property
+    def VCTools(self):
+        """
+        Microsoft Visual C++ Tools
+        """
+        si = self.si
+        tools = [os.path.join(si.VCInstallDir, 'VCPackages')]
+
+        forcex86 = True if self.vc_ver <= 10.0 else False
+        arch_subdir = self.pi.cross_dir(forcex86)
+        if arch_subdir:
+            tools += [os.path.join(si.VCInstallDir, 'Bin%s' % arch_subdir)]
+
+        if self.vc_ver == 14.0:
+            path = 'Bin%s' % self.pi.current_dir(hidex86=True)
+            tools += [os.path.join(si.VCInstallDir, path)]
+
+        elif self.vc_ver >= 15.0:
+            host_dir = (r'bin\HostX86%s' if self.pi.current_is_x86() else
+                        r'bin\HostX64%s')
+            tools += [os.path.join(
+                si.VCInstallDir, host_dir % self.pi.target_dir(x64=True))]
+
+            if self.pi.current_cpu != self.pi.target_cpu:
+                tools += [os.path.join(
+                    si.VCInstallDir, host_dir % self.pi.current_dir(x64=True))]
+
+        else:
+            tools += [os.path.join(si.VCInstallDir, 'Bin')]
+
+        return tools
+
+    @property
+    def OSLibraries(self):
+        """
+        Microsoft Windows SDK Libraries
+        """
+        if self.vc_ver <= 10.0:
+            arch_subdir = self.pi.target_dir(hidex86=True, x64=True)
+            return [os.path.join(self.si.WindowsSdkDir, 'Lib%s' % arch_subdir)]
+
+        else:
+            arch_subdir = self.pi.target_dir(x64=True)
+            lib = os.path.join(self.si.WindowsSdkDir, 'lib')
+            libver = self._sdk_subdir
+            return [os.path.join(lib, '%sum%s' % (libver , arch_subdir))]
+
+    @property
+    def OSIncludes(self):
+        """
+        Microsoft Windows SDK Include
+        """
+        include = os.path.join(self.si.WindowsSdkDir, 'include')
+
+        if self.vc_ver <= 10.0:
+            return [include, os.path.join(include, 'gl')]
+
+        else:
+            if self.vc_ver >= 14.0:
+                sdkver = self._sdk_subdir
+            else:
+                sdkver = ''
+            return [os.path.join(include, '%sshared' % sdkver),
+                    os.path.join(include, '%sum' % sdkver),
+                    os.path.join(include, '%swinrt' % sdkver)]
+
+    @property
+    def OSLibpath(self):
+        """
+        Microsoft Windows SDK Libraries Paths
+        """
+        ref = os.path.join(self.si.WindowsSdkDir, 'References')
+        libpath = []
+
+        if self.vc_ver <= 9.0:
+            libpath += self.OSLibraries
+
+        if self.vc_ver >= 11.0:
+            libpath += [os.path.join(ref, r'CommonConfiguration\Neutral')]
+
+        if self.vc_ver >= 14.0:
+            libpath += [
+                ref,
+                os.path.join(self.si.WindowsSdkDir, 'UnionMetadata'),
+                os.path.join(
+                    ref,
+                    'Windows.Foundation.UniversalApiContract',
+                    '1.0.0.0',
+                ),
+                os.path.join(
+                    ref,
+                    'Windows.Foundation.FoundationContract',
+                    '1.0.0.0',
+                ),
+                os.path.join(
+                    ref,
+                    'Windows.Networking.Connectivity.WwanContract',
+                    '1.0.0.0',
+                ),
+                os.path.join(
+                    self.si.WindowsSdkDir,
+                    'ExtensionSDKs',
+                    'Microsoft.VCLibs',
+                    '%0.1f' % self.vc_ver,
+                    'References',
+                    'CommonConfiguration',
+                    'neutral',
+                ),
+            ]
+        return libpath
+
+    @property
+    def SdkTools(self):
+        """
+        Microsoft Windows SDK Tools
+        """
+        return list(self._sdk_tools())
+
+    def _sdk_tools(self):
+        """
+        Microsoft Windows SDK Tools paths generator
+        """
+        if self.vc_ver < 15.0:
+            bin_dir = 'Bin' if self.vc_ver <= 11.0 else r'Bin\x86'
+            yield os.path.join(self.si.WindowsSdkDir, bin_dir)
+
+        if not self.pi.current_is_x86():
+            arch_subdir = self.pi.current_dir(x64=True)
+            path = 'Bin%s' % arch_subdir
+            yield os.path.join(self.si.WindowsSdkDir, path)
+
+        if self.vc_ver == 10.0 or self.vc_ver == 11.0:
+            if self.pi.target_is_x86():
+                arch_subdir = ''
+            else:
+                arch_subdir = self.pi.current_dir(hidex86=True, x64=True)
+            path = r'Bin\NETFX 4.0 Tools%s' % arch_subdir
+            yield os.path.join(self.si.WindowsSdkDir, path)
+
+        elif self.vc_ver >= 15.0:
+            path = os.path.join(self.si.WindowsSdkDir, 'Bin')
+            arch_subdir = self.pi.current_dir(x64=True)
+            sdkver = self.si.WindowsSdkLastVersion
+            yield os.path.join(path, '%s%s' % (sdkver, arch_subdir))
+
+        if self.si.WindowsSDKExecutablePath:
+            yield self.si.WindowsSDKExecutablePath
+
+    @property
+    def _sdk_subdir(self):
+        """
+        Microsoft Windows SDK version subdir
+        """
+        ucrtver = self.si.WindowsSdkLastVersion
+        return ('%s\\' % ucrtver) if ucrtver else ''
+
+    @property
+    def SdkSetup(self):
+        """
+        Microsoft Windows SDK Setup
+        """
+        if self.vc_ver > 9.0:
+            return []
+
+        return [os.path.join(self.si.WindowsSdkDir, 'Setup')]
+
+    @property
+    def FxTools(self):
+        """
+        Microsoft .NET Framework Tools
+        """
+        pi = self.pi
+        si = self.si
+
+        if self.vc_ver <= 10.0:
+            include32 = True
+            include64 = not pi.target_is_x86() and not pi.current_is_x86()
+        else:
+            include32 = pi.target_is_x86() or pi.current_is_x86()
+            include64 = pi.current_cpu == 'amd64' or pi.target_cpu == 'amd64'
+
+        tools = []
+        if include32:
+            tools += [os.path.join(si.FrameworkDir32, ver)
+                      for ver in si.FrameworkVersion32]
+        if include64:
+            tools += [os.path.join(si.FrameworkDir64, ver)
+                      for ver in si.FrameworkVersion64]
+        return tools
+
+    @property
+    def NetFxSDKLibraries(self):
+        """
+        Microsoft .Net Framework SDK Libraries
+        """
+        if self.vc_ver < 14.0 or not self.si.NetFxSdkDir:
+            return []
+
+        arch_subdir = self.pi.target_dir(x64=True)
+        return [os.path.join(self.si.NetFxSdkDir, r'lib\um%s' % arch_subdir)]
+
+    @property
+    def NetFxSDKIncludes(self):
+        """
+        Microsoft .Net Framework SDK Includes
+        """
+        if self.vc_ver < 14.0 or not self.si.NetFxSdkDir:
+            return []
+
+        return [os.path.join(self.si.NetFxSdkDir, r'include\um')]
+
+    @property
+    def VsTDb(self):
+        """
+        Microsoft Visual Studio Team System Database
+        """
+        return [os.path.join(self.si.VSInstallDir, r'VSTSDB\Deploy')]
+
+    @property
+    def MSBuild(self):
+        """
+        Microsoft Build Engine
+        """
+        if self.vc_ver < 12.0:
+            return []
+        elif self.vc_ver < 15.0:
+            base_path = self.si.ProgramFilesx86
+            arch_subdir = self.pi.current_dir(hidex86=True)
+        else:
+            base_path = self.si.VSInstallDir
+            arch_subdir = ''
+
+        path = r'MSBuild\%0.1f\bin%s' % (self.vc_ver, arch_subdir)
+        build = [os.path.join(base_path, path)]
+
+        if self.vc_ver >= 15.0:
+            # Add Roslyn C# & Visual Basic Compiler
+            build += [os.path.join(base_path, path, 'Roslyn')]
+
+        return build
+
+    @property
+    def HTMLHelpWorkshop(self):
+        """
+        Microsoft HTML Help Workshop
+        """
+        if self.vc_ver < 11.0:
+            return []
+
+        return [os.path.join(self.si.ProgramFilesx86, 'HTML Help Workshop')]
+
+    @property
+    def UCRTLibraries(self):
+        """
+        Microsoft Universal C Runtime SDK Libraries
+        """
+        if self.vc_ver < 14.0:
+            return []
+
+        arch_subdir = self.pi.target_dir(x64=True)
+        lib = os.path.join(self.si.UniversalCRTSdkDir, 'lib')
+        ucrtver = self._ucrt_subdir
+        return [os.path.join(lib, '%sucrt%s' % (ucrtver, arch_subdir))]
+
+    @property
+    def UCRTIncludes(self):
+        """
+        Microsoft Universal C Runtime SDK Include
+        """
+        if self.vc_ver < 14.0:
+            return []
+
+        include = os.path.join(self.si.UniversalCRTSdkDir, 'include')
+        return [os.path.join(include, '%sucrt' % self._ucrt_subdir)]
+
+    @property
+    def _ucrt_subdir(self):
+        """
+        Microsoft Universal C Runtime SDK version subdir
+        """
+        ucrtver = self.si.UniversalCRTSdkLastVersion
+        return ('%s\\' % ucrtver) if ucrtver else ''
+
+    @property
+    def FSharp(self):
+        """
+        Microsoft Visual F#
+        """
+        if self.vc_ver < 11.0 and self.vc_ver > 12.0:
+            return []
+
+        return self.si.FSharpInstallDir
+
+    @property
+    def VCRuntimeRedist(self):
+        """
+        Microsoft Visual C++ runtime redistribuable dll
+        """
+        arch_subdir = self.pi.target_dir(x64=True)
+        if self.vc_ver < 15:
+            redist_path = self.si.VCInstallDir
+            vcruntime = 'redist%s\\Microsoft.VC%d0.CRT\\vcruntime%d0.dll'
+        else:
+            redist_path = self.si.VCInstallDir.replace('\\Tools', '\\Redist')
+            vcruntime = 'onecore%s\\Microsoft.VC%d0.CRT\\vcruntime%d0.dll'
+
+        # Visual Studio 2017  is still Visual C++ 14.0
+        dll_ver = 14.0 if self.vc_ver == 15 else self.vc_ver
+
+        vcruntime = vcruntime % (arch_subdir, self.vc_ver, dll_ver)
+        return os.path.join(redist_path, vcruntime)
+
+    def return_env(self, exists=True):
+        """
+        Return environment dict.
+
+        Parameters
+        ----------
+        exists: bool
+            It True, only return existing paths.
+        """
+        env = dict(
+            include=self._build_paths('include',
+                                      [self.VCIncludes,
+                                       self.OSIncludes,
+                                       self.UCRTIncludes,
+                                       self.NetFxSDKIncludes],
+                                      exists),
+            lib=self._build_paths('lib',
+                                  [self.VCLibraries,
+                                   self.OSLibraries,
+                                   self.FxTools,
+                                   self.UCRTLibraries,
+                                   self.NetFxSDKLibraries],
+                                  exists),
+            libpath=self._build_paths('libpath',
+                                      [self.VCLibraries,
+                                       self.FxTools,
+                                       self.VCStoreRefs,
+                                       self.OSLibpath],
+                                      exists),
+            path=self._build_paths('path',
+                                   [self.VCTools,
+                                    self.VSTools,
+                                    self.VsTDb,
+                                    self.SdkTools,
+                                    self.SdkSetup,
+                                    self.FxTools,
+                                    self.MSBuild,
+                                    self.HTMLHelpWorkshop,
+                                    self.FSharp],
+                                   exists),
+        )
+        if self.vc_ver >= 14 and os.path.isfile(self.VCRuntimeRedist):
+            env['py_vcruntime_redist'] = self.VCRuntimeRedist
+        return env
+
+    def _build_paths(self, name, spec_path_lists, exists):
+        """
+        Given an environment variable name and specified paths,
+        return a pathsep-separated string of paths containing
+        unique, extant, directories from those paths and from
+        the environment variable. Raise an error if no paths
+        are resolved.
+        """
+        # flatten spec_path_lists
+        spec_paths = itertools.chain.from_iterable(spec_path_lists)
+        env_paths = safe_env.get(name, '').split(os.pathsep)
+        paths = itertools.chain(spec_paths, env_paths)
+        extant_paths = list(filter(os.path.isdir, paths)) if exists else paths
+        if not extant_paths:
+            msg = "%s environment variable is empty" % name.upper()
+            raise distutils.errors.DistutilsPlatformError(msg)
+        unique_paths = self._unique_everseen(extant_paths)
+        return os.pathsep.join(unique_paths)
+
+    # from Python docs
+    def _unique_everseen(self, iterable, key=None):
+        """
+        List unique elements, preserving order.
+        Remember all elements ever seen.
+
+        _unique_everseen('AAAABBBCCDAABBB') --> A B C D
+
+        _unique_everseen('ABBCcAD', str.lower) --> A B C D
+        """
+        seen = set()
+        seen_add = seen.add
+        if key is None:
+            for element in filterfalse(seen.__contains__, iterable):
+                seen_add(element)
+                yield element
+        else:
+            for element in iterable:
+                k = key(element)
+                if k not in seen:
+                    seen_add(k)
+                    yield element
diff --git a/vendor/setuptools-39.0.1/setuptools/namespaces.py b/vendor/setuptools-39.0.1/setuptools/namespaces.py
new file mode 100755
index 00000000..dc16106d
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/namespaces.py
@@ -0,0 +1,107 @@
+import os
+from distutils import log
+import itertools
+
+from setuptools.extern.six.moves import map
+
+
+flatten = itertools.chain.from_iterable
+
+
+class Installer:
+
+    nspkg_ext = '-nspkg.pth'
+
+    def install_namespaces(self):
+        nsp = self._get_all_ns_packages()
+        if not nsp:
+            return
+        filename, ext = os.path.splitext(self._get_target())
+        filename += self.nspkg_ext
+        self.outputs.append(filename)
+        log.info("Installing %s", filename)
+        lines = map(self._gen_nspkg_line, nsp)
+
+        if self.dry_run:
+            # always generate the lines, even in dry run
+            list(lines)
+            return
+
+        with open(filename, 'wt') as f:
+            f.writelines(lines)
+
+    def uninstall_namespaces(self):
+        filename, ext = os.path.splitext(self._get_target())
+        filename += self.nspkg_ext
+        if not os.path.exists(filename):
+            return
+        log.info("Removing %s", filename)
+        os.remove(filename)
+
+    def _get_target(self):
+        return self.target
+
+    _nspkg_tmpl = (
+        "import sys, types, os",
+        "has_mfs = sys.version_info > (3, 5)",
+        "p = os.path.join(%(root)s, *%(pth)r)",
+        "importlib = has_mfs and __import__('importlib.util')",
+        "has_mfs and __import__('importlib.machinery')",
+        "m = has_mfs and "
+            "sys.modules.setdefault(%(pkg)r, "
+                "importlib.util.module_from_spec("
+                    "importlib.machinery.PathFinder.find_spec(%(pkg)r, "
+                        "[os.path.dirname(p)])))",
+        "m = m or "
+            "sys.modules.setdefault(%(pkg)r, types.ModuleType(%(pkg)r))",
+        "mp = (m or []) and m.__dict__.setdefault('__path__',[])",
+        "(p not in mp) and mp.append(p)",
+    )
+    "lines for the namespace installer"
+
+    _nspkg_tmpl_multi = (
+        'm and setattr(sys.modules[%(parent)r], %(child)r, m)',
+    )
+    "additional line(s) when a parent package is indicated"
+
+    def _get_root(self):
+        return "sys._getframe(1).f_locals['sitedir']"
+
+    def _gen_nspkg_line(self, pkg):
+        # ensure pkg is not a unicode string under Python 2.7
+        pkg = str(pkg)
+        pth = tuple(pkg.split('.'))
+        root = self._get_root()
+        tmpl_lines = self._nspkg_tmpl
+        parent, sep, child = pkg.rpartition('.')
+        if parent:
+            tmpl_lines += self._nspkg_tmpl_multi
+        return ';'.join(tmpl_lines) % locals() + '\n'
+
+    def _get_all_ns_packages(self):
+        """Return sorted list of all package namespaces"""
+        pkgs = self.distribution.namespace_packages or []
+        return sorted(flatten(map(self._pkg_names, pkgs)))
+
+    @staticmethod
+    def _pkg_names(pkg):
+        """
+        Given a namespace package, yield the components of that
+        package.
+
+        >>> names = Installer._pkg_names('a.b.c')
+        >>> set(names) == set(['a', 'a.b', 'a.b.c'])
+        True
+        """
+        parts = pkg.split('.')
+        while parts:
+            yield '.'.join(parts)
+            parts.pop()
+
+
+class DevelopInstaller(Installer):
+    def _get_root(self):
+        return repr(str(self.egg_path))
+
+    def _get_target(self):
+        return self.egg_link
diff --git a/vendor/setuptools-39.0.1/setuptools/package_index.py b/vendor/setuptools-39.0.1/setuptools/package_index.py
new file mode 100755
index 00000000..914b5e61
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/package_index.py
@@ -0,0 +1,1119 @@
+"""PyPI and direct package downloading"""
+import sys
+import os
+import re
+import shutil
+import socket
+import base64
+import hashlib
+import itertools
+from functools import wraps
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import urllib, http_client, configparser, map
+
+import setuptools
+from pkg_resources import (
+    CHECKOUT_DIST, Distribution, BINARY_DIST, normalize_path, SOURCE_DIST,
+    Environment, find_distributions, safe_name, safe_version,
+    to_filename, Requirement, DEVELOP_DIST, EGG_DIST,
+)
+from setuptools import ssl_support
+from distutils import log
+from distutils.errors import DistutilsError
+from fnmatch import translate
+from setuptools.py27compat import get_all_headers
+from setuptools.py33compat import unescape
+from setuptools.wheel import Wheel
+
+EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.+!]+)$')
+HREF = re.compile("""href\\s*=\\s*['"]?([^'"> ]+)""", re.I)
+# this is here to fix emacs' cruddy broken syntax highlighting
+PYPI_MD5 = re.compile(
+    '<a href="([^"#]+)">([^<]+)</a>\n\\s+\\(<a (?:title="MD5 hash"\n\\s+)'
+    'href="[^?]+\\?:action=show_md5&amp;digest=([0-9a-f]{32})">md5</a>\\)'
+)
+URL_SCHEME = re.compile('([-+.a-z0-9]{2,}):', re.I).match
+EXTENSIONS = ".tar.gz .tar.bz2 .tar .zip .tgz".split()
+
+__all__ = [
+    'PackageIndex', 'distros_for_url', 'parse_bdist_wininst',
+    'interpret_distro_name',
+]
+
+_SOCKET_TIMEOUT = 15
+
+_tmpl = "setuptools/{setuptools.__version__} Python-urllib/{py_major}"
+user_agent = _tmpl.format(py_major=sys.version[:3], setuptools=setuptools)
+
+
+def parse_requirement_arg(spec):
+    try:
+        return Requirement.parse(spec)
+    except ValueError:
+        raise DistutilsError(
+            "Not a URL, existing file, or requirement spec: %r" % (spec,)
+        )
+
+
+def parse_bdist_wininst(name):
+    """Return (base,pyversion) or (None,None) for possible .exe name"""
+
+    lower = name.lower()
+    base, py_ver, plat = None, None, None
+
+    if lower.endswith('.exe'):
+        if lower.endswith('.win32.exe'):
+            base = name[:-10]
+            plat = 'win32'
+        elif lower.startswith('.win32-py', -16):
+            py_ver = name[-7:-4]
+            base = name[:-16]
+            plat = 'win32'
+        elif lower.endswith('.win-amd64.exe'):
+            base = name[:-14]
+            plat = 'win-amd64'
+        elif lower.startswith('.win-amd64-py', -20):
+            py_ver = name[-7:-4]
+            base = name[:-20]
+            plat = 'win-amd64'
+    return base, py_ver, plat
+
+
+def egg_info_for_url(url):
+    parts = urllib.parse.urlparse(url)
+    scheme, server, path, parameters, query, fragment = parts
+    base = urllib.parse.unquote(path.split('/')[-1])
+    if server == 'sourceforge.net' and base == 'download':  # XXX Yuck
+        base = urllib.parse.unquote(path.split('/')[-2])
+    if '#' in base:
+        base, fragment = base.split('#', 1)
+    return base, fragment
+
+
+def distros_for_url(url, metadata=None):
+    """Yield egg or source distribution objects that might be found at a URL"""
+    base, fragment = egg_info_for_url(url)
+    for dist in distros_for_location(url, base, metadata):
+        yield dist
+    if fragment:
+        match = EGG_FRAGMENT.match(fragment)
+        if match:
+            for dist in interpret_distro_name(
+                url, match.group(1), metadata, precedence=CHECKOUT_DIST
+            ):
+                yield dist
+
+
+def distros_for_location(location, basename, metadata=None):
+    """Yield egg or source distribution objects based on basename"""
+    if basename.endswith('.egg.zip'):
+        basename = basename[:-4]  # strip the .zip
+    if basename.endswith('.egg') and '-' in basename:
+        # only one, unambiguous interpretation
+        return [Distribution.from_location(location, basename, metadata)]
+    if basename.endswith('.whl') and '-' in basename:
+        wheel = Wheel(basename)
+        if not wheel.is_compatible():
+            return []
+        return [Distribution(
+            location=location,
+            project_name=wheel.project_name,
+            version=wheel.version,
+            # Increase priority over eggs.
+            precedence=EGG_DIST + 1,
+        )]
+    if basename.endswith('.exe'):
+        win_base, py_ver, platform = parse_bdist_wininst(basename)
+        if win_base is not None:
+            return interpret_distro_name(
+                location, win_base, metadata, py_ver, BINARY_DIST, platform
+            )
+    # Try source distro extensions (.zip, .tgz, etc.)
+    #
+    for ext in EXTENSIONS:
+        if basename.endswith(ext):
+            basename = basename[:-len(ext)]
+            return interpret_distro_name(location, basename, metadata)
+    return []  # no extension matched
+
+
+def distros_for_filename(filename, metadata=None):
+    """Yield possible egg or source distribution objects based on a filename"""
+    return distros_for_location(
+        normalize_path(filename), os.path.basename(filename), metadata
+    )
+
+
+def interpret_distro_name(
+        location, basename, metadata, py_version=None, precedence=SOURCE_DIST,
+        platform=None
+):
+    """Generate alternative interpretations of a source distro name
+
+    Note: if `location` is a filesystem filename, you should call
+    ``pkg_resources.normalize_path()`` on it before passing it to this
+    routine!
+    """
+    # Generate alternative interpretations of a source distro name
+    # Because some packages are ambiguous as to name/versions split
+    # e.g. "adns-python-1.1.0", "egenix-mx-commercial", etc.
+    # So, we generate each possible interepretation (e.g. "adns, python-1.1.0"
+    # "adns-python, 1.1.0", and "adns-python-1.1.0, no version").  In practice,
+    # the spurious interpretations should be ignored, because in the event
+    # there's also an "adns" package, the spurious "python-1.1.0" version will
+    # compare lower than any numeric version number, and is therefore unlikely
+    # to match a request for it.  It's still a potential problem, though, and
+    # in the long run PyPI and the distutils should go for "safe" names and
+    # versions in distribution archive names (sdist and bdist).
+
+    parts = basename.split('-')
+    if not py_version and any(re.match(r'py\d\.\d$', p) for p in parts[2:]):
+        # it is a bdist_dumb, not an sdist -- bail out
+        return
+
+    for p in range(1, len(parts) + 1):
+        yield Distribution(
+            location, metadata, '-'.join(parts[:p]), '-'.join(parts[p:]),
+            py_version=py_version, precedence=precedence,
+            platform=platform
+        )
+
+
+# From Python 2.7 docs
+def unique_everseen(iterable, key=None):
+    "List unique elements, preserving order. Remember all elements ever seen."
+    # unique_everseen('AAAABBBCCDAABBB') --> A B C D
+    # unique_everseen('ABBCcAD', str.lower) --> A B C D
+    seen = set()
+    seen_add = seen.add
+    if key is None:
+        for element in six.moves.filterfalse(seen.__contains__, iterable):
+            seen_add(element)
+            yield element
+    else:
+        for element in iterable:
+            k = key(element)
+            if k not in seen:
+                seen_add(k)
+                yield element
+
+
+def unique_values(func):
+    """
+    Wrap a function returning an iterable such that the resulting iterable
+    only ever yields unique items.
+    """
+
+    @wraps(func)
+    def wrapper(*args, **kwargs):
+        return unique_everseen(func(*args, **kwargs))
+
+    return wrapper
+
+
+REL = re.compile(r"""<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>""", re.I)
+# this line is here to fix emacs' cruddy broken syntax highlighting
+
+
+@unique_values
+def find_external_links(url, page):
+    """Find rel="homepage" and rel="download" links in `page`, yielding URLs"""
+
+    for match in REL.finditer(page):
+        tag, rel = match.groups()
+        rels = set(map(str.strip, rel.lower().split(',')))
+        if 'homepage' in rels or 'download' in rels:
+            for match in HREF.finditer(tag):
+                yield urllib.parse.urljoin(url, htmldecode(match.group(1)))
+
+    for tag in ("<th>Home Page", "<th>Download URL"):
+        pos = page.find(tag)
+        if pos != -1:
+            match = HREF.search(page, pos)
+            if match:
+                yield urllib.parse.urljoin(url, htmldecode(match.group(1)))
+
+
+class ContentChecker(object):
+    """
+    A null content checker that defines the interface for checking content
+    """
+
+    def feed(self, block):
+        """
+        Feed a block of data to the hash.
+        """
+        return
+
+    def is_valid(self):
+        """
+        Check the hash. Return False if validation fails.
+        """
+        return True
+
+    def report(self, reporter, template):
+        """
+        Call reporter with information about the checker (hash name)
+        substituted into the template.
+        """
+        return
+
+
+class HashChecker(ContentChecker):
+    pattern = re.compile(
+        r'(?P<hash_name>sha1|sha224|sha384|sha256|sha512|md5)='
+        r'(?P<expected>[a-f0-9]+)'
+    )
+
+    def __init__(self, hash_name, expected):
+        self.hash_name = hash_name
+        self.hash = hashlib.new(hash_name)
+        self.expected = expected
+
+    @classmethod
+    def from_url(cls, url):
+        "Construct a (possibly null) ContentChecker from a URL"
+        fragment = urllib.parse.urlparse(url)[-1]
+        if not fragment:
+            return ContentChecker()
+        match = cls.pattern.search(fragment)
+        if not match:
+            return ContentChecker()
+        return cls(**match.groupdict())
+
+    def feed(self, block):
+        self.hash.update(block)
+
+    def is_valid(self):
+        return self.hash.hexdigest() == self.expected
+
+    def report(self, reporter, template):
+        msg = template % self.hash_name
+        return reporter(msg)
+
+
+class PackageIndex(Environment):
+    """A distribution index that scans web pages for download URLs"""
+
+    def __init__(
+            self, index_url="https://pypi.python.org/simple", hosts=('*',),
+            ca_bundle=None, verify_ssl=True, *args, **kw
+    ):
+        Environment.__init__(self, *args, **kw)
+        self.index_url = index_url + "/" [:not index_url.endswith('/')]
+        self.scanned_urls = {}
+        self.fetched_urls = {}
+        self.package_pages = {}
+        self.allows = re.compile('|'.join(map(translate, hosts))).match
+        self.to_scan = []
+        use_ssl = (
+            verify_ssl
+            and ssl_support.is_available
+            and (ca_bundle or ssl_support.find_ca_bundle())
+        )
+        if use_ssl:
+            self.opener = ssl_support.opener_for(ca_bundle)
+        else:
+            self.opener = urllib.request.urlopen
+
+    def process_url(self, url, retrieve=False):
+        """Evaluate a URL as a possible download, and maybe retrieve it"""
+        if url in self.scanned_urls and not retrieve:
+            return
+        self.scanned_urls[url] = True
+        if not URL_SCHEME(url):
+            self.process_filename(url)
+            return
+        else:
+            dists = list(distros_for_url(url))
+            if dists:
+                if not self.url_ok(url):
+                    return
+                self.debug("Found link: %s", url)
+
+        if dists or not retrieve or url in self.fetched_urls:
+            list(map(self.add, dists))
+            return  # don't need the actual page
+
+        if not self.url_ok(url):
+            self.fetched_urls[url] = True
+            return
+
+        self.info("Reading %s", url)
+        self.fetched_urls[url] = True  # prevent multiple fetch attempts
+        tmpl = "Download error on %s: %%s -- Some packages may not be found!"
+        f = self.open_url(url, tmpl % url)
+        if f is None:
+            return
+        self.fetched_urls[f.url] = True
+        if 'html' not in f.headers.get('content-type', '').lower():
+            f.close()  # not html, we can't process it
+            return
+
+        base = f.url  # handle redirects
+        page = f.read()
+        if not isinstance(page, str):
+            # In Python 3 and got bytes but want str.
+            if isinstance(f, urllib.error.HTTPError):
+                # Errors have no charset, assume latin1:
+                charset = 'latin-1'
+            else:
+                charset = f.headers.get_param('charset') or 'latin-1'
+            page = page.decode(charset, "ignore")
+        f.close()
+        for match in HREF.finditer(page):
+            link = urllib.parse.urljoin(base, htmldecode(match.group(1)))
+            self.process_url(link)
+        if url.startswith(self.index_url) and getattr(f, 'code', None) != 404:
+            page = self.process_index(url, page)
+
+    def process_filename(self, fn, nested=False):
+        # process filenames or directories
+        if not os.path.exists(fn):
+            self.warn("Not found: %s", fn)
+            return
+
+        if os.path.isdir(fn) and not nested:
+            path = os.path.realpath(fn)
+            for item in os.listdir(path):
+                self.process_filename(os.path.join(path, item), True)
+
+        dists = distros_for_filename(fn)
+        if dists:
+            self.debug("Found: %s", fn)
+            list(map(self.add, dists))
+
+    def url_ok(self, url, fatal=False):
+        s = URL_SCHEME(url)
+        is_file = s and s.group(1).lower() == 'file'
+        if is_file or self.allows(urllib.parse.urlparse(url)[1]):
+            return True
+        msg = (
+            "\nNote: Bypassing %s (disallowed host; see "
+            "http://bit.ly/2hrImnY for details).\n")
+        if fatal:
+            raise DistutilsError(msg % url)
+        else:
+            self.warn(msg, url)
+
+    def scan_egg_links(self, search_path):
+        dirs = filter(os.path.isdir, search_path)
+        egg_links = (
+            (path, entry)
+            for path in dirs
+            for entry in os.listdir(path)
+            if entry.endswith('.egg-link')
+        )
+        list(itertools.starmap(self.scan_egg_link, egg_links))
+
+    def scan_egg_link(self, path, entry):
+        with open(os.path.join(path, entry)) as raw_lines:
+            # filter non-empty lines
+            lines = list(filter(None, map(str.strip, raw_lines)))
+
+        if len(lines) != 2:
+            # format is not recognized; punt
+            return
+
+        egg_path, setup_path = lines
+
+        for dist in find_distributions(os.path.join(path, egg_path)):
+            dist.location = os.path.join(path, *lines)
+            dist.precedence = SOURCE_DIST
+            self.add(dist)
+
+    def process_index(self, url, page):
+        """Process the contents of a PyPI page"""
+
+        def scan(link):
+            # Process a URL to see if it's for a package page
+            if link.startswith(self.index_url):
+                parts = list(map(
+                    urllib.parse.unquote, link[len(self.index_url):].split('/')
+                ))
+                if len(parts) == 2 and '#' not in parts[1]:
+                    # it's a package page, sanitize and index it
+                    pkg = safe_name(parts[0])
+                    ver = safe_version(parts[1])
+                    self.package_pages.setdefault(pkg.lower(), {})[link] = True
+                    return to_filename(pkg), to_filename(ver)
+            return None, None
+
+        # process an index page into the package-page index
+        for match in HREF.finditer(page):
+            try:
+                scan(urllib.parse.urljoin(url, htmldecode(match.group(1))))
+            except ValueError:
+                pass
+
+        pkg, ver = scan(url)  # ensure this page is in the page index
+        if pkg:
+            # process individual package page
+            for new_url in find_external_links(url, page):
+                # Process the found URL
+                base, frag = egg_info_for_url(new_url)
+                if base.endswith('.py') and not frag:
+                    if ver:
+                        new_url += '#egg=%s-%s' % (pkg, ver)
+                    else:
+                        self.need_version_info(url)
+                self.scan_url(new_url)
+
+            return PYPI_MD5.sub(
+                lambda m: '<a href="%s#md5=%s">%s</a>' % m.group(1, 3, 2), page
+            )
+        else:
+            return ""  # no sense double-scanning non-package pages
+
+    def need_version_info(self, url):
+        self.scan_all(
+            "Page at %s links to .py file(s) without version info; an index "
+            "scan is required.", url
+        )
+
+    def scan_all(self, msg=None, *args):
+        if self.index_url not in self.fetched_urls:
+            if msg:
+                self.warn(msg, *args)
+            self.info(
+                "Scanning index of all packages (this may take a while)"
+            )
+        self.scan_url(self.index_url)
+
+    def find_packages(self, requirement):
+        self.scan_url(self.index_url + requirement.unsafe_name + '/')
+
+        if not self.package_pages.get(requirement.key):
+            # Fall back to safe version of the name
+            self.scan_url(self.index_url + requirement.project_name + '/')
+
+        if not self.package_pages.get(requirement.key):
+            # We couldn't find the target package, so search the index page too
+            self.not_found_in_index(requirement)
+
+        for url in list(self.package_pages.get(requirement.key, ())):
+            # scan each page that might be related to the desired package
+            self.scan_url(url)
+
+    def obtain(self, requirement, installer=None):
+        self.prescan()
+        self.find_packages(requirement)
+        for dist in self[requirement.key]:
+            if dist in requirement:
+                return dist
+            self.debug("%s does not match %s", requirement, dist)
+        return super(PackageIndex, self).obtain(requirement, installer)
+
+    def check_hash(self, checker, filename, tfp):
+        """
+        checker is a ContentChecker
+        """
+        checker.report(
+            self.debug,
+            "Validating %%s checksum for %s" % filename)
+        if not checker.is_valid():
+            tfp.close()
+            os.unlink(filename)
+            raise DistutilsError(
+                "%s validation failed for %s; "
+                "possible download problem?"
+                % (checker.hash.name, os.path.basename(filename))
+            )
+
+    def add_find_links(self, urls):
+        """Add `urls` to the list that will be prescanned for searches"""
+        for url in urls:
+            if (
+                self.to_scan is None  # if we have already "gone online"
+                or not URL_SCHEME(url)  # or it's a local file/directory
+                or url.startswith('file:')
+                or list(distros_for_url(url))  # or a direct package link
+            ):
+                # then go ahead and process it now
+                self.scan_url(url)
+            else:
+                # otherwise, defer retrieval till later
+                self.to_scan.append(url)
+
+    def prescan(self):
+        """Scan urls scheduled for prescanning (e.g. --find-links)"""
+        if self.to_scan:
+            list(map(self.scan_url, self.to_scan))
+        self.to_scan = None  # from now on, go ahead and process immediately
+
+    def not_found_in_index(self, requirement):
+        if self[requirement.key]:  # we've seen at least one distro
+            meth, msg = self.info, "Couldn't retrieve index page for %r"
+        else:  # no distros seen for this name, might be misspelled
+            meth, msg = (
+                self.warn,
+                "Couldn't find index page for %r (maybe misspelled?)")
+        meth(msg, requirement.unsafe_name)
+        self.scan_all()
+
+    def download(self, spec, tmpdir):
+        """Locate and/or download `spec` to `tmpdir`, returning a local path
+
+        `spec` may be a ``Requirement`` object, or a string containing a URL,
+        an existing local filename, or a project/version requirement spec
+        (i.e. the string form of a ``Requirement`` object).  If it is the URL
+        of a .py file with an unambiguous ``#egg=name-version`` tag (i.e., one
+        that escapes ``-`` as ``_`` throughout), a trivial ``setup.py`` is
+        automatically created alongside the downloaded file.
+
+        If `spec` is a ``Requirement`` object or a string containing a
+        project/version requirement spec, this method returns the location of
+        a matching distribution (possibly after downloading it to `tmpdir`).
+        If `spec` is a locally existing file or directory name, it is simply
+        returned unchanged.  If `spec` is a URL, it is downloaded to a subpath
+        of `tmpdir`, and the local filename is returned.  Various errors may be
+        raised if a problem occurs during downloading.
+        """
+        if not isinstance(spec, Requirement):
+            scheme = URL_SCHEME(spec)
+            if scheme:
+                # It's a url, download it to tmpdir
+                found = self._download_url(scheme.group(1), spec, tmpdir)
+                base, fragment = egg_info_for_url(spec)
+                if base.endswith('.py'):
+                    found = self.gen_setup(found, fragment, tmpdir)
+                return found
+            elif os.path.exists(spec):
+                # Existing file or directory, just return it
+                return spec
+            else:
+                spec = parse_requirement_arg(spec)
+        return getattr(self.fetch_distribution(spec, tmpdir), 'location', None)
+
+    def fetch_distribution(
+            self, requirement, tmpdir, force_scan=False, source=False,
+            develop_ok=False, local_index=None):
+        """Obtain a distribution suitable for fulfilling `requirement`
+
+        `requirement` must be a ``pkg_resources.Requirement`` instance.
+        If necessary, or if the `force_scan` flag is set, the requirement is
+        searched for in the (online) package index as well as the locally
+        installed packages.  If a distribution matching `requirement` is found,
+        the returned distribution's ``location`` is the value you would have
+        gotten from calling the ``download()`` method with the matching
+        distribution's URL or filename.  If no matching distribution is found,
+        ``None`` is returned.
+
+        If the `source` flag is set, only source distributions and source
+        checkout links will be considered.  Unless the `develop_ok` flag is
+        set, development and system eggs (i.e., those using the ``.egg-info``
+        format) will be ignored.
+        """
+        # process a Requirement
+        self.info("Searching for %s", requirement)
+        skipped = {}
+        dist = None
+
+        def find(req, env=None):
+            if env is None:
+                env = self
+            # Find a matching distribution; may be called more than once
+
+            for dist in env[req.key]:
+
+                if dist.precedence == DEVELOP_DIST and not develop_ok:
+                    if dist not in skipped:
+                        self.warn(
+                            "Skipping development or system egg: %s", dist,
+                        )
+                        skipped[dist] = 1
+                    continue
+
+                test = (
+                    dist in req
+                    and (dist.precedence <= SOURCE_DIST or not source)
+                )
+                if test:
+                    loc = self.download(dist.location, tmpdir)
+                    dist.download_location = loc
+                    if os.path.exists(dist.download_location):
+                        return dist
+
+        if force_scan:
+            self.prescan()
+            self.find_packages(requirement)
+            dist = find(requirement)
+
+        if not dist and local_index is not None:
+            dist = find(requirement, local_index)
+
+        if dist is None:
+            if self.to_scan is not None:
+                self.prescan()
+            dist = find(requirement)
+
+        if dist is None and not force_scan:
+            self.find_packages(requirement)
+            dist = find(requirement)
+
+        if dist is None:
+            self.warn(
+                "No local packages or working download links found for %s%s",
+                (source and "a source distribution of " or ""),
+                requirement,
+            )
+        else:
+            self.info("Best match: %s", dist)
+            return dist.clone(location=dist.download_location)
+
+    def fetch(self, requirement, tmpdir, force_scan=False, source=False):
+        """Obtain a file suitable for fulfilling `requirement`
+
+        DEPRECATED; use the ``fetch_distribution()`` method now instead.  For
+        backward compatibility, this routine is identical but returns the
+        ``location`` of the downloaded distribution instead of a distribution
+        object.
+        """
+        dist = self.fetch_distribution(requirement, tmpdir, force_scan, source)
+        if dist is not None:
+            return dist.location
+        return None
+
+    def gen_setup(self, filename, fragment, tmpdir):
+        match = EGG_FRAGMENT.match(fragment)
+        dists = match and [
+            d for d in
+            interpret_distro_name(filename, match.group(1), None) if d.version
+        ] or []
+
+        if len(dists) == 1:  # unambiguous ``#egg`` fragment
+            basename = os.path.basename(filename)
+
+            # Make sure the file has been downloaded to the temp dir.
+            if os.path.dirname(filename) != tmpdir:
+                dst = os.path.join(tmpdir, basename)
+                from setuptools.command.easy_install import samefile
+                if not samefile(filename, dst):
+                    shutil.copy2(filename, dst)
+                    filename = dst
+
+            with open(os.path.join(tmpdir, 'setup.py'), 'w') as file:
+                file.write(
+                    "from setuptools import setup\n"
+                    "setup(name=%r, version=%r, py_modules=[%r])\n"
+                    % (
+                        dists[0].project_name, dists[0].version,
+                        os.path.splitext(basename)[0]
+                    )
+                )
+            return filename
+
+        elif match:
+            raise DistutilsError(
+                "Can't unambiguously interpret project/version identifier %r; "
+                "any dashes in the name or version should be escaped using "
+                "underscores. %r" % (fragment, dists)
+            )
+        else:
+            raise DistutilsError(
+                "Can't process plain .py files without an '#egg=name-version'"
+                " suffix to enable automatic setup script generation."
+            )
+
+    dl_blocksize = 8192
+
+    def _download_to(self, url, filename):
+        self.info("Downloading %s", url)
+        # Download the file
+        fp = None
+        try:
+            checker = HashChecker.from_url(url)
+            fp = self.open_url(url)
+            if isinstance(fp, urllib.error.HTTPError):
+                raise DistutilsError(
+                    "Can't download %s: %s %s" % (url, fp.code, fp.msg)
+                )
+            headers = fp.info()
+            blocknum = 0
+            bs = self.dl_blocksize
+            size = -1
+            if "content-length" in headers:
+                # Some servers return multiple Content-Length headers :(
+                sizes = get_all_headers(headers, 'Content-Length')
+                size = max(map(int, sizes))
+                self.reporthook(url, filename, blocknum, bs, size)
+            with open(filename, 'wb') as tfp:
+                while True:
+                    block = fp.read(bs)
+                    if block:
+                        checker.feed(block)
+                        tfp.write(block)
+                        blocknum += 1
+                        self.reporthook(url, filename, blocknum, bs, size)
+                    else:
+                        break
+                self.check_hash(checker, filename, tfp)
+            return headers
+        finally:
+            if fp:
+                fp.close()
+
+    def reporthook(self, url, filename, blocknum, blksize, size):
+        pass  # no-op
+
+    def open_url(self, url, warning=None):
+        if url.startswith('file:'):
+            return local_open(url)
+        try:
+            return open_with_auth(url, self.opener)
+        except (ValueError, http_client.InvalidURL) as v:
+            msg = ' '.join([str(arg) for arg in v.args])
+            if warning:
+                self.warn(warning, msg)
+            else:
+                raise DistutilsError('%s %s' % (url, msg))
+        except urllib.error.HTTPError as v:
+            return v
+        except urllib.error.URLError as v:
+            if warning:
+                self.warn(warning, v.reason)
+            else:
+                raise DistutilsError("Download error for %s: %s"
+                                     % (url, v.reason))
+        except http_client.BadStatusLine as v:
+            if warning:
+                self.warn(warning, v.line)
+            else:
+                raise DistutilsError(
+                    '%s returned a bad status line. The server might be '
+                    'down, %s' %
+                    (url, v.line)
+                )
+        except (http_client.HTTPException, socket.error) as v:
+            if warning:
+                self.warn(warning, v)
+            else:
+                raise DistutilsError("Download error for %s: %s"
+                                     % (url, v))
+
+    def _download_url(self, scheme, url, tmpdir):
+        # Determine download filename
+        #
+        name, fragment = egg_info_for_url(url)
+        if name:
+            while '..' in name:
+                name = name.replace('..', '.').replace('\\', '_')
+        else:
+            name = "__downloaded__"  # default if URL has no path contents
+
+        if name.endswith('.egg.zip'):
+            name = name[:-4]  # strip the extra .zip before download
+
+        filename = os.path.join(tmpdir, name)
+
+        # Download the file
+        #
+        if scheme == 'svn' or scheme.startswith('svn+'):
+            return self._download_svn(url, filename)
+        elif scheme == 'git' or scheme.startswith('git+'):
+            return self._download_git(url, filename)
+        elif scheme.startswith('hg+'):
+            return self._download_hg(url, filename)
+        elif scheme == 'file':
+            return urllib.request.url2pathname(urllib.parse.urlparse(url)[2])
+        else:
+            self.url_ok(url, True)  # raises error if not allowed
+            return self._attempt_download(url, filename)
+
+    def scan_url(self, url):
+        self.process_url(url, True)
+
+    def _attempt_download(self, url, filename):
+        headers = self._download_to(url, filename)
+        if 'html' in headers.get('content-type', '').lower():
+            return self._download_html(url, headers, filename)
+        else:
+            return filename
+
+    def _download_html(self, url, headers, filename):
+        file = open(filename)
+        for line in file:
+            if line.strip():
+                # Check for a subversion index page
+                if re.search(r'<title>([^- ]+ - )?Revision \d+:', line):
+                    # it's a subversion index page:
+                    file.close()
+                    os.unlink(filename)
+                    return self._download_svn(url, filename)
+                break  # not an index page
+        file.close()
+        os.unlink(filename)
+        raise DistutilsError("Unexpected HTML page found at " + url)
+
+    def _download_svn(self, url, filename):
+        url = url.split('#', 1)[0]  # remove any fragment for svn's sake
+        creds = ''
+        if url.lower().startswith('svn:') and '@' in url:
+            scheme, netloc, path, p, q, f = urllib.parse.urlparse(url)
+            if not netloc and path.startswith('//') and '/' in path[2:]:
+                netloc, path = path[2:].split('/', 1)
+                auth, host = urllib.parse.splituser(netloc)
+                if auth:
+                    if ':' in auth:
+                        user, pw = auth.split(':', 1)
+                        creds = " --username=%s --password=%s" % (user, pw)
+                    else:
+                        creds = " --username=" + auth
+                    netloc = host
+                    parts = scheme, netloc, url, p, q, f
+                    url = urllib.parse.urlunparse(parts)
+        self.info("Doing subversion checkout from %s to %s", url, filename)
+        os.system("svn checkout%s -q %s %s" % (creds, url, filename))
+        return filename
+
+    @staticmethod
+    def _vcs_split_rev_from_url(url, pop_prefix=False):
+        scheme, netloc, path, query, frag = urllib.parse.urlsplit(url)
+
+        scheme = scheme.split('+', 1)[-1]
+
+        # Some fragment identification fails
+        path = path.split('#', 1)[0]
+
+        rev = None
+        if '@' in path:
+            path, rev = path.rsplit('@', 1)
+
+        # Also, discard fragment
+        url = urllib.parse.urlunsplit((scheme, netloc, path, query, ''))
+
+        return url, rev
+
+    def _download_git(self, url, filename):
+        filename = filename.split('#', 1)[0]
+        url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True)
+
+        self.info("Doing git clone from %s to %s", url, filename)
+        os.system("git clone --quiet %s %s" % (url, filename))
+
+        if rev is not None:
+            self.info("Checking out %s", rev)
+            os.system("(cd %s && git checkout --quiet %s)" % (
+                filename,
+                rev,
+            ))
+
+        return filename
+
+    def _download_hg(self, url, filename):
+        filename = filename.split('#', 1)[0]
+        url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True)
+
+        self.info("Doing hg clone from %s to %s", url, filename)
+        os.system("hg clone --quiet %s %s" % (url, filename))
+
+        if rev is not None:
+            self.info("Updating to %s", rev)
+            os.system("(cd %s && hg up -C -r %s -q)" % (
+                filename,
+                rev,
+            ))
+
+        return filename
+
+    def debug(self, msg, *args):
+        log.debug(msg, *args)
+
+    def info(self, msg, *args):
+        log.info(msg, *args)
+
+    def warn(self, msg, *args):
+        log.warn(msg, *args)
+
+
+# This pattern matches a character entity reference (a decimal numeric
+# references, a hexadecimal numeric reference, or a named reference).
+entity_sub = re.compile(r'&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?').sub
+
+
+def decode_entity(match):
+    what = match.group(1)
+    return unescape(what)
+
+
+def htmldecode(text):
+    """Decode HTML entities in the given text."""
+    return entity_sub(decode_entity, text)
+
+
+def socket_timeout(timeout=15):
+    def _socket_timeout(func):
+        def _socket_timeout(*args, **kwargs):
+            old_timeout = socket.getdefaulttimeout()
+            socket.setdefaulttimeout(timeout)
+            try:
+                return func(*args, **kwargs)
+            finally:
+                socket.setdefaulttimeout(old_timeout)
+
+        return _socket_timeout
+
+    return _socket_timeout
+
+
+def _encode_auth(auth):
+    """
+    A function compatible with Python 2.3-3.3 that will encode
+    auth from a URL suitable for an HTTP header.
+    >>> str(_encode_auth('username%3Apassword'))
+    'dXNlcm5hbWU6cGFzc3dvcmQ='
+
+    Long auth strings should not cause a newline to be inserted.
+    >>> long_auth = 'username:' + 'password'*10
+    >>> chr(10) in str(_encode_auth(long_auth))
+    False
+    """
+    auth_s = urllib.parse.unquote(auth)
+    # convert to bytes
+    auth_bytes = auth_s.encode()
+    # use the legacy interface for Python 2.3 support
+    encoded_bytes = base64.encodestring(auth_bytes)
+    # convert back to a string
+    encoded = encoded_bytes.decode()
+    # strip the trailing carriage return
+    return encoded.replace('\n', '')
+
+
+class Credential(object):
+    """
+    A username/password pair. Use like a namedtuple.
+    """
+
+    def __init__(self, username, password):
+        self.username = username
+        self.password = password
+
+    def __iter__(self):
+        yield self.username
+        yield self.password
+
+    def __str__(self):
+        return '%(username)s:%(password)s' % vars(self)
+
+
+class PyPIConfig(configparser.RawConfigParser):
+    def __init__(self):
+        """
+        Load from ~/.pypirc
+        """
+        defaults = dict.fromkeys(['username', 'password', 'repository'], '')
+        configparser.RawConfigParser.__init__(self, defaults)
+
+        rc = os.path.join(os.path.expanduser('~'), '.pypirc')
+        if os.path.exists(rc):
+            self.read(rc)
+
+    @property
+    def creds_by_repository(self):
+        sections_with_repositories = [
+            section for section in self.sections()
+            if self.get(section, 'repository').strip()
+        ]
+
+        return dict(map(self._get_repo_cred, sections_with_repositories))
+
+    def _get_repo_cred(self, section):
+        repo = self.get(section, 'repository').strip()
+        return repo, Credential(
+            self.get(section, 'username').strip(),
+            self.get(section, 'password').strip(),
+        )
+
+    def find_credential(self, url):
+        """
+        If the URL indicated appears to be a repository defined in this
+        config, return the credential for that repository.
+        """
+        for repository, cred in self.creds_by_repository.items():
+            if url.startswith(repository):
+                return cred
+
+
+def open_with_auth(url, opener=urllib.request.urlopen):
+    """Open a urllib2 request, handling HTTP authentication"""
+
+    scheme, netloc, path, params, query, frag = urllib.parse.urlparse(url)
+
+    # Double scheme does not raise on Mac OS X as revealed by a
+    # failing test. We would expect "nonnumeric port". Refs #20.
+    if netloc.endswith(':'):
+        raise http_client.InvalidURL("nonnumeric port: ''")
+
+    if scheme in ('http', 'https'):
+        auth, host = urllib.parse.splituser(netloc)
+    else:
+        auth = None
+
+    if not auth:
+        cred = PyPIConfig().find_credential(url)
+        if cred:
+            auth = str(cred)
+            info = cred.username, url
+            log.info('Authenticating as %s for %s (from .pypirc)', *info)
+
+    if auth:
+        auth = "Basic " + _encode_auth(auth)
+        parts = scheme, host, path, params, query, frag
+        new_url = urllib.parse.urlunparse(parts)
+        request = urllib.request.Request(new_url)
+        request.add_header("Authorization", auth)
+    else:
+        request = urllib.request.Request(url)
+
+    request.add_header('User-Agent', user_agent)
+    fp = opener(request)
+
+    if auth:
+        # Put authentication info back into request URL if same host,
+        # so that links found on the page will work
+        s2, h2, path2, param2, query2, frag2 = urllib.parse.urlparse(fp.url)
+        if s2 == scheme and h2 == host:
+            parts = s2, netloc, path2, param2, query2, frag2
+            fp.url = urllib.parse.urlunparse(parts)
+
+    return fp
+
+
+# adding a timeout to avoid freezing package_index
+open_with_auth = socket_timeout(_SOCKET_TIMEOUT)(open_with_auth)
+
+
+def fix_sf_url(url):
+    return url  # backward compatibility
+
+
+def local_open(url):
+    """Read a local path, with special support for directories"""
+    scheme, server, path, param, query, frag = urllib.parse.urlparse(url)
+    filename = urllib.request.url2pathname(path)
+    if os.path.isfile(filename):
+        return urllib.request.urlopen(url)
+    elif path.endswith('/') and os.path.isdir(filename):
+        files = []
+        for f in os.listdir(filename):
+            filepath = os.path.join(filename, f)
+            if f == 'index.html':
+                with open(filepath, 'r') as fp:
+                    body = fp.read()
+                break
+            elif os.path.isdir(filepath):
+                f += '/'
+            files.append('<a href="{name}">{name}</a>'.format(name=f))
+        else:
+            tmpl = (
+                "<html><head><title>{url}</title>"
+                "</head><body>{files}</body></html>")
+            body = tmpl.format(url=url, files='\n'.join(files))
+        status, message = 200, "OK"
+    else:
+        status, message, body = 404, "Path not found", "Not found"
+
+    headers = {'content-type': 'text/html'}
+    body_stream = six.StringIO(body)
+    return urllib.error.HTTPError(url, status, message, headers, body_stream)
diff --git a/vendor/setuptools-39.0.1/setuptools/pep425tags.py b/vendor/setuptools-39.0.1/setuptools/pep425tags.py
new file mode 100644
index 00000000..dfe55d58
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/pep425tags.py
@@ -0,0 +1,316 @@
+# This file originally from pip:
+# https://github.com/pypa/pip/blob/8f4f15a5a95d7d5b511ceaee9ed261176c181970/src/pip/_internal/pep425tags.py
+"""Generate and work with PEP 425 Compatibility Tags."""
+from __future__ import absolute_import
+
+import distutils.util
+import platform
+import re
+import sys
+import sysconfig
+import warnings
+from collections import OrderedDict
+
+from . import glibc
+
+_osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)')
+
+
+def get_config_var(var):
+    try:
+        return sysconfig.get_config_var(var)
+    except IOError as e:  # Issue #1074
+        warnings.warn("{}".format(e), RuntimeWarning)
+        return None
+
+
+def get_abbr_impl():
+    """Return abbreviated implementation name."""
+    if hasattr(sys, 'pypy_version_info'):
+        pyimpl = 'pp'
+    elif sys.platform.startswith('java'):
+        pyimpl = 'jy'
+    elif sys.platform == 'cli':
+        pyimpl = 'ip'
+    else:
+        pyimpl = 'cp'
+    return pyimpl
+
+
+def get_impl_ver():
+    """Return implementation version."""
+    impl_ver = get_config_var("py_version_nodot")
+    if not impl_ver or get_abbr_impl() == 'pp':
+        impl_ver = ''.join(map(str, get_impl_version_info()))
+    return impl_ver
+
+
+def get_impl_version_info():
+    """Return sys.version_info-like tuple for use in decrementing the minor
+    version."""
+    if get_abbr_impl() == 'pp':
+        # as per https://github.com/pypa/pip/issues/2882
+        return (sys.version_info[0], sys.pypy_version_info.major,
+                sys.pypy_version_info.minor)
+    else:
+        return sys.version_info[0], sys.version_info[1]
+
+
+def get_impl_tag():
+    """
+    Returns the Tag for this specific implementation.
+    """
+    return "{}{}".format(get_abbr_impl(), get_impl_ver())
+
+
+def get_flag(var, fallback, expected=True, warn=True):
+    """Use a fallback method for determining SOABI flags if the needed config
+    var is unset or unavailable."""
+    val = get_config_var(var)
+    if val is None:
+        if warn:
+            warnings.warn("Config variable '{0}' is unset, Python ABI tag may "
+                          "be incorrect".format(var), RuntimeWarning, 2)
+        return fallback()
+    return val == expected
+
+
+def get_abi_tag():
+    """Return the ABI tag based on SOABI (if available) or emulate SOABI
+    (CPython 2, PyPy)."""
+    soabi = get_config_var('SOABI')
+    impl = get_abbr_impl()
+    if not soabi and impl in {'cp', 'pp'} and hasattr(sys, 'maxunicode'):
+        d = ''
+        m = ''
+        u = ''
+        if get_flag('Py_DEBUG',
+                    lambda: hasattr(sys, 'gettotalrefcount'),
+                    warn=(impl == 'cp')):
+            d = 'd'
+        if get_flag('WITH_PYMALLOC',
+                    lambda: impl == 'cp',
+                    warn=(impl == 'cp')):
+            m = 'm'
+        if get_flag('Py_UNICODE_SIZE',
+                    lambda: sys.maxunicode == 0x10ffff,
+                    expected=4,
+                    warn=(impl == 'cp' and
+                          sys.version_info < (3, 3))) \
+                and sys.version_info < (3, 3):
+            u = 'u'
+        abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u)
+    elif soabi and soabi.startswith('cpython-'):
+        abi = 'cp' + soabi.split('-')[1]
+    elif soabi:
+        abi = soabi.replace('.', '_').replace('-', '_')
+    else:
+        abi = None
+    return abi
+
+
+def _is_running_32bit():
+    return sys.maxsize == 2147483647
+
+
+def get_platform():
+    """Return our platform name 'win32', 'linux_x86_64'"""
+    if sys.platform == 'darwin':
+        # distutils.util.get_platform() returns the release based on the value
+        # of MACOSX_DEPLOYMENT_TARGET on which Python was built, which may
+        # be significantly older than the user's current machine.
+        release, _, machine = platform.mac_ver()
+        split_ver = release.split('.')
+
+        if machine == "x86_64" and _is_running_32bit():
+            machine = "i386"
+        elif machine == "ppc64" and _is_running_32bit():
+            machine = "ppc"
+
+        return 'macosx_{}_{}_{}'.format(split_ver[0], split_ver[1], machine)
+
+    # XXX remove distutils dependency
+    result = distutils.util.get_platform().replace('.', '_').replace('-', '_')
+    if result == "linux_x86_64" and _is_running_32bit():
+        # 32 bit Python program (running on a 64 bit Linux): pip should only
+        # install and run 32 bit compiled extensions in that case.
+        result = "linux_i686"
+
+    return result
+
+
+def is_manylinux1_compatible():
+    # Only Linux, and only x86-64 / i686
+    if get_platform() not in {"linux_x86_64", "linux_i686"}:
+        return False
+
+    # Check for presence of _manylinux module
+    try:
+        import _manylinux
+        return bool(_manylinux.manylinux1_compatible)
+    except (ImportError, AttributeError):
+        # Fall through to heuristic check below
+        pass
+
+    # Check glibc version. CentOS 5 uses glibc 2.5.
+    return glibc.have_compatible_glibc(2, 5)
+
+
+def get_darwin_arches(major, minor, machine):
+    """Return a list of supported arches (including group arches) for
+    the given major, minor and machine architecture of an macOS machine.
+    """
+    arches = []
+
+    def _supports_arch(major, minor, arch):
+        # Looking at the application support for macOS versions in the chart
+        # provided by https://en.wikipedia.org/wiki/OS_X#Versions it appears
+        # our timeline looks roughly like:
+        #
+        # 10.0 - Introduces ppc support.
+        # 10.4 - Introduces ppc64, i386, and x86_64 support, however the ppc64
+        #        and x86_64 support is CLI only, and cannot be used for GUI
+        #        applications.
+        # 10.5 - Extends ppc64 and x86_64 support to cover GUI applications.
+        # 10.6 - Drops support for ppc64
+        # 10.7 - Drops support for ppc
+        #
+        # Given that we do not know if we're installing a CLI or a GUI
+        # application, we must be conservative and assume it might be a GUI
+        # application and behave as if ppc64 and x86_64 support did not occur
+        # until 10.5.
+        #
+        # Note: The above information is taken from the "Application support"
+        #       column in the chart not the "Processor support" since I believe
+        #       that we care about what instruction sets an application can use
+        #       not which processors the OS supports.
+        if arch == 'ppc':
+            return (major, minor) <= (10, 5)
+        if arch == 'ppc64':
+            return (major, minor) == (10, 5)
+        if arch == 'i386':
+            return (major, minor) >= (10, 4)
+        if arch == 'x86_64':
+            return (major, minor) >= (10, 5)
+        if arch in groups:
+            for garch in groups[arch]:
+                if _supports_arch(major, minor, garch):
+                    return True
+        return False
+
+    groups = OrderedDict([
+        ("fat", ("i386", "ppc")),
+        ("intel", ("x86_64", "i386")),
+        ("fat64", ("x86_64", "ppc64")),
+        ("fat32", ("x86_64", "i386", "ppc")),
+    ])
+
+    if _supports_arch(major, minor, machine):
+        arches.append(machine)
+
+    for garch in groups:
+        if machine in groups[garch] and _supports_arch(major, minor, garch):
+            arches.append(garch)
+
+    arches.append('universal')
+
+    return arches
+
+
+def get_supported(versions=None, noarch=False, platform=None,
+                  impl=None, abi=None):
+    """Return a list of supported tags for each version specified in
+    `versions`.
+
+    :param versions: a list of string versions, of the form ["33", "32"],
+        or None. The first version will be assumed to support our ABI.
+    :param platform: specify the exact platform you want valid
+        tags for, or None. If None, use the local system platform.
+    :param impl: specify the exact implementation you want valid
+        tags for, or None. If None, use the local interpreter impl.
+    :param abi: specify the exact abi you want valid
+        tags for, or None. If None, use the local interpreter abi.
+    """
+    supported = []
+
+    # Versions must be given with respect to the preference
+    if versions is None:
+        versions = []
+        version_info = get_impl_version_info()
+        major = version_info[:-1]
+        # Support all previous minor Python versions.
+        for minor in range(version_info[-1], -1, -1):
+            versions.append(''.join(map(str, major + (minor,))))
+
+    impl = impl or get_abbr_impl()
+
+    abis = []
+
+    abi = abi or get_abi_tag()
+    if abi:
+        abis[0:0] = [abi]
+
+    abi3s = set()
+    import imp
+    for suffix in imp.get_suffixes():
+        if suffix[0].startswith('.abi'):
+            abi3s.add(suffix[0].split('.', 2)[1])
+
+    abis.extend(sorted(list(abi3s)))
+
+    abis.append('none')
+
+    if not noarch:
+        arch = platform or get_platform()
+        if arch.startswith('macosx'):
+            # support macosx-10.6-intel on macosx-10.9-x86_64
+            match = _osx_arch_pat.match(arch)
+            if match:
+                name, major, minor, actual_arch = match.groups()
+                tpl = '{}_{}_%i_%s'.format(name, major)
+                arches = []
+                for m in reversed(range(int(minor) + 1)):
+                    for a in get_darwin_arches(int(major), m, actual_arch):
+                        arches.append(tpl % (m, a))
+            else:
+                # arch pattern didn't match (?!)
+                arches = [arch]
+        elif platform is None and is_manylinux1_compatible():
+            arches = [arch.replace('linux', 'manylinux1'), arch]
+        else:
+            arches = [arch]
+
+        # Current version, current API (built specifically for our Python):
+        for abi in abis:
+            for arch in arches:
+                supported.append(('%s%s' % (impl, versions[0]), abi, arch))
+
+        # abi3 modules compatible with older version of Python
+        for version in versions[1:]:
+            # abi3 was introduced in Python 3.2
+            if version in {'31', '30'}:
+                break
+            for abi in abi3s:   # empty set if not Python 3
+                for arch in arches:
+                    supported.append(("%s%s" % (impl, version), abi, arch))
+
+        # Has binaries, does not use the Python API:
+        for arch in arches:
+            supported.append(('py%s' % (versions[0][0]), 'none', arch))
+
+    # No abi / arch, but requires our implementation:
+    supported.append(('%s%s' % (impl, versions[0]), 'none', 'any'))
+    # Tagged specifically as being cross-version compatible
+    # (with just the major version specified)
+    supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any'))
+
+    # No abi / arch, generic Python
+    for i, version in enumerate(versions):
+        supported.append(('py%s' % (version,), 'none', 'any'))
+        if i == 0:
+            supported.append(('py%s' % (version[0]), 'none', 'any'))
+
+    return supported
+
+
+implementation_tag = get_impl_tag()
diff --git a/vendor/setuptools-39.0.1/setuptools/py27compat.py b/vendor/setuptools-39.0.1/setuptools/py27compat.py
new file mode 100644
index 00000000..2985011b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/py27compat.py
@@ -0,0 +1,28 @@
+"""
+Compatibility Support for Python 2.7 and earlier
+"""
+
+import platform
+
+from setuptools.extern import six
+
+
+def get_all_headers(message, key):
+    """
+    Given an HTTPMessage, return all headers matching a given key.
+    """
+    return message.get_all(key)
+
+
+if six.PY2:
+    def get_all_headers(message, key):
+        return message.getheaders(key)
+
+
+linux_py2_ascii = (
+    platform.system() == 'Linux' and
+    six.PY2
+)
+
+rmtree_safe = str if linux_py2_ascii else lambda x: x
+"""Workaround for http://bugs.python.org/issue24672"""
diff --git a/vendor/setuptools-39.0.1/setuptools/py31compat.py b/vendor/setuptools-39.0.1/setuptools/py31compat.py
new file mode 100644
index 00000000..4ea95320
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/py31compat.py
@@ -0,0 +1,41 @@
+__all__ = ['get_config_vars', 'get_path']
+
+try:
+    # Python 2.7 or >=3.2
+    from sysconfig import get_config_vars, get_path
+except ImportError:
+    from distutils.sysconfig import get_config_vars, get_python_lib
+
+    def get_path(name):
+        if name not in ('platlib', 'purelib'):
+            raise ValueError("Name must be purelib or platlib")
+        return get_python_lib(name == 'platlib')
+
+
+try:
+    # Python >=3.2
+    from tempfile import TemporaryDirectory
+except ImportError:
+    import shutil
+    import tempfile
+
+    class TemporaryDirectory(object):
+        """
+        Very simple temporary directory context manager.
+        Will try to delete afterward, but will also ignore OS and similar
+        errors on deletion.
+        """
+
+        def __init__(self):
+            self.name = None  # Handle mkdtemp raising an exception
+            self.name = tempfile.mkdtemp()
+
+        def __enter__(self):
+            return self.name
+
+        def __exit__(self, exctype, excvalue, exctrace):
+            try:
+                shutil.rmtree(self.name, True)
+            except OSError:  # removal errors are not the only possible
+                pass
+            self.name = None
diff --git a/vendor/setuptools-39.0.1/setuptools/py33compat.py b/vendor/setuptools-39.0.1/setuptools/py33compat.py
new file mode 100644
index 00000000..2a73ebb3
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/py33compat.py
@@ -0,0 +1,54 @@
+import dis
+import array
+import collections
+
+try:
+    import html
+except ImportError:
+    html = None
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import html_parser
+
+
+OpArg = collections.namedtuple('OpArg', 'opcode arg')
+
+
+class Bytecode_compat(object):
+    def __init__(self, code):
+        self.code = code
+
+    def __iter__(self):
+        """Yield '(op,arg)' pair for each operation in code object 'code'"""
+
+        bytes = array.array('b', self.code.co_code)
+        eof = len(self.code.co_code)
+
+        ptr = 0
+        extended_arg = 0
+
+        while ptr < eof:
+
+            op = bytes[ptr]
+
+            if op >= dis.HAVE_ARGUMENT:
+
+                arg = bytes[ptr + 1] + bytes[ptr + 2] * 256 + extended_arg
+                ptr += 3
+
+                if op == dis.EXTENDED_ARG:
+                    long_type = six.integer_types[-1]
+                    extended_arg = arg * long_type(65536)
+                    continue
+
+            else:
+                arg = None
+                ptr += 1
+
+            yield OpArg(op, arg)
+
+
+Bytecode = getattr(dis, 'Bytecode', Bytecode_compat)
+
+
+unescape = getattr(html, 'unescape', html_parser.HTMLParser().unescape)
diff --git a/vendor/setuptools-39.0.1/setuptools/py36compat.py b/vendor/setuptools-39.0.1/setuptools/py36compat.py
new file mode 100644
index 00000000..f5279696
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/py36compat.py
@@ -0,0 +1,82 @@
+import sys
+from distutils.errors import DistutilsOptionError
+from distutils.util import strtobool
+from distutils.debug import DEBUG
+
+
+class Distribution_parse_config_files:
+    """
+    Mix-in providing forward-compatibility for functionality to be
+    included by default on Python 3.7.
+
+    Do not edit the code in this class except to update functionality
+    as implemented in distutils.
+    """
+    def parse_config_files(self, filenames=None):
+        from configparser import ConfigParser
+
+        # Ignore install directory options if we have a venv
+        if sys.prefix != sys.base_prefix:
+            ignore_options = [
+                'install-base', 'install-platbase', 'install-lib',
+                'install-platlib', 'install-purelib', 'install-headers',
+                'install-scripts', 'install-data', 'prefix', 'exec-prefix',
+                'home', 'user', 'root']
+        else:
+            ignore_options = []
+
+        ignore_options = frozenset(ignore_options)
+
+        if filenames is None:
+            filenames = self.find_config_files()
+
+        if DEBUG:
+            self.announce("Distribution.parse_config_files():")
+
+        parser = ConfigParser(interpolation=None)
+        for filename in filenames:
+            if DEBUG:
+                self.announce("  reading %s" % filename)
+            parser.read(filename)
+            for section in parser.sections():
+                options = parser.options(section)
+                opt_dict = self.get_option_dict(section)
+
+                for opt in options:
+                    if opt != '__name__' and opt not in ignore_options:
+                        val = parser.get(section,opt)
+                        opt = opt.replace('-', '_')
+                        opt_dict[opt] = (filename, val)
+
+            # Make the ConfigParser forget everything (so we retain
+            # the original filenames that options come from)
+            parser.__init__()
+
+        # If there was a "global" section in the config file, use it
+        # to set Distribution options.
+
+        if 'global' in self.command_options:
+            for (opt, (src, val)) in self.command_options['global'].items():
+                alias = self.negative_opt.get(opt)
+                try:
+                    if alias:
+                        setattr(self, alias, not strtobool(val))
+                    elif opt in ('verbose', 'dry_run'): # ugh!
+                        setattr(self, opt, strtobool(val))
+                    else:
+                        setattr(self, opt, val)
+                except ValueError as msg:
+                    raise DistutilsOptionError(msg)
+
+
+if sys.version_info < (3,):
+    # Python 2 behavior is sufficient
+    class Distribution_parse_config_files:
+        pass
+
+
+if False:
+    # When updated behavior is available upstream,
+    # disable override here.
+    class Distribution_parse_config_files:
+        pass
diff --git a/vendor/setuptools-39.0.1/setuptools/sandbox.py b/vendor/setuptools-39.0.1/setuptools/sandbox.py
new file mode 100755
index 00000000..685f3f72
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/sandbox.py
@@ -0,0 +1,491 @@
+import os
+import sys
+import tempfile
+import operator
+import functools
+import itertools
+import re
+import contextlib
+import pickle
+import textwrap
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import builtins, map
+
+import pkg_resources.py31compat
+
+if sys.platform.startswith('java'):
+    import org.python.modules.posix.PosixModule as _os
+else:
+    _os = sys.modules[os.name]
+try:
+    _file = file
+except NameError:
+    _file = None
+_open = open
+from distutils.errors import DistutilsError
+from pkg_resources import working_set
+
+
+__all__ = [
+    "AbstractSandbox", "DirectorySandbox", "SandboxViolation", "run_setup",
+]
+
+
+def _execfile(filename, globals, locals=None):
+    """
+    Python 3 implementation of execfile.
+    """
+    mode = 'rb'
+    with open(filename, mode) as stream:
+        script = stream.read()
+    if locals is None:
+        locals = globals
+    code = compile(script, filename, 'exec')
+    exec(code, globals, locals)
+
+
+@contextlib.contextmanager
+def save_argv(repl=None):
+    saved = sys.argv[:]
+    if repl is not None:
+        sys.argv[:] = repl
+    try:
+        yield saved
+    finally:
+        sys.argv[:] = saved
+
+
+@contextlib.contextmanager
+def save_path():
+    saved = sys.path[:]
+    try:
+        yield saved
+    finally:
+        sys.path[:] = saved
+
+
+@contextlib.contextmanager
+def override_temp(replacement):
+    """
+    Monkey-patch tempfile.tempdir with replacement, ensuring it exists
+    """
+    pkg_resources.py31compat.makedirs(replacement, exist_ok=True)
+
+    saved = tempfile.tempdir
+
+    tempfile.tempdir = replacement
+
+    try:
+        yield
+    finally:
+        tempfile.tempdir = saved
+
+
+@contextlib.contextmanager
+def pushd(target):
+    saved = os.getcwd()
+    os.chdir(target)
+    try:
+        yield saved
+    finally:
+        os.chdir(saved)
+
+
+class UnpickleableException(Exception):
+    """
+    An exception representing another Exception that could not be pickled.
+    """
+
+    @staticmethod
+    def dump(type, exc):
+        """
+        Always return a dumped (pickled) type and exc. If exc can't be pickled,
+        wrap it in UnpickleableException first.
+        """
+        try:
+            return pickle.dumps(type), pickle.dumps(exc)
+        except Exception:
+            # get UnpickleableException inside the sandbox
+            from setuptools.sandbox import UnpickleableException as cls
+            return cls.dump(cls, cls(repr(exc)))
+
+
+class ExceptionSaver:
+    """
+    A Context Manager that will save an exception, serialized, and restore it
+    later.
+    """
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, exc, tb):
+        if not exc:
+            return
+
+        # dump the exception
+        self._saved = UnpickleableException.dump(type, exc)
+        self._tb = tb
+
+        # suppress the exception
+        return True
+
+    def resume(self):
+        "restore and re-raise any exception"
+
+        if '_saved' not in vars(self):
+            return
+
+        type, exc = map(pickle.loads, self._saved)
+        six.reraise(type, exc, self._tb)
+
+
+@contextlib.contextmanager
+def save_modules():
+    """
+    Context in which imported modules are saved.
+
+    Translates exceptions internal to the context into the equivalent exception
+    outside the context.
+    """
+    saved = sys.modules.copy()
+    with ExceptionSaver() as saved_exc:
+        yield saved
+
+    sys.modules.update(saved)
+    # remove any modules imported since
+    del_modules = (
+        mod_name for mod_name in sys.modules
+        if mod_name not in saved
+        # exclude any encodings modules. See #285
+        and not mod_name.startswith('encodings.')
+    )
+    _clear_modules(del_modules)
+
+    saved_exc.resume()
+
+
+def _clear_modules(module_names):
+    for mod_name in list(module_names):
+        del sys.modules[mod_name]
+
+
+@contextlib.contextmanager
+def save_pkg_resources_state():
+    saved = pkg_resources.__getstate__()
+    try:
+        yield saved
+    finally:
+        pkg_resources.__setstate__(saved)
+
+
+@contextlib.contextmanager
+def setup_context(setup_dir):
+    temp_dir = os.path.join(setup_dir, 'temp')
+    with save_pkg_resources_state():
+        with save_modules():
+            hide_setuptools()
+            with save_path():
+                with save_argv():
+                    with override_temp(temp_dir):
+                        with pushd(setup_dir):
+                            # ensure setuptools commands are available
+                            __import__('setuptools')
+                            yield
+
+
+def _needs_hiding(mod_name):
+    """
+    >>> _needs_hiding('setuptools')
+    True
+    >>> _needs_hiding('pkg_resources')
+    True
+    >>> _needs_hiding('setuptools_plugin')
+    False
+    >>> _needs_hiding('setuptools.__init__')
+    True
+    >>> _needs_hiding('distutils')
+    True
+    >>> _needs_hiding('os')
+    False
+    >>> _needs_hiding('Cython')
+    True
+    """
+    pattern = re.compile(r'(setuptools|pkg_resources|distutils|Cython)(\.|$)')
+    return bool(pattern.match(mod_name))
+
+
+def hide_setuptools():
+    """
+    Remove references to setuptools' modules from sys.modules to allow the
+    invocation to import the most appropriate setuptools. This technique is
+    necessary to avoid issues such as #315 where setuptools upgrading itself
+    would fail to find a function declared in the metadata.
+    """
+    modules = filter(_needs_hiding, sys.modules)
+    _clear_modules(modules)
+
+
+def run_setup(setup_script, args):
+    """Run a distutils setup script, sandboxed in its directory"""
+    setup_dir = os.path.abspath(os.path.dirname(setup_script))
+    with setup_context(setup_dir):
+        try:
+            sys.argv[:] = [setup_script] + list(args)
+            sys.path.insert(0, setup_dir)
+            # reset to include setup dir, w/clean callback list
+            working_set.__init__()
+            working_set.callbacks.append(lambda dist: dist.activate())
+
+            # __file__ should be a byte string on Python 2 (#712)
+            dunder_file = (
+                setup_script
+                if isinstance(setup_script, str) else
+                setup_script.encode(sys.getfilesystemencoding())
+            )
+
+            with DirectorySandbox(setup_dir):
+                ns = dict(__file__=dunder_file, __name__='__main__')
+                _execfile(setup_script, ns)
+        except SystemExit as v:
+            if v.args and v.args[0]:
+                raise
+            # Normal exit, just return
+
+
+class AbstractSandbox:
+    """Wrap 'os' module and 'open()' builtin for virtualizing setup scripts"""
+
+    _active = False
+
+    def __init__(self):
+        self._attrs = [
+            name for name in dir(_os)
+            if not name.startswith('_') and hasattr(self, name)
+        ]
+
+    def _copy(self, source):
+        for name in self._attrs:
+            setattr(os, name, getattr(source, name))
+
+    def __enter__(self):
+        self._copy(self)
+        if _file:
+            builtins.file = self._file
+        builtins.open = self._open
+        self._active = True
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        self._active = False
+        if _file:
+            builtins.file = _file
+        builtins.open = _open
+        self._copy(_os)
+
+    def run(self, func):
+        """Run 'func' under os sandboxing"""
+        with self:
+            return func()
+
+    def _mk_dual_path_wrapper(name):
+        original = getattr(_os, name)
+
+        def wrap(self, src, dst, *args, **kw):
+            if self._active:
+                src, dst = self._remap_pair(name, src, dst, *args, **kw)
+            return original(src, dst, *args, **kw)
+
+        return wrap
+
+    for name in ["rename", "link", "symlink"]:
+        if hasattr(_os, name):
+            locals()[name] = _mk_dual_path_wrapper(name)
+
+    def _mk_single_path_wrapper(name, original=None):
+        original = original or getattr(_os, name)
+
+        def wrap(self, path, *args, **kw):
+            if self._active:
+                path = self._remap_input(name, path, *args, **kw)
+            return original(path, *args, **kw)
+
+        return wrap
+
+    if _file:
+        _file = _mk_single_path_wrapper('file', _file)
+    _open = _mk_single_path_wrapper('open', _open)
+    for name in [
+        "stat", "listdir", "chdir", "open", "chmod", "chown", "mkdir",
+        "remove", "unlink", "rmdir", "utime", "lchown", "chroot", "lstat",
+        "startfile", "mkfifo", "mknod", "pathconf", "access"
+    ]:
+        if hasattr(_os, name):
+            locals()[name] = _mk_single_path_wrapper(name)
+
+    def _mk_single_with_return(name):
+        original = getattr(_os, name)
+
+        def wrap(self, path, *args, **kw):
+            if self._active:
+                path = self._remap_input(name, path, *args, **kw)
+                return self._remap_output(name, original(path, *args, **kw))
+            return original(path, *args, **kw)
+
+        return wrap
+
+    for name in ['readlink', 'tempnam']:
+        if hasattr(_os, name):
+            locals()[name] = _mk_single_with_return(name)
+
+    def _mk_query(name):
+        original = getattr(_os, name)
+
+        def wrap(self, *args, **kw):
+            retval = original(*args, **kw)
+            if self._active:
+                return self._remap_output(name, retval)
+            return retval
+
+        return wrap
+
+    for name in ['getcwd', 'tmpnam']:
+        if hasattr(_os, name):
+            locals()[name] = _mk_query(name)
+
+    def _validate_path(self, path):
+        """Called to remap or validate any path, whether input or output"""
+        return path
+
+    def _remap_input(self, operation, path, *args, **kw):
+        """Called for path inputs"""
+        return self._validate_path(path)
+
+    def _remap_output(self, operation, path):
+        """Called for path outputs"""
+        return self._validate_path(path)
+
+    def _remap_pair(self, operation, src, dst, *args, **kw):
+        """Called for path pairs like rename, link, and symlink operations"""
+        return (
+            self._remap_input(operation + '-from', src, *args, **kw),
+            self._remap_input(operation + '-to', dst, *args, **kw)
+        )
+
+
+if hasattr(os, 'devnull'):
+    _EXCEPTIONS = [os.devnull,]
+else:
+    _EXCEPTIONS = []
+
+
+class DirectorySandbox(AbstractSandbox):
+    """Restrict operations to a single subdirectory - pseudo-chroot"""
+
+    write_ops = dict.fromkeys([
+        "open", "chmod", "chown", "mkdir", "remove", "unlink", "rmdir",
+        "utime", "lchown", "chroot", "mkfifo", "mknod", "tempnam",
+    ])
+
+    _exception_patterns = [
+        # Allow lib2to3 to attempt to save a pickled grammar object (#121)
+        r'.*lib2to3.*\.pickle$',
+    ]
+    "exempt writing to paths that match the pattern"
+
+    def __init__(self, sandbox, exceptions=_EXCEPTIONS):
+        self._sandbox = os.path.normcase(os.path.realpath(sandbox))
+        self._prefix = os.path.join(self._sandbox, '')
+        self._exceptions = [
+            os.path.normcase(os.path.realpath(path))
+            for path in exceptions
+        ]
+        AbstractSandbox.__init__(self)
+
+    def _violation(self, operation, *args, **kw):
+        from setuptools.sandbox import SandboxViolation
+        raise SandboxViolation(operation, args, kw)
+
+    if _file:
+
+        def _file(self, path, mode='r', *args, **kw):
+            if mode not in ('r', 'rt', 'rb', 'rU', 'U') and not self._ok(path):
+                self._violation("file", path, mode, *args, **kw)
+            return _file(path, mode, *args, **kw)
+
+    def _open(self, path, mode='r', *args, **kw):
+        if mode not in ('r', 'rt', 'rb', 'rU', 'U') and not self._ok(path):
+            self._violation("open", path, mode, *args, **kw)
+        return _open(path, mode, *args, **kw)
+
+    def tmpnam(self):
+        self._violation("tmpnam")
+
+    def _ok(self, path):
+        active = self._active
+        try:
+            self._active = False
+            realpath = os.path.normcase(os.path.realpath(path))
+            return (
+                self._exempted(realpath)
+                or realpath == self._sandbox
+                or realpath.startswith(self._prefix)
+            )
+        finally:
+            self._active = active
+
+    def _exempted(self, filepath):
+        start_matches = (
+            filepath.startswith(exception)
+            for exception in self._exceptions
+        )
+        pattern_matches = (
+            re.match(pattern, filepath)
+            for pattern in self._exception_patterns
+        )
+        candidates = itertools.chain(start_matches, pattern_matches)
+        return any(candidates)
+
+    def _remap_input(self, operation, path, *args, **kw):
+        """Called for path inputs"""
+        if operation in self.write_ops and not self._ok(path):
+            self._violation(operation, os.path.realpath(path), *args, **kw)
+        return path
+
+    def _remap_pair(self, operation, src, dst, *args, **kw):
+        """Called for path pairs like rename, link, and symlink operations"""
+        if not self._ok(src) or not self._ok(dst):
+            self._violation(operation, src, dst, *args, **kw)
+        return (src, dst)
+
+    def open(self, file, flags, mode=0o777, *args, **kw):
+        """Called for low-level os.open()"""
+        if flags & WRITE_FLAGS and not self._ok(file):
+            self._violation("os.open", file, flags, mode, *args, **kw)
+        return _os.open(file, flags, mode, *args, **kw)
+
+
+WRITE_FLAGS = functools.reduce(
+    operator.or_, [getattr(_os, a, 0) for a in
+        "O_WRONLY O_RDWR O_APPEND O_CREAT O_TRUNC O_TEMPORARY".split()]
+)
+
+
+class SandboxViolation(DistutilsError):
+    """A setup script attempted to modify the filesystem outside the sandbox"""
+
+    tmpl = textwrap.dedent("""
+        SandboxViolation: {cmd}{args!r} {kwargs}
+
+        The package setup script has attempted to modify files on your system
+        that are not within the EasyInstall build area, and has been aborted.
+
+        This package cannot be safely installed by EasyInstall, and may not
+        support alternate installation locations even if you run its setup
+        script by hand.  Please inform the package's author and the EasyInstall
+        maintainers to find out if a fix or workaround is available.
+        """).lstrip()
+
+    def __str__(self):
+        cmd, args, kwargs = self.args
+        return self.tmpl.format(**locals())
diff --git a/vendor/setuptools-39.0.1/setuptools/script (dev).tmpl b/vendor/setuptools-39.0.1/setuptools/script (dev).tmpl
new file mode 100644
index 00000000..d58b1bb5
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/script (dev).tmpl	
@@ -0,0 +1,5 @@
+# EASY-INSTALL-DEV-SCRIPT: %(spec)r,%(script_name)r
+__requires__ = %(spec)r
+__import__('pkg_resources').require(%(spec)r)
+__file__ = %(dev_path)r
+exec(compile(open(__file__).read(), __file__, 'exec'))
diff --git a/vendor/setuptools-39.0.1/setuptools/script.tmpl b/vendor/setuptools-39.0.1/setuptools/script.tmpl
new file mode 100644
index 00000000..ff5efbca
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/script.tmpl
@@ -0,0 +1,3 @@
+# EASY-INSTALL-SCRIPT: %(spec)r,%(script_name)r
+__requires__ = %(spec)r
+__import__('pkg_resources').run_script(%(spec)r, %(script_name)r)
diff --git a/vendor/setuptools-39.0.1/setuptools/site-patch.py b/vendor/setuptools-39.0.1/setuptools/site-patch.py
new file mode 100644
index 00000000..0d2d2ff8
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/site-patch.py
@@ -0,0 +1,74 @@
+def __boot():
+    import sys
+    import os
+    PYTHONPATH = os.environ.get('PYTHONPATH')
+    if PYTHONPATH is None or (sys.platform == 'win32' and not PYTHONPATH):
+        PYTHONPATH = []
+    else:
+        PYTHONPATH = PYTHONPATH.split(os.pathsep)
+
+    pic = getattr(sys, 'path_importer_cache', {})
+    stdpath = sys.path[len(PYTHONPATH):]
+    mydir = os.path.dirname(__file__)
+
+    for item in stdpath:
+        if item == mydir or not item:
+            continue  # skip if current dir. on Windows, or my own directory
+        importer = pic.get(item)
+        if importer is not None:
+            loader = importer.find_module('site')
+            if loader is not None:
+                # This should actually reload the current module
+                loader.load_module('site')
+                break
+        else:
+            try:
+                import imp  # Avoid import loop in Python >= 3.3
+                stream, path, descr = imp.find_module('site', [item])
+            except ImportError:
+                continue
+            if stream is None:
+                continue
+            try:
+                # This should actually reload the current module
+                imp.load_module('site', stream, path, descr)
+            finally:
+                stream.close()
+            break
+    else:
+        raise ImportError("Couldn't find the real 'site' module")
+
+    known_paths = dict([(makepath(item)[1], 1) for item in sys.path])  # 2.2 comp
+
+    oldpos = getattr(sys, '__egginsert', 0)  # save old insertion position
+    sys.__egginsert = 0  # and reset the current one
+
+    for item in PYTHONPATH:
+        addsitedir(item)
+
+    sys.__egginsert += oldpos  # restore effective old position
+
+    d, nd = makepath(stdpath[0])
+    insert_at = None
+    new_path = []
+
+    for item in sys.path:
+        p, np = makepath(item)
+
+        if np == nd and insert_at is None:
+            # We've hit the first 'system' path entry, so added entries go here
+            insert_at = len(new_path)
+
+        if np in known_paths or insert_at is None:
+            new_path.append(item)
+        else:
+            # new path after the insert point, back-insert it
+            new_path.insert(insert_at, item)
+            insert_at += 1
+
+    sys.path[:] = new_path
+
+
+if __name__ == 'site':
+    __boot()
+    del __boot
diff --git a/vendor/setuptools-39.0.1/setuptools/ssl_support.py b/vendor/setuptools-39.0.1/setuptools/ssl_support.py
new file mode 100644
index 00000000..6362f1f4
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/ssl_support.py
@@ -0,0 +1,260 @@
+import os
+import socket
+import atexit
+import re
+import functools
+
+from setuptools.extern.six.moves import urllib, http_client, map, filter
+
+from pkg_resources import ResolutionError, ExtractionError
+
+try:
+    import ssl
+except ImportError:
+    ssl = None
+
+__all__ = [
+    'VerifyingHTTPSHandler', 'find_ca_bundle', 'is_available', 'cert_paths',
+    'opener_for'
+]
+
+cert_paths = """
+/etc/pki/tls/certs/ca-bundle.crt
+/etc/ssl/certs/ca-certificates.crt
+/usr/share/ssl/certs/ca-bundle.crt
+/usr/local/share/certs/ca-root.crt
+/etc/ssl/cert.pem
+/System/Library/OpenSSL/certs/cert.pem
+/usr/local/share/certs/ca-root-nss.crt
+/etc/ssl/ca-bundle.pem
+""".strip().split()
+
+try:
+    HTTPSHandler = urllib.request.HTTPSHandler
+    HTTPSConnection = http_client.HTTPSConnection
+except AttributeError:
+    HTTPSHandler = HTTPSConnection = object
+
+is_available = ssl is not None and object not in (HTTPSHandler, HTTPSConnection)
+
+
+try:
+    from ssl import CertificateError, match_hostname
+except ImportError:
+    try:
+        from backports.ssl_match_hostname import CertificateError
+        from backports.ssl_match_hostname import match_hostname
+    except ImportError:
+        CertificateError = None
+        match_hostname = None
+
+if not CertificateError:
+
+    class CertificateError(ValueError):
+        pass
+
+
+if not match_hostname:
+
+    def _dnsname_match(dn, hostname, max_wildcards=1):
+        """Matching according to RFC 6125, section 6.4.3
+
+        http://tools.ietf.org/html/rfc6125#section-6.4.3
+        """
+        pats = []
+        if not dn:
+            return False
+
+        # Ported from python3-syntax:
+        # leftmost, *remainder = dn.split(r'.')
+        parts = dn.split(r'.')
+        leftmost = parts[0]
+        remainder = parts[1:]
+
+        wildcards = leftmost.count('*')
+        if wildcards > max_wildcards:
+            # Issue #17980: avoid denials of service by refusing more
+            # than one wildcard per fragment.  A survey of established
+            # policy among SSL implementations showed it to be a
+            # reasonable choice.
+            raise CertificateError(
+                "too many wildcards in certificate DNS name: " + repr(dn))
+
+        # speed up common case w/o wildcards
+        if not wildcards:
+            return dn.lower() == hostname.lower()
+
+        # RFC 6125, section 6.4.3, subitem 1.
+        # The client SHOULD NOT attempt to match a presented identifier in which
+        # the wildcard character comprises a label other than the left-most label.
+        if leftmost == '*':
+            # When '*' is a fragment by itself, it matches a non-empty dotless
+            # fragment.
+            pats.append('[^.]+')
+        elif leftmost.startswith('xn--') or hostname.startswith('xn--'):
+            # RFC 6125, section 6.4.3, subitem 3.
+            # The client SHOULD NOT attempt to match a presented identifier
+            # where the wildcard character is embedded within an A-label or
+            # U-label of an internationalized domain name.
+            pats.append(re.escape(leftmost))
+        else:
+            # Otherwise, '*' matches any dotless string, e.g. www*
+            pats.append(re.escape(leftmost).replace(r'\*', '[^.]*'))
+
+        # add the remaining fragments, ignore any wildcards
+        for frag in remainder:
+            pats.append(re.escape(frag))
+
+        pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
+        return pat.match(hostname)
+
+    def match_hostname(cert, hostname):
+        """Verify that *cert* (in decoded format as returned by
+        SSLSocket.getpeercert()) matches the *hostname*.  RFC 2818 and RFC 6125
+        rules are followed, but IP addresses are not accepted for *hostname*.
+
+        CertificateError is raised on failure. On success, the function
+        returns nothing.
+        """
+        if not cert:
+            raise ValueError("empty or no certificate")
+        dnsnames = []
+        san = cert.get('subjectAltName', ())
+        for key, value in san:
+            if key == 'DNS':
+                if _dnsname_match(value, hostname):
+                    return
+                dnsnames.append(value)
+        if not dnsnames:
+            # The subject is only checked when there is no dNSName entry
+            # in subjectAltName
+            for sub in cert.get('subject', ()):
+                for key, value in sub:
+                    # XXX according to RFC 2818, the most specific Common Name
+                    # must be used.
+                    if key == 'commonName':
+                        if _dnsname_match(value, hostname):
+                            return
+                        dnsnames.append(value)
+        if len(dnsnames) > 1:
+            raise CertificateError("hostname %r "
+                "doesn't match either of %s"
+                % (hostname, ', '.join(map(repr, dnsnames))))
+        elif len(dnsnames) == 1:
+            raise CertificateError("hostname %r "
+                "doesn't match %r"
+                % (hostname, dnsnames[0]))
+        else:
+            raise CertificateError("no appropriate commonName or "
+                "subjectAltName fields were found")
+
+
+class VerifyingHTTPSHandler(HTTPSHandler):
+    """Simple verifying handler: no auth, subclasses, timeouts, etc."""
+
+    def __init__(self, ca_bundle):
+        self.ca_bundle = ca_bundle
+        HTTPSHandler.__init__(self)
+
+    def https_open(self, req):
+        return self.do_open(
+            lambda host, **kw: VerifyingHTTPSConn(host, self.ca_bundle, **kw), req
+        )
+
+
+class VerifyingHTTPSConn(HTTPSConnection):
+    """Simple verifying connection: no auth, subclasses, timeouts, etc."""
+
+    def __init__(self, host, ca_bundle, **kw):
+        HTTPSConnection.__init__(self, host, **kw)
+        self.ca_bundle = ca_bundle
+
+    def connect(self):
+        sock = socket.create_connection(
+            (self.host, self.port), getattr(self, 'source_address', None)
+        )
+
+        # Handle the socket if a (proxy) tunnel is present
+        if hasattr(self, '_tunnel') and getattr(self, '_tunnel_host', None):
+            self.sock = sock
+            self._tunnel()
+            # http://bugs.python.org/issue7776: Python>=3.4.1 and >=2.7.7
+            # change self.host to mean the proxy server host when tunneling is
+            # being used. Adapt, since we are interested in the destination
+            # host for the match_hostname() comparison.
+            actual_host = self._tunnel_host
+        else:
+            actual_host = self.host
+
+        if hasattr(ssl, 'create_default_context'):
+            ctx = ssl.create_default_context(cafile=self.ca_bundle)
+            self.sock = ctx.wrap_socket(sock, server_hostname=actual_host)
+        else:
+            # This is for python < 2.7.9 and < 3.4?
+            self.sock = ssl.wrap_socket(
+                sock, cert_reqs=ssl.CERT_REQUIRED, ca_certs=self.ca_bundle
+            )
+        try:
+            match_hostname(self.sock.getpeercert(), actual_host)
+        except CertificateError:
+            self.sock.shutdown(socket.SHUT_RDWR)
+            self.sock.close()
+            raise
+
+
+def opener_for(ca_bundle=None):
+    """Get a urlopen() replacement that uses ca_bundle for verification"""
+    return urllib.request.build_opener(
+        VerifyingHTTPSHandler(ca_bundle or find_ca_bundle())
+    ).open
+
+
+# from jaraco.functools
+def once(func):
+    @functools.wraps(func)
+    def wrapper(*args, **kwargs):
+        if not hasattr(func, 'always_returns'):
+            func.always_returns = func(*args, **kwargs)
+        return func.always_returns
+    return wrapper
+
+
+@once
+def get_win_certfile():
+    try:
+        import wincertstore
+    except ImportError:
+        return None
+
+    class CertFile(wincertstore.CertFile):
+        def __init__(self):
+            super(CertFile, self).__init__()
+            atexit.register(self.close)
+
+        def close(self):
+            try:
+                super(CertFile, self).close()
+            except OSError:
+                pass
+
+    _wincerts = CertFile()
+    _wincerts.addstore('CA')
+    _wincerts.addstore('ROOT')
+    return _wincerts.name
+
+
+def find_ca_bundle():
+    """Return an existing CA bundle path, or None"""
+    extant_cert_paths = filter(os.path.isfile, cert_paths)
+    return (
+        get_win_certfile()
+        or next(extant_cert_paths, None)
+        or _certifi_where()
+    )
+
+
+def _certifi_where():
+    try:
+        return __import__('certifi').where()
+    except (ImportError, ResolutionError, ExtractionError):
+        pass
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/__init__.py b/vendor/setuptools-39.0.1/setuptools/tests/__init__.py
new file mode 100644
index 00000000..54dd7d2b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/__init__.py
@@ -0,0 +1,6 @@
+import locale
+
+import pytest
+
+is_ascii = locale.getpreferredencoding() == 'ANSI_X3.4-1968'
+fail_on_ascii = pytest.mark.xfail(is_ascii, reason="Test fails in this locale")
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/contexts.py b/vendor/setuptools-39.0.1/setuptools/tests/contexts.py
new file mode 100644
index 00000000..535ae107
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/contexts.py
@@ -0,0 +1,98 @@
+import tempfile
+import os
+import shutil
+import sys
+import contextlib
+import site
+
+from setuptools.extern import six
+import pkg_resources
+
+
+@contextlib.contextmanager
+def tempdir(cd=lambda dir: None, **kwargs):
+    temp_dir = tempfile.mkdtemp(**kwargs)
+    orig_dir = os.getcwd()
+    try:
+        cd(temp_dir)
+        yield temp_dir
+    finally:
+        cd(orig_dir)
+        shutil.rmtree(temp_dir)
+
+
+@contextlib.contextmanager
+def environment(**replacements):
+    """
+    In a context, patch the environment with replacements. Pass None values
+    to clear the values.
+    """
+    saved = dict(
+        (key, os.environ[key])
+        for key in replacements
+        if key in os.environ
+    )
+
+    # remove values that are null
+    remove = (key for (key, value) in replacements.items() if value is None)
+    for key in list(remove):
+        os.environ.pop(key, None)
+        replacements.pop(key)
+
+    os.environ.update(replacements)
+
+    try:
+        yield saved
+    finally:
+        for key in replacements:
+            os.environ.pop(key, None)
+        os.environ.update(saved)
+
+
+@contextlib.contextmanager
+def quiet():
+    """
+    Redirect stdout/stderr to StringIO objects to prevent console output from
+    distutils commands.
+    """
+
+    old_stdout = sys.stdout
+    old_stderr = sys.stderr
+    new_stdout = sys.stdout = six.StringIO()
+    new_stderr = sys.stderr = six.StringIO()
+    try:
+        yield new_stdout, new_stderr
+    finally:
+        new_stdout.seek(0)
+        new_stderr.seek(0)
+        sys.stdout = old_stdout
+        sys.stderr = old_stderr
+
+
+@contextlib.contextmanager
+def save_user_site_setting():
+    saved = site.ENABLE_USER_SITE
+    try:
+        yield saved
+    finally:
+        site.ENABLE_USER_SITE = saved
+
+
+@contextlib.contextmanager
+def save_pkg_resources_state():
+    pr_state = pkg_resources.__getstate__()
+    # also save sys.path
+    sys_path = sys.path[:]
+    try:
+        yield pr_state, sys_path
+    finally:
+        sys.path[:] = sys_path
+        pkg_resources.__setstate__(pr_state)
+
+
+@contextlib.contextmanager
+def suppress_exceptions(*excs):
+    try:
+        yield
+    except excs:
+        pass
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/environment.py b/vendor/setuptools-39.0.1/setuptools/tests/environment.py
new file mode 100644
index 00000000..c67898ca
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/environment.py
@@ -0,0 +1,60 @@
+import os
+import sys
+import unicodedata
+
+from subprocess import Popen as _Popen, PIPE as _PIPE
+
+
+def _which_dirs(cmd):
+    result = set()
+    for path in os.environ.get('PATH', '').split(os.pathsep):
+        filename = os.path.join(path, cmd)
+        if os.access(filename, os.X_OK):
+            result.add(path)
+    return result
+
+
+def run_setup_py(cmd, pypath=None, path=None,
+                 data_stream=0, env=None):
+    """
+    Execution command for tests, separate from those used by the
+    code directly to prevent accidental behavior issues
+    """
+    if env is None:
+        env = dict()
+        for envname in os.environ:
+            env[envname] = os.environ[envname]
+
+    # override the python path if needed
+    if pypath is not None:
+        env["PYTHONPATH"] = pypath
+
+    # overide the execution path if needed
+    if path is not None:
+        env["PATH"] = path
+    if not env.get("PATH", ""):
+        env["PATH"] = _which_dirs("tar").union(_which_dirs("gzip"))
+        env["PATH"] = os.pathsep.join(env["PATH"])
+
+    cmd = [sys.executable, "setup.py"] + list(cmd)
+
+    # http://bugs.python.org/issue8557
+    shell = sys.platform == 'win32'
+
+    try:
+        proc = _Popen(
+            cmd, stdout=_PIPE, stderr=_PIPE, shell=shell, env=env,
+        )
+
+        data = proc.communicate()[data_stream]
+    except OSError:
+        return 1, ''
+
+    # decode the console string if needed
+    if hasattr(data, "decode"):
+        # use the default encoding
+        data = data.decode()
+        data = unicodedata.normalize('NFC', data)
+
+    # communicate calls wait()
+    return proc.returncode, data
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/files.py b/vendor/setuptools-39.0.1/setuptools/tests/files.py
new file mode 100644
index 00000000..f5f0e6bb
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/files.py
@@ -0,0 +1,39 @@
+import os
+
+
+from setuptools.extern.six import binary_type
+import pkg_resources.py31compat
+
+
+def build_files(file_defs, prefix=""):
+    """
+    Build a set of files/directories, as described by the file_defs dictionary.
+
+    Each key/value pair in the dictionary is interpreted as a filename/contents
+    pair. If the contents value is a dictionary, a directory is created, and the
+    dictionary interpreted as the files within it, recursively.
+
+    For example:
+
+    {"README.txt": "A README file",
+     "foo": {
+        "__init__.py": "",
+        "bar": {
+            "__init__.py": "",
+        },
+        "baz.py": "# Some code",
+     }
+    }
+    """
+    for name, contents in file_defs.items():
+        full_name = os.path.join(prefix, name)
+        if isinstance(contents, dict):
+            pkg_resources.py31compat.makedirs(full_name, exist_ok=True)
+            build_files(contents, prefix=full_name)
+        else:
+            if isinstance(contents, binary_type):
+                with open(full_name, 'wb') as f:
+                    f.write(contents)
+            else:
+                with open(full_name, 'w') as f:
+                    f.write(contents)
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/fixtures.py b/vendor/setuptools-39.0.1/setuptools/tests/fixtures.py
new file mode 100644
index 00000000..5204c8d1
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/fixtures.py
@@ -0,0 +1,23 @@
+import pytest
+
+from . import contexts
+
+
+@pytest.yield_fixture
+def user_override(monkeypatch):
+    """
+    Override site.USER_BASE and site.USER_SITE with temporary directories in
+    a context.
+    """
+    with contexts.tempdir() as user_base:
+        monkeypatch.setattr('site.USER_BASE', user_base)
+        with contexts.tempdir() as user_site:
+            monkeypatch.setattr('site.USER_SITE', user_site)
+            with contexts.save_user_site_setting():
+                yield
+
+
+@pytest.yield_fixture
+def tmpdir_cwd(tmpdir):
+    with tmpdir.as_cwd() as orig:
+        yield orig
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/indexes/test_links_priority/external.html b/vendor/setuptools-39.0.1/setuptools/tests/indexes/test_links_priority/external.html
new file mode 100644
index 00000000..92e4702f
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/indexes/test_links_priority/external.html
@@ -0,0 +1,3 @@
+<html><body>
+<a href="/foobar-0.1.tar.gz#md5=1__bad_md5___">bad old link</a>
+</body></html>
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/indexes/test_links_priority/simple/foobar/index.html b/vendor/setuptools-39.0.1/setuptools/tests/indexes/test_links_priority/simple/foobar/index.html
new file mode 100644
index 00000000..fefb028b
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/indexes/test_links_priority/simple/foobar/index.html
@@ -0,0 +1,4 @@
+<html><body>
+<a href="/foobar-0.1.tar.gz#md5=0_correct_md5">foobar-0.1.tar.gz</a><br/>
+<a href="../../external.html" rel="homepage">external homepage</a><br/>
+</body></html>
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/mod_with_constant.py b/vendor/setuptools-39.0.1/setuptools/tests/mod_with_constant.py
new file mode 100644
index 00000000..ef755dd1
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/mod_with_constant.py
@@ -0,0 +1 @@
+value = 'three, sir!'
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/namespaces.py b/vendor/setuptools-39.0.1/setuptools/tests/namespaces.py
new file mode 100644
index 00000000..ef5ecdad
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/namespaces.py
@@ -0,0 +1,42 @@
+from __future__ import absolute_import, unicode_literals
+
+import textwrap
+
+
+def build_namespace_package(tmpdir, name):
+    src_dir = tmpdir / name
+    src_dir.mkdir()
+    setup_py = src_dir / 'setup.py'
+    namespace, sep, rest = name.partition('.')
+    script = textwrap.dedent("""
+        import setuptools
+        setuptools.setup(
+            name={name!r},
+            version="1.0",
+            namespace_packages=[{namespace!r}],
+            packages=[{namespace!r}],
+        )
+        """).format(**locals())
+    setup_py.write_text(script, encoding='utf-8')
+    ns_pkg_dir = src_dir / namespace
+    ns_pkg_dir.mkdir()
+    pkg_init = ns_pkg_dir / '__init__.py'
+    tmpl = '__import__("pkg_resources").declare_namespace({namespace!r})'
+    decl = tmpl.format(**locals())
+    pkg_init.write_text(decl, encoding='utf-8')
+    pkg_mod = ns_pkg_dir / (rest + '.py')
+    some_functionality = 'name = {rest!r}'.format(**locals())
+    pkg_mod.write_text(some_functionality, encoding='utf-8')
+    return src_dir
+
+
+def make_site_dir(target):
+    """
+    Add a sitecustomize.py module in target to cause
+    target to be added to site dirs such that .pth files
+    are processed there.
+    """
+    sc = target / 'sitecustomize.py'
+    target_str = str(target)
+    tmpl = '__import__("site").addsitedir({target_str!r})'
+    sc.write_text(tmpl.format(**locals()), encoding='utf-8')
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/script-with-bom.py b/vendor/setuptools-39.0.1/setuptools/tests/script-with-bom.py
new file mode 100644
index 00000000..22dee0d2
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/script-with-bom.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+result = 'passed'
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/server.py b/vendor/setuptools-39.0.1/setuptools/tests/server.py
new file mode 100644
index 00000000..35312120
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/server.py
@@ -0,0 +1,72 @@
+"""Basic http server for tests to simulate PyPI or custom indexes
+"""
+
+import time
+import threading
+
+from setuptools.extern.six.moves import BaseHTTPServer, SimpleHTTPServer
+
+
+class IndexServer(BaseHTTPServer.HTTPServer):
+    """Basic single-threaded http server simulating a package index
+
+    You can use this server in unittest like this::
+        s = IndexServer()
+        s.start()
+        index_url = s.base_url() + 'mytestindex'
+        # do some test requests to the index
+        # The index files should be located in setuptools/tests/indexes
+        s.stop()
+    """
+
+    def __init__(self, server_address=('', 0),
+            RequestHandlerClass=SimpleHTTPServer.SimpleHTTPRequestHandler):
+        BaseHTTPServer.HTTPServer.__init__(self, server_address,
+            RequestHandlerClass)
+        self._run = True
+
+    def start(self):
+        self.thread = threading.Thread(target=self.serve_forever)
+        self.thread.start()
+
+    def stop(self):
+        "Stop the server"
+
+        # Let the server finish the last request and wait for a new one.
+        time.sleep(0.1)
+
+        self.shutdown()
+        self.thread.join()
+        self.socket.close()
+
+    def base_url(self):
+        port = self.server_port
+        return 'http://127.0.0.1:%s/setuptools/tests/indexes/' % port
+
+
+class RequestRecorder(BaseHTTPServer.BaseHTTPRequestHandler):
+    def do_GET(self):
+        requests = vars(self.server).setdefault('requests', [])
+        requests.append(self)
+        self.send_response(200, 'OK')
+
+
+class MockServer(BaseHTTPServer.HTTPServer, threading.Thread):
+    """
+    A simple HTTP Server that records the requests made to it.
+    """
+
+    def __init__(self, server_address=('', 0),
+            RequestHandlerClass=RequestRecorder):
+        BaseHTTPServer.HTTPServer.__init__(self, server_address,
+            RequestHandlerClass)
+        threading.Thread.__init__(self)
+        self.setDaemon(True)
+        self.requests = []
+
+    def run(self):
+        self.serve_forever()
+
+    @property
+    def url(self):
+        return 'http://localhost:%(server_port)s/' % vars(self)
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_archive_util.py b/vendor/setuptools-39.0.1/setuptools/tests/test_archive_util.py
new file mode 100644
index 00000000..b789e9ac
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_archive_util.py
@@ -0,0 +1,42 @@
+# coding: utf-8
+
+import tarfile
+import io
+
+from setuptools.extern import six
+
+import pytest
+
+from setuptools import archive_util
+
+
+@pytest.fixture
+def tarfile_with_unicode(tmpdir):
+    """
+    Create a tarfile containing only a file whose name is
+    a zero byte file called testimäge.png.
+    """
+    tarobj = io.BytesIO()
+
+    with tarfile.open(fileobj=tarobj, mode="w:gz") as tgz:
+        data = b""
+
+        filename = "testimäge.png"
+        if six.PY2:
+            filename = filename.decode('utf-8')
+
+        t = tarfile.TarInfo(filename)
+        t.size = len(data)
+
+        tgz.addfile(t, io.BytesIO(data))
+
+    target = tmpdir / 'unicode-pkg-1.0.tar.gz'
+    with open(str(target), mode='wb') as tf:
+        tf.write(tarobj.getvalue())
+    return str(target)
+
+
+@pytest.mark.xfail(reason="#710 and #712")
+def test_unicode_files(tarfile_with_unicode, tmpdir):
+    target = tmpdir / 'out'
+    archive_util.unpack_archive(tarfile_with_unicode, six.text_type(target))
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_bdist_egg.py b/vendor/setuptools-39.0.1/setuptools/tests/test_bdist_egg.py
new file mode 100644
index 00000000..54742aa6
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_bdist_egg.py
@@ -0,0 +1,66 @@
+"""develop tests
+"""
+import os
+import re
+import zipfile
+
+import pytest
+
+from setuptools.dist import Distribution
+
+from . import contexts
+
+SETUP_PY = """\
+from setuptools import setup
+
+setup(name='foo', py_modules=['hi'])
+"""
+
+
+@pytest.fixture(scope='function')
+def setup_context(tmpdir):
+    with (tmpdir / 'setup.py').open('w') as f:
+        f.write(SETUP_PY)
+    with (tmpdir / 'hi.py').open('w') as f:
+        f.write('1\n')
+    with tmpdir.as_cwd():
+        yield tmpdir
+
+
+class Test:
+    def test_bdist_egg(self, setup_context, user_override):
+        dist = Distribution(dict(
+            script_name='setup.py',
+            script_args=['bdist_egg'],
+            name='foo',
+            py_modules=['hi'],
+        ))
+        os.makedirs(os.path.join('build', 'src'))
+        with contexts.quiet():
+            dist.parse_command_line()
+            dist.run_commands()
+
+        # let's see if we got our egg link at the right place
+        [content] = os.listdir('dist')
+        assert re.match(r'foo-0.0.0-py[23].\d.egg$', content)
+
+    @pytest.mark.xfail(
+        os.environ.get('PYTHONDONTWRITEBYTECODE'),
+        reason="Byte code disabled",
+    )
+    def test_exclude_source_files(self, setup_context, user_override):
+        dist = Distribution(dict(
+            script_name='setup.py',
+            script_args=['bdist_egg', '--exclude-source-files'],
+            name='foo',
+            py_modules=['hi'],
+        ))
+        with contexts.quiet():
+            dist.parse_command_line()
+            dist.run_commands()
+        [dist_name] = os.listdir('dist')
+        dist_filename = os.path.join('dist', dist_name)
+        zip = zipfile.ZipFile(dist_filename)
+        names = list(zi.filename for zi in zip.filelist)
+        assert 'hi.pyc' in names
+        assert 'hi.py' not in names
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_build_clib.py b/vendor/setuptools-39.0.1/setuptools/tests/test_build_clib.py
new file mode 100644
index 00000000..aebcc350
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_build_clib.py
@@ -0,0 +1,59 @@
+import pytest
+import os
+import shutil
+
+import mock
+from distutils.errors import DistutilsSetupError
+from setuptools.command.build_clib import build_clib
+from setuptools.dist import Distribution
+
+
+class TestBuildCLib:
+    @mock.patch(
+            'setuptools.command.build_clib.newer_pairwise_group'
+            )
+    def test_build_libraries(self, mock_newer):
+        dist = Distribution()
+        cmd = build_clib(dist)
+
+        # this will be a long section, just making sure all
+        # exceptions are properly raised
+        libs = [('example', {'sources': 'broken.c'})]
+        with pytest.raises(DistutilsSetupError):
+            cmd.build_libraries(libs)
+
+        obj_deps = 'some_string'
+        libs = [('example', {'sources': ['source.c'], 'obj_deps': obj_deps})]
+        with pytest.raises(DistutilsSetupError):
+            cmd.build_libraries(libs)
+
+        obj_deps = {'': ''}
+        libs = [('example', {'sources': ['source.c'], 'obj_deps': obj_deps})]
+        with pytest.raises(DistutilsSetupError):
+            cmd.build_libraries(libs)
+
+        obj_deps = {'source.c': ''}
+        libs = [('example', {'sources': ['source.c'], 'obj_deps': obj_deps})]
+        with pytest.raises(DistutilsSetupError):
+            cmd.build_libraries(libs)
+
+        # with that out of the way, let's see if the crude dependency
+        # system works
+        cmd.compiler = mock.MagicMock(spec=cmd.compiler)
+        mock_newer.return_value = ([],[])
+
+        obj_deps = {'': ('global.h',), 'example.c': ('example.h',)}
+        libs = [('example', {'sources': ['example.c'] ,'obj_deps': obj_deps})]
+
+        cmd.build_libraries(libs)
+        assert [['example.c', 'global.h', 'example.h']] in mock_newer.call_args[0]
+        assert not cmd.compiler.compile.called
+        assert cmd.compiler.create_static_lib.call_count == 1
+
+        # reset the call numbers so we can test again
+        cmd.compiler.reset_mock()
+
+        mock_newer.return_value = ''  # anything as long as it's not ([],[])
+        cmd.build_libraries(libs)
+        assert cmd.compiler.compile.call_count == 1
+        assert cmd.compiler.create_static_lib.call_count == 1
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_build_ext.py b/vendor/setuptools-39.0.1/setuptools/tests/test_build_ext.py
new file mode 100644
index 00000000..60257154
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_build_ext.py
@@ -0,0 +1,45 @@
+import sys
+import distutils.command.build_ext as orig
+from distutils.sysconfig import get_config_var
+
+from setuptools.extern import six
+
+from setuptools.command.build_ext import build_ext, get_abi3_suffix
+from setuptools.dist import Distribution
+from setuptools.extension import Extension
+
+
+class TestBuildExt:
+    def test_get_ext_filename(self):
+        """
+        Setuptools needs to give back the same
+        result as distutils, even if the fullname
+        is not in ext_map.
+        """
+        dist = Distribution()
+        cmd = build_ext(dist)
+        cmd.ext_map['foo/bar'] = ''
+        res = cmd.get_ext_filename('foo')
+        wanted = orig.build_ext.get_ext_filename(cmd, 'foo')
+        assert res == wanted
+
+    def test_abi3_filename(self):
+        """
+        Filename needs to be loadable by several versions
+        of Python 3 if 'is_abi3' is truthy on Extension()
+        """
+        print(get_abi3_suffix())
+
+        extension = Extension('spam.eggs', ['eggs.c'], py_limited_api=True)
+        dist = Distribution(dict(ext_modules=[extension]))
+        cmd = build_ext(dist)
+        cmd.finalize_options()
+        assert 'spam.eggs' in cmd.ext_map
+        res = cmd.get_ext_filename('spam.eggs')
+
+        if six.PY2 or not get_abi3_suffix():
+            assert res.endswith(get_config_var('SO'))
+        elif sys.platform == 'win32':
+            assert res.endswith('eggs.pyd')
+        else:
+            assert 'abi3' in res
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_build_meta.py b/vendor/setuptools-39.0.1/setuptools/tests/test_build_meta.py
new file mode 100644
index 00000000..659c1a65
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_build_meta.py
@@ -0,0 +1,126 @@
+import os
+
+import pytest
+
+from .files import build_files
+from .textwrap import DALS
+
+
+futures = pytest.importorskip('concurrent.futures')
+importlib = pytest.importorskip('importlib')
+
+
+class BuildBackendBase(object):
+    def __init__(self, cwd=None, env={}, backend_name='setuptools.build_meta'):
+        self.cwd = cwd
+        self.env = env
+        self.backend_name = backend_name
+
+
+class BuildBackend(BuildBackendBase):
+    """PEP 517 Build Backend"""
+    def __init__(self, *args, **kwargs):
+        super(BuildBackend, self).__init__(*args, **kwargs)
+        self.pool = futures.ProcessPoolExecutor()
+
+    def __getattr__(self, name):
+        """Handles aribrary function invocations on the build backend."""
+        def method(*args, **kw):
+            root = os.path.abspath(self.cwd)
+            caller = BuildBackendCaller(root, self.env, self.backend_name)
+            return self.pool.submit(caller, name, *args, **kw).result()
+
+        return method
+
+
+class BuildBackendCaller(BuildBackendBase):
+    def __call__(self, name, *args, **kw):
+        """Handles aribrary function invocations on the build backend."""
+        os.chdir(self.cwd)
+        os.environ.update(self.env)
+        mod = importlib.import_module(self.backend_name)
+        return getattr(mod, name)(*args, **kw)
+
+
+defns = [{
+            'setup.py': DALS("""
+                __import__('setuptools').setup(
+                    name='foo',
+                    py_modules=['hello'],
+                    setup_requires=['six'],
+                )
+                """),
+            'hello.py': DALS("""
+                def run():
+                    print('hello')
+                """),
+        },
+        {
+            'setup.py': DALS("""
+                assert __name__ == '__main__'
+                __import__('setuptools').setup(
+                    name='foo',
+                    py_modules=['hello'],
+                    setup_requires=['six'],
+                )
+                """),
+            'hello.py': DALS("""
+                def run():
+                    print('hello')
+                """),
+        },
+        {
+            'setup.py': DALS("""
+                variable = True
+                def function():
+                    return variable
+                assert variable
+                __import__('setuptools').setup(
+                    name='foo',
+                    py_modules=['hello'],
+                    setup_requires=['six'],
+                )
+                """),
+            'hello.py': DALS("""
+                def run():
+                    print('hello')
+                """),
+        }]
+
+
+@pytest.fixture(params=defns)
+def build_backend(tmpdir, request):
+    build_files(request.param, prefix=str(tmpdir))
+    with tmpdir.as_cwd():
+        yield BuildBackend(cwd='.')
+
+
+def test_get_requires_for_build_wheel(build_backend):
+    actual = build_backend.get_requires_for_build_wheel()
+    expected = ['six', 'setuptools', 'wheel']
+    assert sorted(actual) == sorted(expected)
+
+
+def test_build_wheel(build_backend):
+    dist_dir = os.path.abspath('pip-wheel')
+    os.makedirs(dist_dir)
+    wheel_name = build_backend.build_wheel(dist_dir)
+
+    assert os.path.isfile(os.path.join(dist_dir, wheel_name))
+
+
+def test_build_sdist(build_backend):
+    dist_dir = os.path.abspath('pip-sdist')
+    os.makedirs(dist_dir)
+    sdist_name = build_backend.build_sdist(dist_dir)
+
+    assert os.path.isfile(os.path.join(dist_dir, sdist_name))
+
+
+def test_prepare_metadata_for_build_wheel(build_backend):
+    dist_dir = os.path.abspath('pip-dist-info')
+    os.makedirs(dist_dir)
+
+    dist_info = build_backend.prepare_metadata_for_build_wheel(dist_dir)
+
+    assert os.path.isfile(os.path.join(dist_dir, dist_info, 'METADATA'))
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_build_py.py b/vendor/setuptools-39.0.1/setuptools/tests/test_build_py.py
new file mode 100644
index 00000000..cc701ae6
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_build_py.py
@@ -0,0 +1,30 @@
+import os
+
+import pytest
+
+from setuptools.dist import Distribution
+
+
+@pytest.yield_fixture
+def tmpdir_as_cwd(tmpdir):
+    with tmpdir.as_cwd():
+        yield tmpdir
+
+
+def test_directories_in_package_data_glob(tmpdir_as_cwd):
+    """
+    Directories matching the glob in package_data should
+    not be included in the package data.
+
+    Regression test for #261.
+    """
+    dist = Distribution(dict(
+        script_name='setup.py',
+        script_args=['build_py'],
+        packages=[''],
+        name='foo',
+        package_data={'': ['path/*']},
+    ))
+    os.makedirs('path/subpath')
+    dist.parse_command_line()
+    dist.run_commands()
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_config.py b/vendor/setuptools-39.0.1/setuptools/tests/test_config.py
new file mode 100644
index 00000000..abb953a8
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_config.py
@@ -0,0 +1,583 @@
+import contextlib
+import pytest
+from distutils.errors import DistutilsOptionError, DistutilsFileError
+from setuptools.dist import Distribution
+from setuptools.config import ConfigHandler, read_configuration
+
+
+class ErrConfigHandler(ConfigHandler):
+    """Erroneous handler. Fails to implement required methods."""
+
+
+def make_package_dir(name, base_dir):
+    dir_package = base_dir.mkdir(name)
+    init_file = dir_package.join('__init__.py')
+    init_file.write('')
+    return dir_package, init_file
+
+
+def fake_env(tmpdir, setup_cfg, setup_py=None):
+
+    if setup_py is None:
+        setup_py = (
+            'from setuptools import setup\n'
+            'setup()\n'
+        )
+
+    tmpdir.join('setup.py').write(setup_py)
+    config = tmpdir.join('setup.cfg')
+    config.write(setup_cfg)
+
+    package_dir, init_file = make_package_dir('fake_package', tmpdir)
+
+    init_file.write(
+        'VERSION = (1, 2, 3)\n'
+        '\n'
+        'VERSION_MAJOR = 1'
+        '\n'
+        'def get_version():\n'
+        '    return [3, 4, 5, "dev"]\n'
+        '\n'
+    )
+    return package_dir, config
+
+
+@contextlib.contextmanager
+def get_dist(tmpdir, kwargs_initial=None, parse=True):
+    kwargs_initial = kwargs_initial or {}
+
+    with tmpdir.as_cwd():
+        dist = Distribution(kwargs_initial)
+        dist.script_name = 'setup.py'
+        parse and dist.parse_config_files()
+
+        yield dist
+
+
+def test_parsers_implemented():
+
+    with pytest.raises(NotImplementedError):
+        handler = ErrConfigHandler(None, {})
+        handler.parsers
+
+
+class TestConfigurationReader:
+
+    def test_basic(self, tmpdir):
+        _, config = fake_env(
+            tmpdir,
+            '[metadata]\n'
+            'version = 10.1.1\n'
+            'keywords = one, two\n'
+            '\n'
+            '[options]\n'
+            'scripts = bin/a.py, bin/b.py\n'
+        )
+        config_dict = read_configuration('%s' % config)
+        assert config_dict['metadata']['version'] == '10.1.1'
+        assert config_dict['metadata']['keywords'] == ['one', 'two']
+        assert config_dict['options']['scripts'] == ['bin/a.py', 'bin/b.py']
+
+    def test_no_config(self, tmpdir):
+        with pytest.raises(DistutilsFileError):
+            read_configuration('%s' % tmpdir.join('setup.cfg'))
+
+    def test_ignore_errors(self, tmpdir):
+        _, config = fake_env(
+            tmpdir,
+            '[metadata]\n'
+            'version = attr: none.VERSION\n'
+            'keywords = one, two\n'
+        )
+        with pytest.raises(ImportError):
+            read_configuration('%s' % config)
+
+        config_dict = read_configuration(
+            '%s' % config, ignore_option_errors=True)
+
+        assert config_dict['metadata']['keywords'] == ['one', 'two']
+        assert 'version' not in config_dict['metadata']
+
+        config.remove()
+
+
+class TestMetadata:
+
+    def test_basic(self, tmpdir):
+
+        fake_env(
+            tmpdir,
+            '[metadata]\n'
+            'version = 10.1.1\n'
+            'description = Some description\n'
+            'long_description_content_type = text/something\n'
+            'long_description = file: README\n'
+            'name = fake_name\n'
+            'keywords = one, two\n'
+            'provides = package, package.sub\n'
+            'license = otherlic\n'
+            'download_url = http://test.test.com/test/\n'
+            'maintainer_email = test@test.com\n'
+        )
+
+        tmpdir.join('README').write('readme contents\nline2')
+
+        meta_initial = {
+            # This will be used so `otherlic` won't replace it.
+            'license': 'BSD 3-Clause License',
+        }
+
+        with get_dist(tmpdir, meta_initial) as dist:
+            metadata = dist.metadata
+
+            assert metadata.version == '10.1.1'
+            assert metadata.description == 'Some description'
+            assert metadata.long_description_content_type == 'text/something'
+            assert metadata.long_description == 'readme contents\nline2'
+            assert metadata.provides == ['package', 'package.sub']
+            assert metadata.license == 'BSD 3-Clause License'
+            assert metadata.name == 'fake_name'
+            assert metadata.keywords == ['one', 'two']
+            assert metadata.download_url == 'http://test.test.com/test/'
+            assert metadata.maintainer_email == 'test@test.com'
+
+    def test_file_mixed(self, tmpdir):
+
+        fake_env(
+            tmpdir,
+            '[metadata]\n'
+            'long_description = file: README.rst, CHANGES.rst\n'
+            '\n'
+        )
+
+        tmpdir.join('README.rst').write('readme contents\nline2')
+        tmpdir.join('CHANGES.rst').write('changelog contents\nand stuff')
+
+        with get_dist(tmpdir) as dist:
+            assert dist.metadata.long_description == (
+                'readme contents\nline2\n'
+                'changelog contents\nand stuff'
+            )
+
+    def test_file_sandboxed(self, tmpdir):
+
+        fake_env(
+            tmpdir,
+            '[metadata]\n'
+            'long_description = file: ../../README\n'
+        )
+
+        with get_dist(tmpdir, parse=False) as dist:
+            with pytest.raises(DistutilsOptionError):
+                dist.parse_config_files()  # file: out of sandbox
+
+    def test_aliases(self, tmpdir):
+
+        fake_env(
+            tmpdir,
+            '[metadata]\n'
+            'author-email = test@test.com\n'
+            'home-page = http://test.test.com/test/\n'
+            'summary = Short summary\n'
+            'platform = a, b\n'
+            'classifier =\n'
+            '  Framework :: Django\n'
+            '  Programming Language :: Python :: 3.5\n'
+        )
+
+        with get_dist(tmpdir) as dist:
+            metadata = dist.metadata
+            assert metadata.author_email == 'test@test.com'
+            assert metadata.url == 'http://test.test.com/test/'
+            assert metadata.description == 'Short summary'
+            assert metadata.platforms == ['a', 'b']
+            assert metadata.classifiers == [
+                'Framework :: Django',
+                'Programming Language :: Python :: 3.5',
+            ]
+
+    def test_multiline(self, tmpdir):
+
+        fake_env(
+            tmpdir,
+            '[metadata]\n'
+            'name = fake_name\n'
+            'keywords =\n'
+            '  one\n'
+            '  two\n'
+            'classifiers =\n'
+            '  Framework :: Django\n'
+            '  Programming Language :: Python :: 3.5\n'
+        )
+        with get_dist(tmpdir) as dist:
+            metadata = dist.metadata
+            assert metadata.keywords == ['one', 'two']
+            assert metadata.classifiers == [
+                'Framework :: Django',
+                'Programming Language :: Python :: 3.5',
+            ]
+
+    def test_dict(self, tmpdir):
+
+        fake_env(
+            tmpdir,
+            '[metadata]\n'
+            'project_urls =\n'
+            '  Link One = https://example.com/one/\n'
+            '  Link Two = https://example.com/two/\n'
+        )
+        with get_dist(tmpdir) as dist:
+            metadata = dist.metadata
+            assert metadata.project_urls == {
+                'Link One': 'https://example.com/one/',
+                'Link Two': 'https://example.com/two/',
+            }
+
+    def test_version(self, tmpdir):
+
+        _, config = fake_env(
+            tmpdir,
+            '[metadata]\n'
+            'version = attr: fake_package.VERSION\n'
+        )
+        with get_dist(tmpdir) as dist:
+            assert dist.metadata.version == '1.2.3'
+
+        config.write(
+            '[metadata]\n'
+            'version = attr: fake_package.get_version\n'
+        )
+        with get_dist(tmpdir) as dist:
+            assert dist.metadata.version == '3.4.5.dev'
+
+        config.write(
+            '[metadata]\n'
+            'version = attr: fake_package.VERSION_MAJOR\n'
+        )
+        with get_dist(tmpdir) as dist:
+            assert dist.metadata.version == '1'
+
+        subpack = tmpdir.join('fake_package').mkdir('subpackage')
+        subpack.join('__init__.py').write('')
+        subpack.join('submodule.py').write('VERSION = (2016, 11, 26)')
+
+        config.write(
+            '[metadata]\n'
+            'version = attr: fake_package.subpackage.submodule.VERSION\n'
+        )
+        with get_dist(tmpdir) as dist:
+            assert dist.metadata.version == '2016.11.26'
+
+    def test_unknown_meta_item(self, tmpdir):
+
+        fake_env(
+            tmpdir,
+            '[metadata]\n'
+            'name = fake_name\n'
+            'unknown = some\n'
+        )
+        with get_dist(tmpdir, parse=False) as dist:
+            dist.parse_config_files()  # Skip unknown.
+
+    def test_usupported_section(self, tmpdir):
+
+        fake_env(
+            tmpdir,
+            '[metadata.some]\n'
+            'key = val\n'
+        )
+        with get_dist(tmpdir, parse=False) as dist:
+            with pytest.raises(DistutilsOptionError):
+                dist.parse_config_files()
+
+    def test_classifiers(self, tmpdir):
+        expected = set([
+            'Framework :: Django',
+            'Programming Language :: Python :: 3',
+            'Programming Language :: Python :: 3.5',
+        ])
+
+        # From file.
+        _, config = fake_env(
+            tmpdir,
+            '[metadata]\n'
+            'classifiers = file: classifiers\n'
+        )
+
+        tmpdir.join('classifiers').write(
+            'Framework :: Django\n'
+            'Programming Language :: Python :: 3\n'
+            'Programming Language :: Python :: 3.5\n'
+        )
+
+        with get_dist(tmpdir) as dist:
+            assert set(dist.metadata.classifiers) == expected
+
+        # From list notation
+        config.write(
+            '[metadata]\n'
+            'classifiers =\n'
+            '    Framework :: Django\n'
+            '    Programming Language :: Python :: 3\n'
+            '    Programming Language :: Python :: 3.5\n'
+        )
+        with get_dist(tmpdir) as dist:
+            assert set(dist.metadata.classifiers) == expected
+
+
+class TestOptions:
+
+    def test_basic(self, tmpdir):
+
+        fake_env(
+            tmpdir,
+            '[options]\n'
+            'zip_safe = True\n'
+            'use_2to3 = 1\n'
+            'include_package_data = yes\n'
+            'package_dir = b=c, =src\n'
+            'packages = pack_a, pack_b.subpack\n'
+            'namespace_packages = pack1, pack2\n'
+            'use_2to3_fixers = your.fixers, or.here\n'
+            'use_2to3_exclude_fixers = one.here, two.there\n'
+            'convert_2to3_doctests = src/tests/one.txt, src/two.txt\n'
+            'scripts = bin/one.py, bin/two.py\n'
+            'eager_resources = bin/one.py, bin/two.py\n'
+            'install_requires = docutils>=0.3; pack ==1.1, ==1.3; hey\n'
+            'tests_require = mock==0.7.2; pytest\n'
+            'setup_requires = docutils>=0.3; spack ==1.1, ==1.3; there\n'
+            'dependency_links = http://some.com/here/1, '
+                'http://some.com/there/2\n'
+            'python_requires = >=1.0, !=2.8\n'
+            'py_modules = module1, module2\n'
+        )
+        with get_dist(tmpdir) as dist:
+            assert dist.zip_safe
+            assert dist.use_2to3
+            assert dist.include_package_data
+            assert dist.package_dir == {'': 'src', 'b': 'c'}
+            assert dist.packages == ['pack_a', 'pack_b.subpack']
+            assert dist.namespace_packages == ['pack1', 'pack2']
+            assert dist.use_2to3_fixers == ['your.fixers', 'or.here']
+            assert dist.use_2to3_exclude_fixers == ['one.here', 'two.there']
+            assert dist.convert_2to3_doctests == ([
+                'src/tests/one.txt', 'src/two.txt'])
+            assert dist.scripts == ['bin/one.py', 'bin/two.py']
+            assert dist.dependency_links == ([
+                'http://some.com/here/1',
+                'http://some.com/there/2'
+            ])
+            assert dist.install_requires == ([
+                'docutils>=0.3',
+                'pack==1.1,==1.3',
+                'hey'
+            ])
+            assert dist.setup_requires == ([
+                'docutils>=0.3',
+                'spack ==1.1, ==1.3',
+                'there'
+            ])
+            assert dist.tests_require == ['mock==0.7.2', 'pytest']
+            assert dist.python_requires == '>=1.0, !=2.8'
+            assert dist.py_modules == ['module1', 'module2']
+
+    def test_multiline(self, tmpdir):
+        fake_env(
+            tmpdir,
+            '[options]\n'
+            'package_dir = \n'
+            '  b=c\n'
+            '  =src\n'
+            'packages = \n'
+            '  pack_a\n'
+            '  pack_b.subpack\n'
+            'namespace_packages = \n'
+            '  pack1\n'
+            '  pack2\n'
+            'use_2to3_fixers = \n'
+            '  your.fixers\n'
+            '  or.here\n'
+            'use_2to3_exclude_fixers = \n'
+            '  one.here\n'
+            '  two.there\n'
+            'convert_2to3_doctests = \n'
+            '  src/tests/one.txt\n'
+            '  src/two.txt\n'
+            'scripts = \n'
+            '  bin/one.py\n'
+            '  bin/two.py\n'
+            'eager_resources = \n'
+            '  bin/one.py\n'
+            '  bin/two.py\n'
+            'install_requires = \n'
+            '  docutils>=0.3\n'
+            '  pack ==1.1, ==1.3\n'
+            '  hey\n'
+            'tests_require = \n'
+            '  mock==0.7.2\n'
+            '  pytest\n'
+            'setup_requires = \n'
+            '  docutils>=0.3\n'
+            '  spack ==1.1, ==1.3\n'
+            '  there\n'
+            'dependency_links = \n'
+            '  http://some.com/here/1\n'
+            '  http://some.com/there/2\n'
+        )
+        with get_dist(tmpdir) as dist:
+            assert dist.package_dir == {'': 'src', 'b': 'c'}
+            assert dist.packages == ['pack_a', 'pack_b.subpack']
+            assert dist.namespace_packages == ['pack1', 'pack2']
+            assert dist.use_2to3_fixers == ['your.fixers', 'or.here']
+            assert dist.use_2to3_exclude_fixers == ['one.here', 'two.there']
+            assert dist.convert_2to3_doctests == (
+                ['src/tests/one.txt', 'src/two.txt'])
+            assert dist.scripts == ['bin/one.py', 'bin/two.py']
+            assert dist.dependency_links == ([
+                'http://some.com/here/1',
+                'http://some.com/there/2'
+            ])
+            assert dist.install_requires == ([
+                'docutils>=0.3',
+                'pack==1.1,==1.3',
+                'hey'
+            ])
+            assert dist.setup_requires == ([
+                'docutils>=0.3',
+                'spack ==1.1, ==1.3',
+                'there'
+            ])
+            assert dist.tests_require == ['mock==0.7.2', 'pytest']
+
+    def test_package_dir_fail(self, tmpdir):
+        fake_env(
+            tmpdir,
+            '[options]\n'
+            'package_dir = a b\n'
+        )
+        with get_dist(tmpdir, parse=False) as dist:
+            with pytest.raises(DistutilsOptionError):
+                dist.parse_config_files()
+
+    def test_package_data(self, tmpdir):
+        fake_env(
+            tmpdir,
+            '[options.package_data]\n'
+            '* = *.txt, *.rst\n'
+            'hello = *.msg\n'
+            '\n'
+            '[options.exclude_package_data]\n'
+            '* = fake1.txt, fake2.txt\n'
+            'hello = *.dat\n'
+        )
+
+        with get_dist(tmpdir) as dist:
+            assert dist.package_data == {
+                '': ['*.txt', '*.rst'],
+                'hello': ['*.msg'],
+            }
+            assert dist.exclude_package_data == {
+                '': ['fake1.txt', 'fake2.txt'],
+                'hello': ['*.dat'],
+            }
+
+    def test_packages(self, tmpdir):
+        fake_env(
+            tmpdir,
+            '[options]\n'
+            'packages = find:\n'
+        )
+
+        with get_dist(tmpdir) as dist:
+            assert dist.packages == ['fake_package']
+
+    def test_find_directive(self, tmpdir):
+        dir_package, config = fake_env(
+            tmpdir,
+            '[options]\n'
+            'packages = find:\n'
+        )
+
+        dir_sub_one, _ = make_package_dir('sub_one', dir_package)
+        dir_sub_two, _ = make_package_dir('sub_two', dir_package)
+
+        with get_dist(tmpdir) as dist:
+            assert set(dist.packages) == set([
+                'fake_package', 'fake_package.sub_two', 'fake_package.sub_one'
+            ])
+
+        config.write(
+            '[options]\n'
+            'packages = find:\n'
+            '\n'
+            '[options.packages.find]\n'
+            'where = .\n'
+            'include =\n'
+            '    fake_package.sub_one\n'
+            '    two\n'
+        )
+        with get_dist(tmpdir) as dist:
+            assert dist.packages == ['fake_package.sub_one']
+
+        config.write(
+            '[options]\n'
+            'packages = find:\n'
+            '\n'
+            '[options.packages.find]\n'
+            'exclude =\n'
+            '    fake_package.sub_one\n'
+        )
+        with get_dist(tmpdir) as dist:
+            assert set(dist.packages) == set(
+                ['fake_package',  'fake_package.sub_two'])
+
+    def test_extras_require(self, tmpdir):
+        fake_env(
+            tmpdir,
+            '[options.extras_require]\n'
+            'pdf = ReportLab>=1.2; RXP\n'
+            'rest = \n'
+            '  docutils>=0.3\n'
+            '  pack ==1.1, ==1.3\n'
+        )
+
+        with get_dist(tmpdir) as dist:
+            assert dist.extras_require == {
+                'pdf': ['ReportLab>=1.2', 'RXP'],
+                'rest': ['docutils>=0.3', 'pack==1.1,==1.3']
+            }
+            assert dist.metadata.provides_extras == set(['pdf', 'rest'])
+
+    def test_entry_points(self, tmpdir):
+        _, config = fake_env(
+            tmpdir,
+            '[options.entry_points]\n'
+            'group1 = point1 = pack.module:func, '
+                '.point2 = pack.module2:func_rest [rest]\n'
+            'group2 = point3 = pack.module:func2\n'
+        )
+
+        with get_dist(tmpdir) as dist:
+            assert dist.entry_points == {
+                'group1': [
+                    'point1 = pack.module:func',
+                    '.point2 = pack.module2:func_rest [rest]',
+                ],
+                'group2': ['point3 = pack.module:func2']
+            }
+
+        expected = (
+            '[blogtool.parsers]\n'
+            '.rst = some.nested.module:SomeClass.some_classmethod[reST]\n'
+        )
+
+        tmpdir.join('entry_points').write(expected)
+
+        # From file.
+        config.write(
+            '[options]\n'
+            'entry_points = file: entry_points\n'
+        )
+
+        with get_dist(tmpdir) as dist:
+            assert dist.entry_points == expected
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_dep_util.py b/vendor/setuptools-39.0.1/setuptools/tests/test_dep_util.py
new file mode 100644
index 00000000..e5027c10
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_dep_util.py
@@ -0,0 +1,30 @@
+from setuptools.dep_util import newer_pairwise_group
+import os
+import pytest
+
+
+@pytest.fixture
+def groups_target(tmpdir):
+    """Sets up some older sources, a target and newer sources.
+    Returns a 3-tuple in this order.
+    """
+    creation_order = ['older.c', 'older.h', 'target.o', 'newer.c', 'newer.h']
+    mtime = 0
+
+    for i in range(len(creation_order)):
+        creation_order[i] = os.path.join(str(tmpdir), creation_order[i])
+        with open(creation_order[i], 'w'):
+            pass
+
+        # make sure modification times are sequential
+        os.utime(creation_order[i], (mtime, mtime))
+        mtime += 1
+
+    return creation_order[:2], creation_order[2], creation_order[3:]
+
+
+def test_newer_pairwise_group(groups_target):
+    older = newer_pairwise_group([groups_target[0]], [groups_target[1]])
+    newer = newer_pairwise_group([groups_target[2]], [groups_target[1]])
+    assert older == ([], [])
+    assert newer == ([groups_target[2]], [groups_target[1]])
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_depends.py b/vendor/setuptools-39.0.1/setuptools/tests/test_depends.py
new file mode 100644
index 00000000..e0cfa880
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_depends.py
@@ -0,0 +1,16 @@
+import sys
+
+from setuptools import depends
+
+
+class TestGetModuleConstant:
+
+	def test_basic(self):
+		"""
+		Invoke get_module_constant on a module in
+		the test package.
+		"""
+		mod_name = 'setuptools.tests.mod_with_constant'
+		val = depends.get_module_constant(mod_name, 'value')
+		assert val == 'three, sir!'
+		assert 'setuptools.tests.mod_with_constant' not in sys.modules
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_develop.py b/vendor/setuptools-39.0.1/setuptools/tests/test_develop.py
new file mode 100644
index 00000000..00d4bd9a
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_develop.py
@@ -0,0 +1,202 @@
+"""develop tests
+"""
+
+from __future__ import absolute_import, unicode_literals
+
+import os
+import site
+import sys
+import io
+import subprocess
+import platform
+
+from setuptools.extern import six
+from setuptools.command import test
+
+import pytest
+
+from setuptools.command.develop import develop
+from setuptools.dist import Distribution
+from . import contexts
+from . import namespaces
+
+SETUP_PY = """\
+from setuptools import setup
+
+setup(name='foo',
+    packages=['foo'],
+    use_2to3=True,
+)
+"""
+
+INIT_PY = """print "foo"
+"""
+
+
+@pytest.yield_fixture
+def temp_user(monkeypatch):
+    with contexts.tempdir() as user_base:
+        with contexts.tempdir() as user_site:
+            monkeypatch.setattr('site.USER_BASE', user_base)
+            monkeypatch.setattr('site.USER_SITE', user_site)
+            yield
+
+
+@pytest.yield_fixture
+def test_env(tmpdir, temp_user):
+    target = tmpdir
+    foo = target.mkdir('foo')
+    setup = target / 'setup.py'
+    if setup.isfile():
+        raise ValueError(dir(target))
+    with setup.open('w') as f:
+        f.write(SETUP_PY)
+    init = foo / '__init__.py'
+    with init.open('w') as f:
+        f.write(INIT_PY)
+    with target.as_cwd():
+        yield target
+
+
+class TestDevelop:
+    in_virtualenv = hasattr(sys, 'real_prefix')
+    in_venv = hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix
+
+    @pytest.mark.skipif(
+        in_virtualenv or in_venv,
+        reason="Cannot run when invoked in a virtualenv or venv")
+    def test_2to3_user_mode(self, test_env):
+        settings = dict(
+            name='foo',
+            packages=['foo'],
+            use_2to3=True,
+            version='0.0',
+        )
+        dist = Distribution(settings)
+        dist.script_name = 'setup.py'
+        cmd = develop(dist)
+        cmd.user = 1
+        cmd.ensure_finalized()
+        cmd.install_dir = site.USER_SITE
+        cmd.user = 1
+        with contexts.quiet():
+            cmd.run()
+
+        # let's see if we got our egg link at the right place
+        content = os.listdir(site.USER_SITE)
+        content.sort()
+        assert content == ['easy-install.pth', 'foo.egg-link']
+
+        # Check that we are using the right code.
+        fn = os.path.join(site.USER_SITE, 'foo.egg-link')
+        with io.open(fn) as egg_link_file:
+            path = egg_link_file.read().split()[0].strip()
+        fn = os.path.join(path, 'foo', '__init__.py')
+        with io.open(fn) as init_file:
+            init = init_file.read().strip()
+
+        expected = 'print("foo")' if six.PY3 else 'print "foo"'
+        assert init == expected
+
+    def test_console_scripts(self, tmpdir):
+        """
+        Test that console scripts are installed and that they reference
+        only the project by name and not the current version.
+        """
+        pytest.skip(
+            "TODO: needs a fixture to cause 'develop' "
+            "to be invoked without mutating environment.")
+        settings = dict(
+            name='foo',
+            packages=['foo'],
+            version='0.0',
+            entry_points={
+                'console_scripts': [
+                    'foocmd = foo:foo',
+                ],
+            },
+        )
+        dist = Distribution(settings)
+        dist.script_name = 'setup.py'
+        cmd = develop(dist)
+        cmd.ensure_finalized()
+        cmd.install_dir = tmpdir
+        cmd.run()
+        # assert '0.0' not in foocmd_text
+
+
+class TestResolver:
+    """
+    TODO: These tests were written with a minimal understanding
+    of what _resolve_setup_path is intending to do. Come up with
+    more meaningful cases that look like real-world scenarios.
+    """
+    def test_resolve_setup_path_cwd(self):
+        assert develop._resolve_setup_path('.', '.', '.') == '.'
+
+    def test_resolve_setup_path_one_dir(self):
+        assert develop._resolve_setup_path('pkgs', '.', 'pkgs') == '../'
+
+    def test_resolve_setup_path_one_dir_trailing_slash(self):
+        assert develop._resolve_setup_path('pkgs/', '.', 'pkgs') == '../'
+
+
+class TestNamespaces:
+
+    @staticmethod
+    def install_develop(src_dir, target):
+
+        develop_cmd = [
+            sys.executable,
+            'setup.py',
+            'develop',
+            '--install-dir', str(target),
+        ]
+        with src_dir.as_cwd():
+            with test.test.paths_on_pythonpath([str(target)]):
+                subprocess.check_call(develop_cmd)
+
+    @pytest.mark.skipif(
+        bool(os.environ.get("APPVEYOR")),
+        reason="https://github.com/pypa/setuptools/issues/851",
+    )
+    @pytest.mark.skipif(
+        platform.python_implementation() == 'PyPy' and six.PY3,
+        reason="https://github.com/pypa/setuptools/issues/1202",
+    )
+    def test_namespace_package_importable(self, tmpdir):
+        """
+        Installing two packages sharing the same namespace, one installed
+        naturally using pip or `--single-version-externally-managed`
+        and the other installed using `develop` should leave the namespace
+        in tact and both packages reachable by import.
+        """
+        pkg_A = namespaces.build_namespace_package(tmpdir, 'myns.pkgA')
+        pkg_B = namespaces.build_namespace_package(tmpdir, 'myns.pkgB')
+        target = tmpdir / 'packages'
+        # use pip to install to the target directory
+        install_cmd = [
+            sys.executable,
+            '-m',
+            'pip',
+            'install',
+            str(pkg_A),
+            '-t', str(target),
+        ]
+        subprocess.check_call(install_cmd)
+        self.install_develop(pkg_B, target)
+        namespaces.make_site_dir(target)
+        try_import = [
+            sys.executable,
+            '-c', 'import myns.pkgA; import myns.pkgB',
+        ]
+        with test.test.paths_on_pythonpath([str(target)]):
+            subprocess.check_call(try_import)
+
+        # additionally ensure that pkg_resources import works
+        pkg_resources_imp = [
+            sys.executable,
+            '-c', 'import pkg_resources',
+        ]
+        with test.test.paths_on_pythonpath([str(target)]):
+            subprocess.check_call(pkg_resources_imp)
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_dist.py b/vendor/setuptools-39.0.1/setuptools/tests/test_dist.py
new file mode 100644
index 00000000..5162e1c9
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_dist.py
@@ -0,0 +1,145 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import unicode_literals
+
+import io
+
+from setuptools import Distribution
+from setuptools.extern.six.moves.urllib.request import pathname2url
+from setuptools.extern.six.moves.urllib_parse import urljoin
+
+from .textwrap import DALS
+from .test_easy_install import make_nspkg_sdist
+
+import pytest
+
+
+def test_dist_fetch_build_egg(tmpdir):
+    """
+    Check multiple calls to `Distribution.fetch_build_egg` work as expected.
+    """
+    index = tmpdir.mkdir('index')
+    index_url = urljoin('file://', pathname2url(str(index)))
+
+    def sdist_with_index(distname, version):
+        dist_dir = index.mkdir(distname)
+        dist_sdist = '%s-%s.tar.gz' % (distname, version)
+        make_nspkg_sdist(str(dist_dir.join(dist_sdist)), distname, version)
+        with dist_dir.join('index.html').open('w') as fp:
+            fp.write(DALS(
+                '''
+                <!DOCTYPE html><html><body>
+                <a href="{dist_sdist}" rel="internal">{dist_sdist}</a><br/>
+                </body></html>
+                '''
+            ).format(dist_sdist=dist_sdist))
+    sdist_with_index('barbazquux', '3.2.0')
+    sdist_with_index('barbazquux-runner', '2.11.1')
+    with tmpdir.join('setup.cfg').open('w') as fp:
+        fp.write(DALS(
+            '''
+            [easy_install]
+            index_url = {index_url}
+            '''
+        ).format(index_url=index_url))
+    reqs = '''
+    barbazquux-runner
+    barbazquux
+    '''.split()
+    with tmpdir.as_cwd():
+        dist = Distribution()
+        dist.parse_config_files()
+        resolved_dists = [
+            dist.fetch_build_egg(r)
+            for r in reqs
+        ]
+    assert [dist.key for dist in resolved_dists if dist] == reqs
+
+
+def __maintainer_test_cases():
+    attrs = {"name": "package",
+             "version": "1.0",
+             "description": "xxx"}
+
+    def merge_dicts(d1, d2):
+        d1 = d1.copy()
+        d1.update(d2)
+
+        return d1
+
+    test_cases = [
+        ('No author, no maintainer', attrs.copy()),
+        ('Author (no e-mail), no maintainer', merge_dicts(
+            attrs,
+            {'author': 'Author Name'})),
+        ('Author (e-mail), no maintainer', merge_dicts(
+            attrs,
+            {'author': 'Author Name',
+             'author_email': 'author@name.com'})),
+        ('No author, maintainer (no e-mail)', merge_dicts(
+            attrs,
+            {'maintainer': 'Maintainer Name'})),
+        ('No author, maintainer (e-mail)', merge_dicts(
+            attrs,
+            {'maintainer': 'Maintainer Name',
+             'maintainer_email': 'maintainer@name.com'})),
+        ('Author (no e-mail), Maintainer (no-email)', merge_dicts(
+            attrs,
+            {'author': 'Author Name',
+             'maintainer': 'Maintainer Name'})),
+        ('Author (e-mail), Maintainer (e-mail)', merge_dicts(
+            attrs,
+            {'author': 'Author Name',
+             'author_email': 'author@name.com',
+             'maintainer': 'Maintainer Name',
+             'maintainer_email': 'maintainer@name.com'})),
+        ('No author (e-mail), no maintainer (e-mail)', merge_dicts(
+            attrs,
+            {'author_email': 'author@name.com',
+             'maintainer_email': 'maintainer@name.com'})),
+        ('Author unicode', merge_dicts(
+            attrs,
+            {'author': '鉄沢寛'})),
+        ('Maintainer unicode', merge_dicts(
+            attrs,
+            {'maintainer': 'Jan Łukasiewicz'})),
+    ]
+
+    return test_cases
+
+
+@pytest.mark.parametrize('name,attrs', __maintainer_test_cases())
+def test_maintainer_author(name, attrs, tmpdir):
+    tested_keys = {
+        'author': 'Author',
+        'author_email': 'Author-email',
+        'maintainer': 'Maintainer',
+        'maintainer_email': 'Maintainer-email',
+    }
+
+    # Generate a PKG-INFO file
+    dist = Distribution(attrs)
+    fn = tmpdir.mkdir('pkg_info')
+    fn_s = str(fn)
+
+    dist.metadata.write_pkg_info(fn_s)
+
+    with io.open(str(fn.join('PKG-INFO')), 'r', encoding='utf-8') as f:
+        raw_pkg_lines = f.readlines()
+
+    # Drop blank lines
+    pkg_lines = list(filter(None, raw_pkg_lines))
+
+    pkg_lines_set = set(pkg_lines)
+
+    # Duplicate lines should not be generated
+    assert len(pkg_lines) == len(pkg_lines_set)
+
+    for fkey, dkey in tested_keys.items():
+        val = attrs.get(dkey, None)
+        if val is None:
+            for line in pkg_lines:
+                assert not line.startswith(fkey + ':')
+        else:
+            line = '%s: %s' % (fkey, val)
+            assert line in pkg_lines_set
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_dist_info.py b/vendor/setuptools-39.0.1/setuptools/tests/test_dist_info.py
new file mode 100644
index 00000000..f7e7d2bf
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_dist_info.py
@@ -0,0 +1,78 @@
+"""Test .dist-info style distributions.
+"""
+
+from __future__ import unicode_literals
+
+from setuptools.extern.six.moves import map
+
+import pytest
+
+import pkg_resources
+from .textwrap import DALS
+
+
+class TestDistInfo:
+
+    metadata_base = DALS("""
+        Metadata-Version: 1.2
+        Requires-Dist: splort (==4)
+        Provides-Extra: baz
+        Requires-Dist: quux (>=1.1); extra == 'baz'
+        """)
+
+    @classmethod
+    def build_metadata(cls, **kwargs):
+        lines = (
+            '{key}: {value}\n'.format(**locals())
+            for key, value in kwargs.items()
+        )
+        return cls.metadata_base + ''.join(lines)
+
+    @pytest.fixture
+    def metadata(self, tmpdir):
+        dist_info_name = 'VersionedDistribution-2.718.dist-info'
+        versioned = tmpdir / dist_info_name
+        versioned.mkdir()
+        filename = versioned / 'METADATA'
+        content = self.build_metadata(
+            Name='VersionedDistribution',
+        )
+        filename.write_text(content, encoding='utf-8')
+
+        dist_info_name = 'UnversionedDistribution.dist-info'
+        unversioned = tmpdir / dist_info_name
+        unversioned.mkdir()
+        filename = unversioned / 'METADATA'
+        content = self.build_metadata(
+            Name='UnversionedDistribution',
+            Version='0.3',
+        )
+        filename.write_text(content, encoding='utf-8')
+
+        return str(tmpdir)
+
+    def test_distinfo(self, metadata):
+        dists = dict(
+            (d.project_name, d)
+            for d in pkg_resources.find_distributions(metadata)
+        )
+
+        assert len(dists) == 2, dists
+
+        unversioned = dists['UnversionedDistribution']
+        versioned = dists['VersionedDistribution']
+
+        assert versioned.version == '2.718'  # from filename
+        assert unversioned.version == '0.3'  # from METADATA
+
+    def test_conditional_dependencies(self, metadata):
+        specs = 'splort==4', 'quux>=1.1'
+        requires = list(map(pkg_resources.Requirement.parse, specs))
+
+        for d in pkg_resources.find_distributions(metadata):
+            assert d.requires() == requires[:1]
+            assert d.requires(extras=('baz',)) == [
+                requires[0],
+                pkg_resources.Requirement.parse('quux>=1.1;extra=="baz"'),
+            ]
+            assert d.extras == ['baz']
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_easy_install.py b/vendor/setuptools-39.0.1/setuptools/tests/test_easy_install.py
new file mode 100644
index 00000000..57339c8a
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_easy_install.py
@@ -0,0 +1,760 @@
+# -*- coding: utf-8 -*-
+"""Easy install Tests
+"""
+from __future__ import absolute_import
+
+import sys
+import os
+import tempfile
+import site
+import contextlib
+import tarfile
+import logging
+import itertools
+import distutils.errors
+import io
+import zipfile
+import mock
+
+import time
+from setuptools.extern.six.moves import urllib
+
+import pytest
+
+from setuptools import sandbox
+from setuptools.sandbox import run_setup
+import setuptools.command.easy_install as ei
+from setuptools.command.easy_install import PthDistributions
+from setuptools.command import easy_install as easy_install_pkg
+from setuptools.dist import Distribution
+from pkg_resources import normalize_path, working_set
+from pkg_resources import Distribution as PRDistribution
+import setuptools.tests.server
+from setuptools.tests import fail_on_ascii
+import pkg_resources
+
+from . import contexts
+from .textwrap import DALS
+
+
+class FakeDist(object):
+    def get_entry_map(self, group):
+        if group != 'console_scripts':
+            return {}
+        return {'name': 'ep'}
+
+    def as_requirement(self):
+        return 'spec'
+
+
+SETUP_PY = DALS("""
+    from setuptools import setup
+
+    setup(name='foo')
+    """)
+
+
+class TestEasyInstallTest:
+    def test_install_site_py(self, tmpdir):
+        dist = Distribution()
+        cmd = ei.easy_install(dist)
+        cmd.sitepy_installed = False
+        cmd.install_dir = str(tmpdir)
+        cmd.install_site_py()
+        assert (tmpdir / 'site.py').exists()
+
+    def test_get_script_args(self):
+        header = ei.CommandSpec.best().from_environment().as_header()
+        expected = header + DALS(r"""
+            # EASY-INSTALL-ENTRY-SCRIPT: 'spec','console_scripts','name'
+            __requires__ = 'spec'
+            import re
+            import sys
+            from pkg_resources import load_entry_point
+
+            if __name__ == '__main__':
+                sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
+                sys.exit(
+                    load_entry_point('spec', 'console_scripts', 'name')()
+                )
+            """)
+        dist = FakeDist()
+
+        args = next(ei.ScriptWriter.get_args(dist))
+        name, script = itertools.islice(args, 2)
+
+        assert script == expected
+
+    def test_no_find_links(self):
+        # new option '--no-find-links', that blocks find-links added at
+        # the project level
+        dist = Distribution()
+        cmd = ei.easy_install(dist)
+        cmd.check_pth_processing = lambda: True
+        cmd.no_find_links = True
+        cmd.find_links = ['link1', 'link2']
+        cmd.install_dir = os.path.join(tempfile.mkdtemp(), 'ok')
+        cmd.args = ['ok']
+        cmd.ensure_finalized()
+        assert cmd.package_index.scanned_urls == {}
+
+        # let's try without it (default behavior)
+        cmd = ei.easy_install(dist)
+        cmd.check_pth_processing = lambda: True
+        cmd.find_links = ['link1', 'link2']
+        cmd.install_dir = os.path.join(tempfile.mkdtemp(), 'ok')
+        cmd.args = ['ok']
+        cmd.ensure_finalized()
+        keys = sorted(cmd.package_index.scanned_urls.keys())
+        assert keys == ['link1', 'link2']
+
+    def test_write_exception(self):
+        """
+        Test that `cant_write_to_target` is rendered as a DistutilsError.
+        """
+        dist = Distribution()
+        cmd = ei.easy_install(dist)
+        cmd.install_dir = os.getcwd()
+        with pytest.raises(distutils.errors.DistutilsError):
+            cmd.cant_write_to_target()
+
+    def test_all_site_dirs(self, monkeypatch):
+        """
+        get_site_dirs should always return site dirs reported by
+        site.getsitepackages.
+        """
+        path = normalize_path('/setuptools/test/site-packages')
+        mock_gsp = lambda: [path]
+        monkeypatch.setattr(site, 'getsitepackages', mock_gsp, raising=False)
+        assert path in ei.get_site_dirs()
+
+    def test_all_site_dirs_works_without_getsitepackages(self, monkeypatch):
+        monkeypatch.delattr(site, 'getsitepackages', raising=False)
+        assert ei.get_site_dirs()
+
+    @pytest.fixture
+    def sdist_unicode(self, tmpdir):
+        files = [
+            (
+                'setup.py',
+                DALS("""
+                    import setuptools
+                    setuptools.setup(
+                        name="setuptools-test-unicode",
+                        version="1.0",
+                        packages=["mypkg"],
+                        include_package_data=True,
+                    )
+                    """),
+            ),
+            (
+                'mypkg/__init__.py',
+                "",
+            ),
+            (
+                u'mypkg/\u2603.txt',
+                "",
+            ),
+        ]
+        sdist_name = 'setuptools-test-unicode-1.0.zip'
+        sdist = tmpdir / sdist_name
+        # can't use make_sdist, because the issue only occurs
+        #  with zip sdists.
+        sdist_zip = zipfile.ZipFile(str(sdist), 'w')
+        for filename, content in files:
+            sdist_zip.writestr(filename, content)
+        sdist_zip.close()
+        return str(sdist)
+
+    @fail_on_ascii
+    def test_unicode_filename_in_sdist(self, sdist_unicode, tmpdir, monkeypatch):
+        """
+        The install command should execute correctly even if
+        the package has unicode filenames.
+        """
+        dist = Distribution({'script_args': ['easy_install']})
+        target = (tmpdir / 'target').ensure_dir()
+        cmd = ei.easy_install(
+            dist,
+            install_dir=str(target),
+            args=['x'],
+        )
+        monkeypatch.setitem(os.environ, 'PYTHONPATH', str(target))
+        cmd.ensure_finalized()
+        cmd.easy_install(sdist_unicode)
+
+    @pytest.fixture
+    def sdist_script(self, tmpdir):
+        files = [
+            (
+                'setup.py',
+                DALS("""
+                    import setuptools
+                    setuptools.setup(
+                        name="setuptools-test-script",
+                        version="1.0",
+                        scripts=["mypkg_script"],
+                    )
+                    """),
+            ),
+            (
+                u'mypkg_script',
+                DALS("""
+                     #/usr/bin/python
+                     print('mypkg_script')
+                     """),
+            ),
+        ]
+        sdist_name = 'setuptools-test-script-1.0.zip'
+        sdist = str(tmpdir / sdist_name)
+        make_sdist(sdist, files)
+        return sdist
+
+    @pytest.mark.skipif(not sys.platform.startswith('linux'),
+                        reason="Test can only be run on Linux")
+    def test_script_install(self, sdist_script, tmpdir, monkeypatch):
+        """
+        Check scripts are installed.
+        """
+        dist = Distribution({'script_args': ['easy_install']})
+        target = (tmpdir / 'target').ensure_dir()
+        cmd = ei.easy_install(
+            dist,
+            install_dir=str(target),
+            args=['x'],
+        )
+        monkeypatch.setitem(os.environ, 'PYTHONPATH', str(target))
+        cmd.ensure_finalized()
+        cmd.easy_install(sdist_script)
+        assert (target / 'mypkg_script').exists()
+
+
+class TestPTHFileWriter:
+    def test_add_from_cwd_site_sets_dirty(self):
+        '''a pth file manager should set dirty
+        if a distribution is in site but also the cwd
+        '''
+        pth = PthDistributions('does-not_exist', [os.getcwd()])
+        assert not pth.dirty
+        pth.add(PRDistribution(os.getcwd()))
+        assert pth.dirty
+
+    def test_add_from_site_is_ignored(self):
+        location = '/test/location/does-not-have-to-exist'
+        # PthDistributions expects all locations to be normalized
+        location = pkg_resources.normalize_path(location)
+        pth = PthDistributions('does-not_exist', [location, ])
+        assert not pth.dirty
+        pth.add(PRDistribution(location))
+        assert not pth.dirty
+
+
+@pytest.yield_fixture
+def setup_context(tmpdir):
+    with (tmpdir / 'setup.py').open('w') as f:
+        f.write(SETUP_PY)
+    with tmpdir.as_cwd():
+        yield tmpdir
+
+
+@pytest.mark.usefixtures("user_override")
+@pytest.mark.usefixtures("setup_context")
+class TestUserInstallTest:
+
+    # prevent check that site-packages is writable. easy_install
+    # shouldn't be writing to system site-packages during finalize
+    # options, but while it does, bypass the behavior.
+    prev_sp_write = mock.patch(
+        'setuptools.command.easy_install.easy_install.check_site_dir',
+        mock.Mock(),
+    )
+
+    # simulate setuptools installed in user site packages
+    @mock.patch('setuptools.command.easy_install.__file__', site.USER_SITE)
+    @mock.patch('site.ENABLE_USER_SITE', True)
+    @prev_sp_write
+    def test_user_install_not_implied_user_site_enabled(self):
+        self.assert_not_user_site()
+
+    @mock.patch('site.ENABLE_USER_SITE', False)
+    @prev_sp_write
+    def test_user_install_not_implied_user_site_disabled(self):
+        self.assert_not_user_site()
+
+    @staticmethod
+    def assert_not_user_site():
+        # create a finalized easy_install command
+        dist = Distribution()
+        dist.script_name = 'setup.py'
+        cmd = ei.easy_install(dist)
+        cmd.args = ['py']
+        cmd.ensure_finalized()
+        assert not cmd.user, 'user should not be implied'
+
+    def test_multiproc_atexit(self):
+        pytest.importorskip('multiprocessing')
+
+        log = logging.getLogger('test_easy_install')
+        logging.basicConfig(level=logging.INFO, stream=sys.stderr)
+        log.info('this should not break')
+
+    @pytest.fixture()
+    def foo_package(self, tmpdir):
+        egg_file = tmpdir / 'foo-1.0.egg-info'
+        with egg_file.open('w') as f:
+            f.write('Name: foo\n')
+        return str(tmpdir)
+
+    @pytest.yield_fixture()
+    def install_target(self, tmpdir):
+        target = str(tmpdir)
+        with mock.patch('sys.path', sys.path + [target]):
+            python_path = os.path.pathsep.join(sys.path)
+            with mock.patch.dict(os.environ, PYTHONPATH=python_path):
+                yield target
+
+    def test_local_index(self, foo_package, install_target):
+        """
+        The local index must be used when easy_install locates installed
+        packages.
+        """
+        dist = Distribution()
+        dist.script_name = 'setup.py'
+        cmd = ei.easy_install(dist)
+        cmd.install_dir = install_target
+        cmd.args = ['foo']
+        cmd.ensure_finalized()
+        cmd.local_index.scan([foo_package])
+        res = cmd.easy_install('foo')
+        actual = os.path.normcase(os.path.realpath(res.location))
+        expected = os.path.normcase(os.path.realpath(foo_package))
+        assert actual == expected
+
+    @contextlib.contextmanager
+    def user_install_setup_context(self, *args, **kwargs):
+        """
+        Wrap sandbox.setup_context to patch easy_install in that context to
+        appear as user-installed.
+        """
+        with self.orig_context(*args, **kwargs):
+            import setuptools.command.easy_install as ei
+            ei.__file__ = site.USER_SITE
+            yield
+
+    def patched_setup_context(self):
+        self.orig_context = sandbox.setup_context
+
+        return mock.patch(
+            'setuptools.sandbox.setup_context',
+            self.user_install_setup_context,
+        )
+
+
+@pytest.yield_fixture
+def distutils_package():
+    distutils_setup_py = SETUP_PY.replace(
+        'from setuptools import setup',
+        'from distutils.core import setup',
+    )
+    with contexts.tempdir(cd=os.chdir):
+        with open('setup.py', 'w') as f:
+            f.write(distutils_setup_py)
+        yield
+
+
+class TestDistutilsPackage:
+    def test_bdist_egg_available_on_distutils_pkg(self, distutils_package):
+        run_setup('setup.py', ['bdist_egg'])
+
+
+class TestSetupRequires:
+    def test_setup_requires_honors_fetch_params(self):
+        """
+        When easy_install installs a source distribution which specifies
+        setup_requires, it should honor the fetch parameters (such as
+        allow-hosts, index-url, and find-links).
+        """
+        # set up a server which will simulate an alternate package index.
+        p_index = setuptools.tests.server.MockServer()
+        p_index.start()
+        netloc = 1
+        p_index_loc = urllib.parse.urlparse(p_index.url)[netloc]
+        if p_index_loc.endswith(':0'):
+            # Some platforms (Jython) don't find a port to which to bind,
+            #  so skip this test for them.
+            return
+        with contexts.quiet():
+            # create an sdist that has a build-time dependency.
+            with TestSetupRequires.create_sdist() as dist_file:
+                with contexts.tempdir() as temp_install_dir:
+                    with contexts.environment(PYTHONPATH=temp_install_dir):
+                        ei_params = [
+                            '--index-url', p_index.url,
+                            '--allow-hosts', p_index_loc,
+                            '--exclude-scripts',
+                            '--install-dir', temp_install_dir,
+                            dist_file,
+                        ]
+                        with sandbox.save_argv(['easy_install']):
+                            # attempt to install the dist. It should fail because
+                            #  it doesn't exist.
+                            with pytest.raises(SystemExit):
+                                easy_install_pkg.main(ei_params)
+        # there should have been two or three requests to the server
+        #  (three happens on Python 3.3a)
+        assert 2 <= len(p_index.requests) <= 3
+        assert p_index.requests[0].path == '/does-not-exist/'
+
+    @staticmethod
+    @contextlib.contextmanager
+    def create_sdist():
+        """
+        Return an sdist with a setup_requires dependency (of something that
+        doesn't exist)
+        """
+        with contexts.tempdir() as dir:
+            dist_path = os.path.join(dir, 'setuptools-test-fetcher-1.0.tar.gz')
+            make_sdist(dist_path, [
+                ('setup.py', DALS("""
+                    import setuptools
+                    setuptools.setup(
+                        name="setuptools-test-fetcher",
+                        version="1.0",
+                        setup_requires = ['does-not-exist'],
+                    )
+                """))])
+            yield dist_path
+
+    use_setup_cfg = (
+        (),
+        ('dependency_links',),
+        ('setup_requires',),
+        ('dependency_links', 'setup_requires'),
+    )
+
+    @pytest.mark.parametrize('use_setup_cfg', use_setup_cfg)
+    def test_setup_requires_overrides_version_conflict(self, use_setup_cfg):
+        """
+        Regression test for distribution issue 323:
+        https://bitbucket.org/tarek/distribute/issues/323
+
+        Ensures that a distribution's setup_requires requirements can still be
+        installed and used locally even if a conflicting version of that
+        requirement is already on the path.
+        """
+
+        fake_dist = PRDistribution('does-not-matter', project_name='foobar',
+                                   version='0.0')
+        working_set.add(fake_dist)
+
+        with contexts.save_pkg_resources_state():
+            with contexts.tempdir() as temp_dir:
+                test_pkg = create_setup_requires_package(temp_dir, use_setup_cfg=use_setup_cfg)
+                test_setup_py = os.path.join(test_pkg, 'setup.py')
+                with contexts.quiet() as (stdout, stderr):
+                    # Don't even need to install the package, just
+                    # running the setup.py at all is sufficient
+                    run_setup(test_setup_py, ['--name'])
+
+                lines = stdout.readlines()
+                assert len(lines) > 0
+                assert lines[-1].strip() == 'test_pkg'
+
+    @pytest.mark.parametrize('use_setup_cfg', use_setup_cfg)
+    def test_setup_requires_override_nspkg(self, use_setup_cfg):
+        """
+        Like ``test_setup_requires_overrides_version_conflict`` but where the
+        ``setup_requires`` package is part of a namespace package that has
+        *already* been imported.
+        """
+
+        with contexts.save_pkg_resources_state():
+            with contexts.tempdir() as temp_dir:
+                foobar_1_archive = os.path.join(temp_dir, 'foo.bar-0.1.tar.gz')
+                make_nspkg_sdist(foobar_1_archive, 'foo.bar', '0.1')
+                # Now actually go ahead an extract to the temp dir and add the
+                # extracted path to sys.path so foo.bar v0.1 is importable
+                foobar_1_dir = os.path.join(temp_dir, 'foo.bar-0.1')
+                os.mkdir(foobar_1_dir)
+                with tarfile.open(foobar_1_archive) as tf:
+                    tf.extractall(foobar_1_dir)
+                sys.path.insert(1, foobar_1_dir)
+
+                dist = PRDistribution(foobar_1_dir, project_name='foo.bar',
+                                      version='0.1')
+                working_set.add(dist)
+
+                template = DALS("""\
+                    import foo  # Even with foo imported first the
+                                # setup_requires package should override
+                    import setuptools
+                    setuptools.setup(**%r)
+
+                    if not (hasattr(foo, '__path__') and
+                            len(foo.__path__) == 2):
+                        print('FAIL')
+
+                    if 'foo.bar-0.2' not in foo.__path__[0]:
+                        print('FAIL')
+                """)
+
+                test_pkg = create_setup_requires_package(
+                    temp_dir, 'foo.bar', '0.2', make_nspkg_sdist, template,
+                    use_setup_cfg=use_setup_cfg)
+
+                test_setup_py = os.path.join(test_pkg, 'setup.py')
+
+                with contexts.quiet() as (stdout, stderr):
+                    try:
+                        # Don't even need to install the package, just
+                        # running the setup.py at all is sufficient
+                        run_setup(test_setup_py, ['--name'])
+                    except pkg_resources.VersionConflict:
+                        self.fail('Installing setup.py requirements '
+                            'caused a VersionConflict')
+
+                assert 'FAIL' not in stdout.getvalue()
+                lines = stdout.readlines()
+                assert len(lines) > 0
+                assert lines[-1].strip() == 'test_pkg'
+
+    @pytest.mark.parametrize('use_setup_cfg', use_setup_cfg)
+    def test_setup_requires_with_attr_version(self, use_setup_cfg):
+        def make_dependency_sdist(dist_path, distname, version):
+            make_sdist(dist_path, [
+                ('setup.py',
+                 DALS("""
+                      import setuptools
+                      setuptools.setup(
+                          name={name!r},
+                          version={version!r},
+                          py_modules=[{name!r}],
+                      )
+                      """.format(name=distname, version=version))),
+                (distname + '.py',
+                 DALS("""
+                      version = 42
+                      """
+                     ))])
+        with contexts.save_pkg_resources_state():
+            with contexts.tempdir() as temp_dir:
+                test_pkg = create_setup_requires_package(
+                    temp_dir, setup_attrs=dict(version='attr: foobar.version'),
+                    make_package=make_dependency_sdist,
+                    use_setup_cfg=use_setup_cfg+('version',),
+                )
+                test_setup_py = os.path.join(test_pkg, 'setup.py')
+                with contexts.quiet() as (stdout, stderr):
+                    run_setup(test_setup_py, ['--version'])
+                lines = stdout.readlines()
+                assert len(lines) > 0
+                assert lines[-1].strip() == '42'
+
+
+def make_trivial_sdist(dist_path, distname, version):
+    """
+    Create a simple sdist tarball at dist_path, containing just a simple
+    setup.py.
+    """
+
+    make_sdist(dist_path, [
+        ('setup.py',
+         DALS("""\
+             import setuptools
+             setuptools.setup(
+                 name=%r,
+                 version=%r
+             )
+         """ % (distname, version)))])
+
+
+def make_nspkg_sdist(dist_path, distname, version):
+    """
+    Make an sdist tarball with distname and version which also contains one
+    package with the same name as distname.  The top-level package is
+    designated a namespace package).
+    """
+
+    parts = distname.split('.')
+    nspackage = parts[0]
+
+    packages = ['.'.join(parts[:idx]) for idx in range(1, len(parts) + 1)]
+
+    setup_py = DALS("""\
+        import setuptools
+        setuptools.setup(
+            name=%r,
+            version=%r,
+            packages=%r,
+            namespace_packages=[%r]
+        )
+    """ % (distname, version, packages, nspackage))
+
+    init = "__import__('pkg_resources').declare_namespace(__name__)"
+
+    files = [('setup.py', setup_py),
+             (os.path.join(nspackage, '__init__.py'), init)]
+    for package in packages[1:]:
+        filename = os.path.join(*(package.split('.') + ['__init__.py']))
+        files.append((filename, ''))
+
+    make_sdist(dist_path, files)
+
+
+def make_sdist(dist_path, files):
+    """
+    Create a simple sdist tarball at dist_path, containing the files
+    listed in ``files`` as ``(filename, content)`` tuples.
+    """
+
+    with tarfile.open(dist_path, 'w:gz') as dist:
+        for filename, content in files:
+            file_bytes = io.BytesIO(content.encode('utf-8'))
+            file_info = tarfile.TarInfo(name=filename)
+            file_info.size = len(file_bytes.getvalue())
+            file_info.mtime = int(time.time())
+            dist.addfile(file_info, fileobj=file_bytes)
+
+
+def create_setup_requires_package(path, distname='foobar', version='0.1',
+                                  make_package=make_trivial_sdist,
+                                  setup_py_template=None, setup_attrs={},
+                                  use_setup_cfg=()):
+    """Creates a source tree under path for a trivial test package that has a
+    single requirement in setup_requires--a tarball for that requirement is
+    also created and added to the dependency_links argument.
+
+    ``distname`` and ``version`` refer to the name/version of the package that
+    the test package requires via ``setup_requires``.  The name of the test
+    package itself is just 'test_pkg'.
+    """
+
+    test_setup_attrs = {
+        'name': 'test_pkg', 'version': '0.0',
+        'setup_requires': ['%s==%s' % (distname, version)],
+        'dependency_links': [os.path.abspath(path)]
+    }
+    test_setup_attrs.update(setup_attrs)
+
+    test_pkg = os.path.join(path, 'test_pkg')
+    os.mkdir(test_pkg)
+
+    if use_setup_cfg:
+        test_setup_cfg = os.path.join(test_pkg, 'setup.cfg')
+        options = []
+        metadata = []
+        for name in use_setup_cfg:
+            value = test_setup_attrs.pop(name)
+            if name in 'name version'.split():
+                section = metadata
+            else:
+                section = options
+            if isinstance(value, (tuple, list)):
+                value = ';'.join(value)
+            section.append('%s: %s' % (name, value))
+        with open(test_setup_cfg, 'w') as f:
+            f.write(DALS(
+                """
+                [metadata]
+                {metadata}
+                [options]
+                {options}
+                """
+            ).format(
+                options='\n'.join(options),
+                metadata='\n'.join(metadata),
+            ))
+
+    test_setup_py = os.path.join(test_pkg, 'setup.py')
+
+    if setup_py_template is None:
+        setup_py_template = DALS("""\
+            import setuptools
+            setuptools.setup(**%r)
+        """)
+
+    with open(test_setup_py, 'w') as f:
+        f.write(setup_py_template % test_setup_attrs)
+
+    foobar_path = os.path.join(path, '%s-%s.tar.gz' % (distname, version))
+    make_package(foobar_path, distname, version)
+
+    return test_pkg
+
+
+@pytest.mark.skipif(
+    sys.platform.startswith('java') and ei.is_sh(sys.executable),
+    reason="Test cannot run under java when executable is sh"
+)
+class TestScriptHeader:
+    non_ascii_exe = '/Users/José/bin/python'
+    exe_with_spaces = r'C:\Program Files\Python33\python.exe'
+
+    def test_get_script_header(self):
+        expected = '#!%s\n' % ei.nt_quote_arg(os.path.normpath(sys.executable))
+        actual = ei.ScriptWriter.get_script_header('#!/usr/local/bin/python')
+        assert actual == expected
+
+    def test_get_script_header_args(self):
+        expected = '#!%s -x\n' % ei.nt_quote_arg(os.path.normpath
+            (sys.executable))
+        actual = ei.ScriptWriter.get_script_header('#!/usr/bin/python -x')
+        assert actual == expected
+
+    def test_get_script_header_non_ascii_exe(self):
+        actual = ei.ScriptWriter.get_script_header('#!/usr/bin/python',
+            executable=self.non_ascii_exe)
+        expected = '#!%s -x\n' % self.non_ascii_exe
+        assert actual == expected
+
+    def test_get_script_header_exe_with_spaces(self):
+        actual = ei.ScriptWriter.get_script_header('#!/usr/bin/python',
+            executable='"' + self.exe_with_spaces + '"')
+        expected = '#!"%s"\n' % self.exe_with_spaces
+        assert actual == expected
+
+
+class TestCommandSpec:
+    def test_custom_launch_command(self):
+        """
+        Show how a custom CommandSpec could be used to specify a #! executable
+        which takes parameters.
+        """
+        cmd = ei.CommandSpec(['/usr/bin/env', 'python3'])
+        assert cmd.as_header() == '#!/usr/bin/env python3\n'
+
+    def test_from_param_for_CommandSpec_is_passthrough(self):
+        """
+        from_param should return an instance of a CommandSpec
+        """
+        cmd = ei.CommandSpec(['python'])
+        cmd_new = ei.CommandSpec.from_param(cmd)
+        assert cmd is cmd_new
+
+    @mock.patch('sys.executable', TestScriptHeader.exe_with_spaces)
+    @mock.patch.dict(os.environ)
+    def test_from_environment_with_spaces_in_executable(self):
+        os.environ.pop('__PYVENV_LAUNCHER__', None)
+        cmd = ei.CommandSpec.from_environment()
+        assert len(cmd) == 1
+        assert cmd.as_header().startswith('#!"')
+
+    def test_from_simple_string_uses_shlex(self):
+        """
+        In order to support `executable = /usr/bin/env my-python`, make sure
+        from_param invokes shlex on that input.
+        """
+        cmd = ei.CommandSpec.from_param('/usr/bin/env my-python')
+        assert len(cmd) == 2
+        assert '"' not in cmd.as_header()
+
+
+class TestWindowsScriptWriter:
+    def test_header(self):
+        hdr = ei.WindowsScriptWriter.get_script_header('')
+        assert hdr.startswith('#!')
+        assert hdr.endswith('\n')
+        hdr = hdr.lstrip('#!')
+        hdr = hdr.rstrip('\n')
+        # header should not start with an escaped quote
+        assert not hdr.startswith('\\"')
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_egg_info.py b/vendor/setuptools-39.0.1/setuptools/tests/test_egg_info.py
new file mode 100644
index 00000000..d2211671
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_egg_info.py
@@ -0,0 +1,586 @@
+import sys
+import ast
+import os
+import glob
+import re
+import stat
+
+from setuptools.command.egg_info import egg_info, manifest_maker
+from setuptools.dist import Distribution
+from setuptools.extern.six.moves import map
+
+import pytest
+
+from . import environment
+from .files import build_files
+from .textwrap import DALS
+from . import contexts
+
+
+class Environment(str):
+    pass
+
+
+class TestEggInfo(object):
+
+    setup_script = DALS("""
+        from setuptools import setup
+
+        setup(
+            name='foo',
+            py_modules=['hello'],
+            entry_points={'console_scripts': ['hi = hello.run']},
+            zip_safe=False,
+        )
+        """)
+
+    def _create_project(self):
+        build_files({
+            'setup.py': self.setup_script,
+            'hello.py': DALS("""
+                def run():
+                    print('hello')
+                """)
+        })
+
+    @pytest.yield_fixture
+    def env(self):
+        with contexts.tempdir(prefix='setuptools-test.') as env_dir:
+            env = Environment(env_dir)
+            os.chmod(env_dir, stat.S_IRWXU)
+            subs = 'home', 'lib', 'scripts', 'data', 'egg-base'
+            env.paths = dict(
+                (dirname, os.path.join(env_dir, dirname))
+                for dirname in subs
+            )
+            list(map(os.mkdir, env.paths.values()))
+            build_files({
+                env.paths['home']: {
+                    '.pydistutils.cfg': DALS("""
+                    [egg_info]
+                    egg-base = %(egg-base)s
+                    """ % env.paths)
+                }
+            })
+            yield env
+
+    def test_egg_info_save_version_info_setup_empty(self, tmpdir_cwd, env):
+        """
+        When the egg_info section is empty or not present, running
+        save_version_info should add the settings to the setup.cfg
+        in a deterministic order, consistent with the ordering found
+        on Python 2.7 with PYTHONHASHSEED=0.
+        """
+        setup_cfg = os.path.join(env.paths['home'], 'setup.cfg')
+        dist = Distribution()
+        ei = egg_info(dist)
+        ei.initialize_options()
+        ei.save_version_info(setup_cfg)
+
+        with open(setup_cfg, 'r') as f:
+            content = f.read()
+
+        assert '[egg_info]' in content
+        assert 'tag_build =' in content
+        assert 'tag_date = 0' in content
+
+        expected_order = 'tag_build', 'tag_date',
+
+        self._validate_content_order(content, expected_order)
+
+    @staticmethod
+    def _validate_content_order(content, expected):
+        """
+        Assert that the strings in expected appear in content
+        in order.
+        """
+        pattern = '.*'.join(expected)
+        flags = re.MULTILINE | re.DOTALL
+        assert re.search(pattern, content, flags)
+
+    def test_egg_info_save_version_info_setup_defaults(self, tmpdir_cwd, env):
+        """
+        When running save_version_info on an existing setup.cfg
+        with the 'default' values present from a previous run,
+        the file should remain unchanged.
+        """
+        setup_cfg = os.path.join(env.paths['home'], 'setup.cfg')
+        build_files({
+            setup_cfg: DALS("""
+            [egg_info]
+            tag_build =
+            tag_date = 0
+            """),
+        })
+        dist = Distribution()
+        ei = egg_info(dist)
+        ei.initialize_options()
+        ei.save_version_info(setup_cfg)
+
+        with open(setup_cfg, 'r') as f:
+            content = f.read()
+
+        assert '[egg_info]' in content
+        assert 'tag_build =' in content
+        assert 'tag_date = 0' in content
+
+        expected_order = 'tag_build', 'tag_date',
+
+        self._validate_content_order(content, expected_order)
+
+    def test_egg_base_installed_egg_info(self, tmpdir_cwd, env):
+        self._create_project()
+
+        self._run_install_command(tmpdir_cwd, env)
+        actual = self._find_egg_info_files(env.paths['lib'])
+
+        expected = [
+            'PKG-INFO',
+            'SOURCES.txt',
+            'dependency_links.txt',
+            'entry_points.txt',
+            'not-zip-safe',
+            'top_level.txt',
+        ]
+        assert sorted(actual) == expected
+
+    def test_manifest_template_is_read(self, tmpdir_cwd, env):
+        self._create_project()
+        build_files({
+            'MANIFEST.in': DALS("""
+                recursive-include docs *.rst
+            """),
+            'docs': {
+                'usage.rst': "Run 'hi'",
+            }
+        })
+        self._run_install_command(tmpdir_cwd, env)
+        egg_info_dir = self._find_egg_info_files(env.paths['lib']).base
+        sources_txt = os.path.join(egg_info_dir, 'SOURCES.txt')
+        with open(sources_txt) as f:
+            assert 'docs/usage.rst' in f.read().split('\n')
+
+    def _setup_script_with_requires(self, requires, use_setup_cfg=False):
+        setup_script = DALS(
+            '''
+            from setuptools import setup
+
+            setup(name='foo', zip_safe=False, %s)
+            '''
+        ) % ('' if use_setup_cfg else requires)
+        setup_config = requires if use_setup_cfg else ''
+        build_files({'setup.py': setup_script,
+                     'setup.cfg': setup_config})
+
+    mismatch_marker = "python_version<'{this_ver}'".format(
+        this_ver=sys.version_info[0],
+    )
+    # Alternate equivalent syntax.
+    mismatch_marker_alternate = 'python_version < "{this_ver}"'.format(
+        this_ver=sys.version_info[0],
+    )
+    invalid_marker = "<=>++"
+
+    class RequiresTestHelper(object):
+
+        @staticmethod
+        def parametrize(*test_list, **format_dict):
+            idlist = []
+            argvalues = []
+            for test in test_list:
+                test_params = test.lstrip().split('\n\n', 3)
+                name_kwargs = test_params.pop(0).split('\n')
+                if len(name_kwargs) > 1:
+                    val = name_kwargs[1].strip()
+                    install_cmd_kwargs = ast.literal_eval(val)
+                else:
+                    install_cmd_kwargs = {}
+                name = name_kwargs[0].strip()
+                setup_py_requires, setup_cfg_requires, expected_requires = (
+                    DALS(a).format(**format_dict) for a in test_params
+                )
+                for id_, requires, use_cfg in (
+                    (name, setup_py_requires, False),
+                    (name + '_in_setup_cfg', setup_cfg_requires, True),
+                ):
+                    idlist.append(id_)
+                    marks = ()
+                    if requires.startswith('@xfail\n'):
+                        requires = requires[7:]
+                        marks = pytest.mark.xfail
+                    argvalues.append(pytest.param(requires, use_cfg,
+                                                  expected_requires,
+                                                  install_cmd_kwargs,
+                                                  marks=marks))
+            return pytest.mark.parametrize(
+                'requires,use_setup_cfg,'
+                'expected_requires,install_cmd_kwargs',
+                argvalues, ids=idlist,
+            )
+
+    @RequiresTestHelper.parametrize(
+        # Format of a test:
+        #
+        # id
+        # install_cmd_kwargs [optional]
+        #
+        # requires block (when used in setup.py)
+        #
+        # requires block (when used in setup.cfg)
+        #
+        # expected contents of requires.txt
+
+        '''
+        install_requires_deterministic
+
+        install_requires=["fake-factory==0.5.2", "pytz"]
+
+        [options]
+        install_requires =
+            fake-factory==0.5.2
+            pytz
+
+        fake-factory==0.5.2
+        pytz
+        ''',
+
+        '''
+        install_requires_with_marker
+
+        install_requires=["barbazquux;{mismatch_marker}"],
+
+        [options]
+        install_requires =
+            barbazquux; {mismatch_marker}
+
+        [:{mismatch_marker_alternate}]
+        barbazquux
+        ''',
+
+        '''
+        install_requires_with_extra
+        {'cmd': ['egg_info']}
+
+        install_requires=["barbazquux [test]"],
+
+        [options]
+        install_requires =
+            barbazquux [test]
+
+        barbazquux[test]
+        ''',
+
+        '''
+        install_requires_with_extra_and_marker
+
+        install_requires=["barbazquux [test]; {mismatch_marker}"],
+
+        [options]
+        install_requires =
+            barbazquux [test]; {mismatch_marker}
+
+        [:{mismatch_marker_alternate}]
+        barbazquux[test]
+        ''',
+
+        '''
+        setup_requires_with_markers
+
+        setup_requires=["barbazquux;{mismatch_marker}"],
+
+        [options]
+        setup_requires =
+            barbazquux; {mismatch_marker}
+
+        ''',
+
+        '''
+        tests_require_with_markers
+        {'cmd': ['test'], 'output': "Ran 0 tests in"}
+
+        tests_require=["barbazquux;{mismatch_marker}"],
+
+        [options]
+        tests_require =
+            barbazquux; {mismatch_marker}
+
+        ''',
+
+        '''
+        extras_require_with_extra
+        {'cmd': ['egg_info']}
+
+        extras_require={{"extra": ["barbazquux [test]"]}},
+
+        [options.extras_require]
+        extra = barbazquux [test]
+
+        [extra]
+        barbazquux[test]
+        ''',
+
+        '''
+        extras_require_with_extra_and_marker_in_req
+
+        extras_require={{"extra": ["barbazquux [test]; {mismatch_marker}"]}},
+
+        [options.extras_require]
+        extra =
+            barbazquux [test]; {mismatch_marker}
+
+        [extra]
+
+        [extra:{mismatch_marker_alternate}]
+        barbazquux[test]
+        ''',
+
+        # FIXME: ConfigParser does not allow : in key names!
+        '''
+        extras_require_with_marker
+
+        extras_require={{":{mismatch_marker}": ["barbazquux"]}},
+
+        @xfail
+        [options.extras_require]
+        :{mismatch_marker} = barbazquux
+
+        [:{mismatch_marker}]
+        barbazquux
+        ''',
+
+        '''
+        extras_require_with_marker_in_req
+
+        extras_require={{"extra": ["barbazquux; {mismatch_marker}"]}},
+
+        [options.extras_require]
+        extra =
+            barbazquux; {mismatch_marker}
+
+        [extra]
+
+        [extra:{mismatch_marker_alternate}]
+        barbazquux
+        ''',
+
+        '''
+        extras_require_with_empty_section
+
+        extras_require={{"empty": []}},
+
+        [options.extras_require]
+        empty =
+
+        [empty]
+        ''',
+        # Format arguments.
+        invalid_marker=invalid_marker,
+        mismatch_marker=mismatch_marker,
+        mismatch_marker_alternate=mismatch_marker_alternate,
+    )
+    def test_requires(
+            self, tmpdir_cwd, env, requires, use_setup_cfg,
+            expected_requires, install_cmd_kwargs):
+        self._setup_script_with_requires(requires, use_setup_cfg)
+        self._run_install_command(tmpdir_cwd, env, **install_cmd_kwargs)
+        egg_info_dir = os.path.join('.', 'foo.egg-info')
+        requires_txt = os.path.join(egg_info_dir, 'requires.txt')
+        if os.path.exists(requires_txt):
+            with open(requires_txt) as fp:
+                install_requires = fp.read()
+        else:
+            install_requires = ''
+        assert install_requires.lstrip() == expected_requires
+        assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == []
+
+    def test_install_requires_unordered_disallowed(self, tmpdir_cwd, env):
+        """
+        Packages that pass unordered install_requires sequences
+        should be rejected as they produce non-deterministic
+        builds. See #458.
+        """
+        req = 'install_requires={"fake-factory==0.5.2", "pytz"}'
+        self._setup_script_with_requires(req)
+        with pytest.raises(AssertionError):
+            self._run_install_command(tmpdir_cwd, env)
+
+    def test_extras_require_with_invalid_marker(self, tmpdir_cwd, env):
+        tmpl = 'extras_require={{":{marker}": ["barbazquux"]}},'
+        req = tmpl.format(marker=self.invalid_marker)
+        self._setup_script_with_requires(req)
+        with pytest.raises(AssertionError):
+            self._run_install_command(tmpdir_cwd, env)
+        assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == []
+
+    def test_extras_require_with_invalid_marker_in_req(self, tmpdir_cwd, env):
+        tmpl = 'extras_require={{"extra": ["barbazquux; {marker}"]}},'
+        req = tmpl.format(marker=self.invalid_marker)
+        self._setup_script_with_requires(req)
+        with pytest.raises(AssertionError):
+            self._run_install_command(tmpdir_cwd, env)
+        assert glob.glob(os.path.join(env.paths['lib'], 'barbazquux*')) == []
+
+    def test_provides_extra(self, tmpdir_cwd, env):
+        self._setup_script_with_requires(
+            'extras_require={"foobar": ["barbazquux"]},')
+        environ = os.environ.copy().update(
+            HOME=env.paths['home'],
+        )
+        code, data = environment.run_setup_py(
+            cmd=['egg_info'],
+            pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]),
+            data_stream=1,
+            env=environ,
+        )
+        egg_info_dir = os.path.join('.', 'foo.egg-info')
+        with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file:
+            pkg_info_lines = pkginfo_file.read().split('\n')
+        assert 'Provides-Extra: foobar' in pkg_info_lines
+        assert 'Metadata-Version: 2.1' in pkg_info_lines
+
+    def test_doesnt_provides_extra(self, tmpdir_cwd, env):
+        self._setup_script_with_requires(
+            '''install_requires=["spam ; python_version<'3.3'"]''')
+        environ = os.environ.copy().update(
+            HOME=env.paths['home'],
+        )
+        environment.run_setup_py(
+            cmd=['egg_info'],
+            pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]),
+            data_stream=1,
+            env=environ,
+        )
+        egg_info_dir = os.path.join('.', 'foo.egg-info')
+        with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file:
+            pkg_info_text = pkginfo_file.read()
+        assert 'Provides-Extra:' not in pkg_info_text
+
+    def test_long_description_content_type(self, tmpdir_cwd, env):
+        # Test that specifying a `long_description_content_type` keyword arg to
+        # the `setup` function results in writing a `Description-Content-Type`
+        # line to the `PKG-INFO` file in the `<distribution>.egg-info`
+        # directory.
+        # `Description-Content-Type` is described at
+        # https://github.com/pypa/python-packaging-user-guide/pull/258
+
+        self._setup_script_with_requires(
+            """long_description_content_type='text/markdown',""")
+        environ = os.environ.copy().update(
+            HOME=env.paths['home'],
+        )
+        code, data = environment.run_setup_py(
+            cmd=['egg_info'],
+            pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]),
+            data_stream=1,
+            env=environ,
+        )
+        egg_info_dir = os.path.join('.', 'foo.egg-info')
+        with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file:
+            pkg_info_lines = pkginfo_file.read().split('\n')
+        expected_line = 'Description-Content-Type: text/markdown'
+        assert expected_line in pkg_info_lines
+        assert 'Metadata-Version: 2.1' in pkg_info_lines
+
+    def test_project_urls(self, tmpdir_cwd, env):
+        # Test that specifying a `project_urls` dict to the `setup`
+        # function results in writing multiple `Project-URL` lines to
+        # the `PKG-INFO` file in the `<distribution>.egg-info`
+        # directory.
+        # `Project-URL` is described at https://packaging.python.org
+        #     /specifications/core-metadata/#project-url-multiple-use
+
+        self._setup_script_with_requires(
+            """project_urls={
+                'Link One': 'https://example.com/one/',
+                'Link Two': 'https://example.com/two/',
+                },""")
+        environ = os.environ.copy().update(
+            HOME=env.paths['home'],
+        )
+        code, data = environment.run_setup_py(
+            cmd=['egg_info'],
+            pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]),
+            data_stream=1,
+            env=environ,
+        )
+        egg_info_dir = os.path.join('.', 'foo.egg-info')
+        with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file:
+            pkg_info_lines = pkginfo_file.read().split('\n')
+        expected_line = 'Project-URL: Link One, https://example.com/one/'
+        assert expected_line in pkg_info_lines
+        expected_line = 'Project-URL: Link Two, https://example.com/two/'
+        assert expected_line in pkg_info_lines
+
+    def test_python_requires_egg_info(self, tmpdir_cwd, env):
+        self._setup_script_with_requires(
+            """python_requires='>=2.7.12',""")
+        environ = os.environ.copy().update(
+            HOME=env.paths['home'],
+        )
+        code, data = environment.run_setup_py(
+            cmd=['egg_info'],
+            pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]),
+            data_stream=1,
+            env=environ,
+        )
+        egg_info_dir = os.path.join('.', 'foo.egg-info')
+        with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file:
+            pkg_info_lines = pkginfo_file.read().split('\n')
+        assert 'Requires-Python: >=2.7.12' in pkg_info_lines
+        assert 'Metadata-Version: 1.2' in pkg_info_lines
+
+    def test_python_requires_install(self, tmpdir_cwd, env):
+        self._setup_script_with_requires(
+            """python_requires='>=1.2.3',""")
+        self._run_install_command(tmpdir_cwd, env)
+        egg_info_dir = self._find_egg_info_files(env.paths['lib']).base
+        pkginfo = os.path.join(egg_info_dir, 'PKG-INFO')
+        with open(pkginfo) as f:
+            assert 'Requires-Python: >=1.2.3' in f.read().split('\n')
+
+    def test_manifest_maker_warning_suppression(self):
+        fixtures = [
+            "standard file not found: should have one of foo.py, bar.py",
+            "standard file 'setup.py' not found"
+        ]
+
+        for msg in fixtures:
+            assert manifest_maker._should_suppress_warning(msg)
+
+    def _run_install_command(self, tmpdir_cwd, env, cmd=None, output=None):
+        environ = os.environ.copy().update(
+            HOME=env.paths['home'],
+        )
+        if cmd is None:
+            cmd = [
+                'install',
+                '--home', env.paths['home'],
+                '--install-lib', env.paths['lib'],
+                '--install-scripts', env.paths['scripts'],
+                '--install-data', env.paths['data'],
+            ]
+        code, data = environment.run_setup_py(
+            cmd=cmd,
+            pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]),
+            data_stream=1,
+            env=environ,
+        )
+        if code:
+            raise AssertionError(data)
+        if output:
+            assert output in data
+
+    def _find_egg_info_files(self, root):
+        class DirList(list):
+            def __init__(self, files, base):
+                super(DirList, self).__init__(files)
+                self.base = base
+
+        results = (
+            DirList(filenames, dirpath)
+            for dirpath, dirnames, filenames in os.walk(root)
+            if os.path.basename(dirpath) == 'EGG-INFO'
+        )
+        # expect exactly one result
+        result, = results
+        return result
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_find_packages.py b/vendor/setuptools-39.0.1/setuptools/tests/test_find_packages.py
new file mode 100644
index 00000000..a6023de9
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_find_packages.py
@@ -0,0 +1,182 @@
+"""Tests for setuptools.find_packages()."""
+import os
+import sys
+import shutil
+import tempfile
+import platform
+
+import pytest
+
+import setuptools
+from setuptools import find_packages
+
+find_420_packages = setuptools.PEP420PackageFinder.find
+
+# modeled after CPython's test.support.can_symlink
+
+
+def can_symlink():
+    TESTFN = tempfile.mktemp()
+    symlink_path = TESTFN + "can_symlink"
+    try:
+        os.symlink(TESTFN, symlink_path)
+        can = True
+    except (OSError, NotImplementedError, AttributeError):
+        can = False
+    else:
+        os.remove(symlink_path)
+    globals().update(can_symlink=lambda: can)
+    return can
+
+
+def has_symlink():
+    bad_symlink = (
+        # Windows symlink directory detection is broken on Python 3.2
+        platform.system() == 'Windows' and sys.version_info[:2] == (3, 2)
+    )
+    return can_symlink() and not bad_symlink
+
+
+class TestFindPackages:
+    def setup_method(self, method):
+        self.dist_dir = tempfile.mkdtemp()
+        self._make_pkg_structure()
+
+    def teardown_method(self, method):
+        shutil.rmtree(self.dist_dir)
+
+    def _make_pkg_structure(self):
+        """Make basic package structure.
+
+        dist/
+            docs/
+                conf.py
+            pkg/
+                __pycache__/
+                nspkg/
+                    mod.py
+                subpkg/
+                    assets/
+                        asset
+                    __init__.py
+            setup.py
+
+        """
+        self.docs_dir = self._mkdir('docs', self.dist_dir)
+        self._touch('conf.py', self.docs_dir)
+        self.pkg_dir = self._mkdir('pkg', self.dist_dir)
+        self._mkdir('__pycache__', self.pkg_dir)
+        self.ns_pkg_dir = self._mkdir('nspkg', self.pkg_dir)
+        self._touch('mod.py', self.ns_pkg_dir)
+        self.sub_pkg_dir = self._mkdir('subpkg', self.pkg_dir)
+        self.asset_dir = self._mkdir('assets', self.sub_pkg_dir)
+        self._touch('asset', self.asset_dir)
+        self._touch('__init__.py', self.sub_pkg_dir)
+        self._touch('setup.py', self.dist_dir)
+
+    def _mkdir(self, path, parent_dir=None):
+        if parent_dir:
+            path = os.path.join(parent_dir, path)
+        os.mkdir(path)
+        return path
+
+    def _touch(self, path, dir_=None):
+        if dir_:
+            path = os.path.join(dir_, path)
+        fp = open(path, 'w')
+        fp.close()
+        return path
+
+    def test_regular_package(self):
+        self._touch('__init__.py', self.pkg_dir)
+        packages = find_packages(self.dist_dir)
+        assert packages == ['pkg', 'pkg.subpkg']
+
+    def test_exclude(self):
+        self._touch('__init__.py', self.pkg_dir)
+        packages = find_packages(self.dist_dir, exclude=('pkg.*',))
+        assert packages == ['pkg']
+
+    def test_exclude_recursive(self):
+        """
+        Excluding a parent package should not exclude child packages as well.
+        """
+        self._touch('__init__.py', self.pkg_dir)
+        self._touch('__init__.py', self.sub_pkg_dir)
+        packages = find_packages(self.dist_dir, exclude=('pkg',))
+        assert packages == ['pkg.subpkg']
+
+    def test_include_excludes_other(self):
+        """
+        If include is specified, other packages should be excluded.
+        """
+        self._touch('__init__.py', self.pkg_dir)
+        alt_dir = self._mkdir('other_pkg', self.dist_dir)
+        self._touch('__init__.py', alt_dir)
+        packages = find_packages(self.dist_dir, include=['other_pkg'])
+        assert packages == ['other_pkg']
+
+    def test_dir_with_dot_is_skipped(self):
+        shutil.rmtree(os.path.join(self.dist_dir, 'pkg/subpkg/assets'))
+        data_dir = self._mkdir('some.data', self.pkg_dir)
+        self._touch('__init__.py', data_dir)
+        self._touch('file.dat', data_dir)
+        packages = find_packages(self.dist_dir)
+        assert 'pkg.some.data' not in packages
+
+    def test_dir_with_packages_in_subdir_is_excluded(self):
+        """
+        Ensure that a package in a non-package such as build/pkg/__init__.py
+        is excluded.
+        """
+        build_dir = self._mkdir('build', self.dist_dir)
+        build_pkg_dir = self._mkdir('pkg', build_dir)
+        self._touch('__init__.py', build_pkg_dir)
+        packages = find_packages(self.dist_dir)
+        assert 'build.pkg' not in packages
+
+    @pytest.mark.skipif(not has_symlink(), reason='Symlink support required')
+    def test_symlinked_packages_are_included(self):
+        """
+        A symbolically-linked directory should be treated like any other
+        directory when matched as a package.
+
+        Create a link from lpkg -> pkg.
+        """
+        self._touch('__init__.py', self.pkg_dir)
+        linked_pkg = os.path.join(self.dist_dir, 'lpkg')
+        os.symlink('pkg', linked_pkg)
+        assert os.path.isdir(linked_pkg)
+        packages = find_packages(self.dist_dir)
+        assert 'lpkg' in packages
+
+    def _assert_packages(self, actual, expected):
+        assert set(actual) == set(expected)
+
+    def test_pep420_ns_package(self):
+        packages = find_420_packages(
+            self.dist_dir, include=['pkg*'], exclude=['pkg.subpkg.assets'])
+        self._assert_packages(packages, ['pkg', 'pkg.nspkg', 'pkg.subpkg'])
+
+    def test_pep420_ns_package_no_includes(self):
+        packages = find_420_packages(
+            self.dist_dir, exclude=['pkg.subpkg.assets'])
+        self._assert_packages(packages, ['docs', 'pkg', 'pkg.nspkg', 'pkg.subpkg'])
+
+    def test_pep420_ns_package_no_includes_or_excludes(self):
+        packages = find_420_packages(self.dist_dir)
+        expected = [
+            'docs', 'pkg', 'pkg.nspkg', 'pkg.subpkg', 'pkg.subpkg.assets']
+        self._assert_packages(packages, expected)
+
+    def test_regular_package_with_nested_pep420_ns_packages(self):
+        self._touch('__init__.py', self.pkg_dir)
+        packages = find_420_packages(
+            self.dist_dir, exclude=['docs', 'pkg.subpkg.assets'])
+        self._assert_packages(packages, ['pkg', 'pkg.nspkg', 'pkg.subpkg'])
+
+    def test_pep420_ns_package_no_non_package_dirs(self):
+        shutil.rmtree(self.docs_dir)
+        shutil.rmtree(os.path.join(self.dist_dir, 'pkg/subpkg/assets'))
+        packages = find_420_packages(self.dist_dir)
+        self._assert_packages(packages, ['pkg', 'pkg.nspkg', 'pkg.subpkg'])
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_install_scripts.py b/vendor/setuptools-39.0.1/setuptools/tests/test_install_scripts.py
new file mode 100644
index 00000000..7393241f
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_install_scripts.py
@@ -0,0 +1,88 @@
+"""install_scripts tests
+"""
+
+import io
+import sys
+
+import pytest
+
+from setuptools.command.install_scripts import install_scripts
+from setuptools.dist import Distribution
+from . import contexts
+
+
+class TestInstallScripts:
+    settings = dict(
+        name='foo',
+        entry_points={'console_scripts': ['foo=foo:foo']},
+        version='0.0',
+    )
+    unix_exe = '/usr/dummy-test-path/local/bin/python'
+    unix_spaces_exe = '/usr/bin/env dummy-test-python'
+    win32_exe = 'C:\\Dummy Test Path\\Program Files\\Python 3.3\\python.exe'
+
+    def _run_install_scripts(self, install_dir, executable=None):
+        dist = Distribution(self.settings)
+        dist.script_name = 'setup.py'
+        cmd = install_scripts(dist)
+        cmd.install_dir = install_dir
+        if executable is not None:
+            bs = cmd.get_finalized_command('build_scripts')
+            bs.executable = executable
+        cmd.ensure_finalized()
+        with contexts.quiet():
+            cmd.run()
+
+    @pytest.mark.skipif(sys.platform == 'win32', reason='non-Windows only')
+    def test_sys_executable_escaping_unix(self, tmpdir, monkeypatch):
+        """
+        Ensure that shebang is not quoted on Unix when getting the Python exe
+        from sys.executable.
+        """
+        expected = '#!%s\n' % self.unix_exe
+        monkeypatch.setattr('sys.executable', self.unix_exe)
+        with tmpdir.as_cwd():
+            self._run_install_scripts(str(tmpdir))
+            with io.open(str(tmpdir.join('foo')), 'r') as f:
+                actual = f.readline()
+        assert actual == expected
+
+    @pytest.mark.skipif(sys.platform != 'win32', reason='Windows only')
+    def test_sys_executable_escaping_win32(self, tmpdir, monkeypatch):
+        """
+        Ensure that shebang is quoted on Windows when getting the Python exe
+        from sys.executable and it contains a space.
+        """
+        expected = '#!"%s"\n' % self.win32_exe
+        monkeypatch.setattr('sys.executable', self.win32_exe)
+        with tmpdir.as_cwd():
+            self._run_install_scripts(str(tmpdir))
+            with io.open(str(tmpdir.join('foo-script.py')), 'r') as f:
+                actual = f.readline()
+        assert actual == expected
+
+    @pytest.mark.skipif(sys.platform == 'win32', reason='non-Windows only')
+    def test_executable_with_spaces_escaping_unix(self, tmpdir):
+        """
+        Ensure that shebang on Unix is not quoted, even when a value with spaces
+        is specified using --executable.
+        """
+        expected = '#!%s\n' % self.unix_spaces_exe
+        with tmpdir.as_cwd():
+            self._run_install_scripts(str(tmpdir), self.unix_spaces_exe)
+            with io.open(str(tmpdir.join('foo')), 'r') as f:
+                actual = f.readline()
+        assert actual == expected
+
+    @pytest.mark.skipif(sys.platform != 'win32', reason='Windows only')
+    def test_executable_arg_escaping_win32(self, tmpdir):
+        """
+        Ensure that shebang on Windows is quoted when getting a path with spaces
+        from --executable, that is itself properly quoted.
+        """
+        expected = '#!"%s"\n' % self.win32_exe
+        with tmpdir.as_cwd():
+            self._run_install_scripts(str(tmpdir), '"' + self.win32_exe + '"')
+            with io.open(str(tmpdir.join('foo-script.py')), 'r') as f:
+                actual = f.readline()
+        assert actual == expected
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_integration.py b/vendor/setuptools-39.0.1/setuptools/tests/test_integration.py
new file mode 100644
index 00000000..3a9a6c50
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_integration.py
@@ -0,0 +1,165 @@
+"""Run some integration tests.
+
+Try to install a few packages.
+"""
+
+import glob
+import os
+import sys
+
+from setuptools.extern.six.moves import urllib
+import pytest
+
+from setuptools.command.easy_install import easy_install
+from setuptools.command import easy_install as easy_install_pkg
+from setuptools.dist import Distribution
+
+
+def setup_module(module):
+    packages = 'stevedore', 'virtualenvwrapper', 'pbr', 'novaclient'
+    for pkg in packages:
+        try:
+            __import__(pkg)
+            tmpl = "Integration tests cannot run when {pkg} is installed"
+            pytest.skip(tmpl.format(**locals()))
+        except ImportError:
+            pass
+
+    try:
+        urllib.request.urlopen('https://pypi.python.org/pypi')
+    except Exception as exc:
+        pytest.skip(str(exc))
+
+
+@pytest.fixture
+def install_context(request, tmpdir, monkeypatch):
+    """Fixture to set up temporary installation directory.
+    """
+    # Save old values so we can restore them.
+    new_cwd = tmpdir.mkdir('cwd')
+    user_base = tmpdir.mkdir('user_base')
+    user_site = tmpdir.mkdir('user_site')
+    install_dir = tmpdir.mkdir('install_dir')
+
+    def fin():
+        # undo the monkeypatch, particularly needed under
+        # windows because of kept handle on cwd
+        monkeypatch.undo()
+        new_cwd.remove()
+        user_base.remove()
+        user_site.remove()
+        install_dir.remove()
+
+    request.addfinalizer(fin)
+
+    # Change the environment and site settings to control where the
+    # files are installed and ensure we do not overwrite anything.
+    monkeypatch.chdir(new_cwd)
+    monkeypatch.setattr(easy_install_pkg, '__file__', user_site.strpath)
+    monkeypatch.setattr('site.USER_BASE', user_base.strpath)
+    monkeypatch.setattr('site.USER_SITE', user_site.strpath)
+    monkeypatch.setattr('sys.path', sys.path + [install_dir.strpath])
+    monkeypatch.setenv('PYTHONPATH', os.path.pathsep.join(sys.path))
+
+    # Set up the command for performing the installation.
+    dist = Distribution()
+    cmd = easy_install(dist)
+    cmd.install_dir = install_dir.strpath
+    return cmd
+
+
+def _install_one(requirement, cmd, pkgname, modulename):
+    cmd.args = [requirement]
+    cmd.ensure_finalized()
+    cmd.run()
+    target = cmd.install_dir
+    dest_path = glob.glob(os.path.join(target, pkgname + '*.egg'))
+    assert dest_path
+    assert os.path.exists(os.path.join(dest_path[0], pkgname, modulename))
+
+
+def test_stevedore(install_context):
+    _install_one('stevedore', install_context,
+                 'stevedore', 'extension.py')
+
+
+@pytest.mark.xfail
+def test_virtualenvwrapper(install_context):
+    _install_one('virtualenvwrapper', install_context,
+                 'virtualenvwrapper', 'hook_loader.py')
+
+
+def test_pbr(install_context):
+    _install_one('pbr', install_context,
+                 'pbr', 'core.py')
+
+
+@pytest.mark.xfail
+def test_python_novaclient(install_context):
+    _install_one('python-novaclient', install_context,
+                 'novaclient', 'base.py')
+
+
+def test_pyuri(install_context):
+    """
+    Install the pyuri package (version 0.3.1 at the time of writing).
+
+    This is also a regression test for issue #1016.
+    """
+    _install_one('pyuri', install_context, 'pyuri', 'uri.py')
+
+    pyuri = install_context.installed_projects['pyuri']
+
+    # The package data should be installed.
+    assert os.path.exists(os.path.join(pyuri.location, 'pyuri', 'uri.regex'))
+
+
+import re
+import subprocess
+import functools
+import tarfile, zipfile
+
+
+build_deps = ['appdirs', 'packaging', 'pyparsing', 'six']
+@pytest.mark.parametrize("build_dep", build_deps)
+@pytest.mark.skipif(sys.version_info < (3, 6), reason='run only on late versions')
+def test_build_deps_on_distutils(request, tmpdir_factory, build_dep):
+    """
+    All setuptools build dependencies must build without
+    setuptools.
+    """
+    if 'pyparsing' in build_dep:
+        pytest.xfail(reason="Project imports setuptools unconditionally")
+    build_target = tmpdir_factory.mktemp('source')
+    build_dir = download_and_extract(request, build_dep, build_target)
+    install_target = tmpdir_factory.mktemp('target')
+    output = install(build_dir, install_target)
+    for line in output.splitlines():
+        match = re.search('Unknown distribution option: (.*)', line)
+        allowed_unknowns = [
+            'test_suite',
+            'tests_require',
+            'install_requires',
+        ]
+        assert not match or match.group(1).strip('"\'') in allowed_unknowns
+
+
+def install(pkg_dir, install_dir):
+    with open(os.path.join(pkg_dir, 'setuptools.py'), 'w') as breaker:
+        breaker.write('raise ImportError()')
+    cmd = [sys.executable, 'setup.py', 'install', '--prefix', install_dir]
+    env = dict(os.environ, PYTHONPATH=pkg_dir)
+    output = subprocess.check_output(cmd, cwd=pkg_dir, env=env, stderr=subprocess.STDOUT)
+    return output.decode('utf-8')
+
+
+def download_and_extract(request, req, target):
+    cmd = [sys.executable, '-m', 'pip', 'download', '--no-deps',
+        '--no-binary', ':all:', req]
+    output = subprocess.check_output(cmd, encoding='utf-8')
+    filename = re.search('Saved (.*)', output).group(1)
+    request.addfinalizer(functools.partial(os.remove, filename))
+    opener = zipfile.ZipFile if filename.endswith('.zip') else tarfile.open
+    with opener(filename) as archive:
+        archive.extractall(target)
+    return os.path.join(target, os.listdir(target)[0])
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_manifest.py b/vendor/setuptools-39.0.1/setuptools/tests/test_manifest.py
new file mode 100644
index 00000000..65eec7d9
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_manifest.py
@@ -0,0 +1,602 @@
+# -*- coding: utf-8 -*-
+"""sdist tests"""
+
+import contextlib
+import os
+import shutil
+import sys
+import tempfile
+import itertools
+from distutils import log
+from distutils.errors import DistutilsTemplateError
+
+import pkg_resources.py31compat
+from setuptools.command.egg_info import FileList, egg_info, translate_pattern
+from setuptools.dist import Distribution
+from setuptools.extern import six
+from setuptools.tests.textwrap import DALS
+
+import pytest
+
+py3_only = pytest.mark.xfail(six.PY2, reason="Test runs on Python 3 only")
+
+
+def make_local_path(s):
+    """Converts '/' in a string to os.sep"""
+    return s.replace('/', os.sep)
+
+
+SETUP_ATTRS = {
+    'name': 'app',
+    'version': '0.0',
+    'packages': ['app'],
+}
+
+SETUP_PY = """\
+from setuptools import setup
+
+setup(**%r)
+""" % SETUP_ATTRS
+
+
+@contextlib.contextmanager
+def quiet():
+    old_stdout, old_stderr = sys.stdout, sys.stderr
+    sys.stdout, sys.stderr = six.StringIO(), six.StringIO()
+    try:
+        yield
+    finally:
+        sys.stdout, sys.stderr = old_stdout, old_stderr
+
+
+def touch(filename):
+    open(filename, 'w').close()
+
+
+# The set of files always in the manifest, including all files in the
+# .egg-info directory
+default_files = frozenset(map(make_local_path, [
+    'README.rst',
+    'MANIFEST.in',
+    'setup.py',
+    'app.egg-info/PKG-INFO',
+    'app.egg-info/SOURCES.txt',
+    'app.egg-info/dependency_links.txt',
+    'app.egg-info/top_level.txt',
+    'app/__init__.py',
+]))
+
+
+translate_specs = [
+    ('foo', ['foo'], ['bar', 'foobar']),
+    ('foo/bar', ['foo/bar'], ['foo/bar/baz', './foo/bar', 'foo']),
+
+    # Glob matching
+    ('*.txt', ['foo.txt', 'bar.txt'], ['foo/foo.txt']),
+    ('dir/*.txt', ['dir/foo.txt', 'dir/bar.txt', 'dir/.txt'], ['notdir/foo.txt']),
+    ('*/*.py', ['bin/start.py'], []),
+    ('docs/page-?.txt', ['docs/page-9.txt'], ['docs/page-10.txt']),
+
+    # Globstars change what they mean depending upon where they are
+    (
+        'foo/**/bar',
+        ['foo/bing/bar', 'foo/bing/bang/bar', 'foo/bar'],
+        ['foo/abar'],
+    ),
+    (
+        'foo/**',
+        ['foo/bar/bing.py', 'foo/x'],
+        ['/foo/x'],
+    ),
+    (
+        '**',
+        ['x', 'abc/xyz', '@nything'],
+        [],
+    ),
+
+    # Character classes
+    (
+        'pre[one]post',
+        ['preopost', 'prenpost', 'preepost'],
+        ['prepost', 'preonepost'],
+    ),
+
+    (
+        'hello[!one]world',
+        ['helloxworld', 'helloyworld'],
+        ['hellooworld', 'helloworld', 'hellooneworld'],
+    ),
+
+    (
+        '[]one].txt',
+        ['o.txt', '].txt', 'e.txt'],
+        ['one].txt'],
+    ),
+
+    (
+        'foo[!]one]bar',
+        ['fooybar'],
+        ['foo]bar', 'fooobar', 'fooebar'],
+    ),
+
+]
+"""
+A spec of inputs for 'translate_pattern' and matches and mismatches
+for that input.
+"""
+
+match_params = itertools.chain.from_iterable(
+    zip(itertools.repeat(pattern), matches)
+    for pattern, matches, mismatches in translate_specs
+)
+
+
+@pytest.fixture(params=match_params)
+def pattern_match(request):
+    return map(make_local_path, request.param)
+
+
+mismatch_params = itertools.chain.from_iterable(
+    zip(itertools.repeat(pattern), mismatches)
+    for pattern, matches, mismatches in translate_specs
+)
+
+
+@pytest.fixture(params=mismatch_params)
+def pattern_mismatch(request):
+    return map(make_local_path, request.param)
+
+
+def test_translated_pattern_match(pattern_match):
+    pattern, target = pattern_match
+    assert translate_pattern(pattern).match(target)
+
+
+def test_translated_pattern_mismatch(pattern_mismatch):
+    pattern, target = pattern_mismatch
+    assert not translate_pattern(pattern).match(target)
+
+
+class TempDirTestCase(object):
+    def setup_method(self, method):
+        self.temp_dir = tempfile.mkdtemp()
+        self.old_cwd = os.getcwd()
+        os.chdir(self.temp_dir)
+
+    def teardown_method(self, method):
+        os.chdir(self.old_cwd)
+        shutil.rmtree(self.temp_dir)
+
+
+class TestManifestTest(TempDirTestCase):
+    def setup_method(self, method):
+        super(TestManifestTest, self).setup_method(method)
+
+        f = open(os.path.join(self.temp_dir, 'setup.py'), 'w')
+        f.write(SETUP_PY)
+        f.close()
+        """
+        Create a file tree like:
+        - LICENSE
+        - README.rst
+        - testing.rst
+        - .hidden.rst
+        - app/
+            - __init__.py
+            - a.txt
+            - b.txt
+            - c.rst
+            - static/
+                - app.js
+                - app.js.map
+                - app.css
+                - app.css.map
+        """
+
+        for fname in ['README.rst', '.hidden.rst', 'testing.rst', 'LICENSE']:
+            touch(os.path.join(self.temp_dir, fname))
+
+        # Set up the rest of the test package
+        test_pkg = os.path.join(self.temp_dir, 'app')
+        os.mkdir(test_pkg)
+        for fname in ['__init__.py', 'a.txt', 'b.txt', 'c.rst']:
+            touch(os.path.join(test_pkg, fname))
+
+        # Some compiled front-end assets to include
+        static = os.path.join(test_pkg, 'static')
+        os.mkdir(static)
+        for fname in ['app.js', 'app.js.map', 'app.css', 'app.css.map']:
+            touch(os.path.join(static, fname))
+
+    def make_manifest(self, contents):
+        """Write a MANIFEST.in."""
+        with open(os.path.join(self.temp_dir, 'MANIFEST.in'), 'w') as f:
+            f.write(DALS(contents))
+
+    def get_files(self):
+        """Run egg_info and get all the files to include, as a set"""
+        dist = Distribution(SETUP_ATTRS)
+        dist.script_name = 'setup.py'
+        cmd = egg_info(dist)
+        cmd.ensure_finalized()
+
+        cmd.run()
+
+        return set(cmd.filelist.files)
+
+    def test_no_manifest(self):
+        """Check a missing MANIFEST.in includes only the standard files."""
+        assert (default_files - set(['MANIFEST.in'])) == self.get_files()
+
+    def test_empty_files(self):
+        """Check an empty MANIFEST.in includes only the standard files."""
+        self.make_manifest("")
+        assert default_files == self.get_files()
+
+    def test_include(self):
+        """Include extra rst files in the project root."""
+        self.make_manifest("include *.rst")
+        files = default_files | set([
+            'testing.rst', '.hidden.rst'])
+        assert files == self.get_files()
+
+    def test_exclude(self):
+        """Include everything in app/ except the text files"""
+        l = make_local_path
+        self.make_manifest(
+            """
+            include app/*
+            exclude app/*.txt
+            """)
+        files = default_files | set([l('app/c.rst')])
+        assert files == self.get_files()
+
+    def test_include_multiple(self):
+        """Include with multiple patterns."""
+        l = make_local_path
+        self.make_manifest("include app/*.txt app/static/*")
+        files = default_files | set([
+            l('app/a.txt'), l('app/b.txt'),
+            l('app/static/app.js'), l('app/static/app.js.map'),
+            l('app/static/app.css'), l('app/static/app.css.map')])
+        assert files == self.get_files()
+
+    def test_graft(self):
+        """Include the whole app/static/ directory."""
+        l = make_local_path
+        self.make_manifest("graft app/static")
+        files = default_files | set([
+            l('app/static/app.js'), l('app/static/app.js.map'),
+            l('app/static/app.css'), l('app/static/app.css.map')])
+        assert files == self.get_files()
+
+    def test_graft_glob_syntax(self):
+        """Include the whole app/static/ directory."""
+        l = make_local_path
+        self.make_manifest("graft */static")
+        files = default_files | set([
+            l('app/static/app.js'), l('app/static/app.js.map'),
+            l('app/static/app.css'), l('app/static/app.css.map')])
+        assert files == self.get_files()
+
+    def test_graft_global_exclude(self):
+        """Exclude all *.map files in the project."""
+        l = make_local_path
+        self.make_manifest(
+            """
+            graft app/static
+            global-exclude *.map
+            """)
+        files = default_files | set([
+            l('app/static/app.js'), l('app/static/app.css')])
+        assert files == self.get_files()
+
+    def test_global_include(self):
+        """Include all *.rst, *.js, and *.css files in the whole tree."""
+        l = make_local_path
+        self.make_manifest(
+            """
+            global-include *.rst *.js *.css
+            """)
+        files = default_files | set([
+            '.hidden.rst', 'testing.rst', l('app/c.rst'),
+            l('app/static/app.js'), l('app/static/app.css')])
+        assert files == self.get_files()
+
+    def test_graft_prune(self):
+        """Include all files in app/, except for the whole app/static/ dir."""
+        l = make_local_path
+        self.make_manifest(
+            """
+            graft app
+            prune app/static
+            """)
+        files = default_files | set([
+            l('app/a.txt'), l('app/b.txt'), l('app/c.rst')])
+        assert files == self.get_files()
+
+
+class TestFileListTest(TempDirTestCase):
+    """
+    A copy of the relevant bits of distutils/tests/test_filelist.py,
+    to ensure setuptools' version of FileList keeps parity with distutils.
+    """
+
+    def setup_method(self, method):
+        super(TestFileListTest, self).setup_method(method)
+        self.threshold = log.set_threshold(log.FATAL)
+        self._old_log = log.Log._log
+        log.Log._log = self._log
+        self.logs = []
+
+    def teardown_method(self, method):
+        log.set_threshold(self.threshold)
+        log.Log._log = self._old_log
+        super(TestFileListTest, self).teardown_method(method)
+
+    def _log(self, level, msg, args):
+        if level not in (log.DEBUG, log.INFO, log.WARN, log.ERROR, log.FATAL):
+            raise ValueError('%s wrong log level' % str(level))
+        self.logs.append((level, msg, args))
+
+    def get_logs(self, *levels):
+        def _format(msg, args):
+            if len(args) == 0:
+                return msg
+            return msg % args
+        return [_format(msg, args) for level, msg, args
+                in self.logs if level in levels]
+
+    def clear_logs(self):
+        self.logs = []
+
+    def assertNoWarnings(self):
+        assert self.get_logs(log.WARN) == []
+        self.clear_logs()
+
+    def assertWarnings(self):
+        assert len(self.get_logs(log.WARN)) > 0
+        self.clear_logs()
+
+    def make_files(self, files):
+        for file in files:
+            file = os.path.join(self.temp_dir, file)
+            dirname, basename = os.path.split(file)
+            pkg_resources.py31compat.makedirs(dirname, exist_ok=True)
+            open(file, 'w').close()
+
+    def test_process_template_line(self):
+        # testing  all MANIFEST.in template patterns
+        file_list = FileList()
+        l = make_local_path
+
+        # simulated file list
+        self.make_files([
+            'foo.tmp', 'ok', 'xo', 'four.txt',
+            'buildout.cfg',
+            # filelist does not filter out VCS directories,
+            # it's sdist that does
+            l('.hg/last-message.txt'),
+            l('global/one.txt'),
+            l('global/two.txt'),
+            l('global/files.x'),
+            l('global/here.tmp'),
+            l('f/o/f.oo'),
+            l('dir/graft-one'),
+            l('dir/dir2/graft2'),
+            l('dir3/ok'),
+            l('dir3/sub/ok.txt'),
+        ])
+
+        MANIFEST_IN = DALS("""\
+        include ok
+        include xo
+        exclude xo
+        include foo.tmp
+        include buildout.cfg
+        global-include *.x
+        global-include *.txt
+        global-exclude *.tmp
+        recursive-include f *.oo
+        recursive-exclude global *.x
+        graft dir
+        prune dir3
+        """)
+
+        for line in MANIFEST_IN.split('\n'):
+            if not line:
+                continue
+            file_list.process_template_line(line)
+
+        wanted = [
+            'buildout.cfg',
+            'four.txt',
+            'ok',
+            l('.hg/last-message.txt'),
+            l('dir/graft-one'),
+            l('dir/dir2/graft2'),
+            l('f/o/f.oo'),
+            l('global/one.txt'),
+            l('global/two.txt'),
+        ]
+
+        file_list.sort()
+        assert file_list.files == wanted
+
+    def test_exclude_pattern(self):
+        # return False if no match
+        file_list = FileList()
+        assert not file_list.exclude_pattern('*.py')
+
+        # return True if files match
+        file_list = FileList()
+        file_list.files = ['a.py', 'b.py']
+        assert file_list.exclude_pattern('*.py')
+
+        # test excludes
+        file_list = FileList()
+        file_list.files = ['a.py', 'a.txt']
+        file_list.exclude_pattern('*.py')
+        file_list.sort()
+        assert file_list.files == ['a.txt']
+
+    def test_include_pattern(self):
+        # return False if no match
+        file_list = FileList()
+        self.make_files([])
+        assert not file_list.include_pattern('*.py')
+
+        # return True if files match
+        file_list = FileList()
+        self.make_files(['a.py', 'b.txt'])
+        assert file_list.include_pattern('*.py')
+
+        # test * matches all files
+        file_list = FileList()
+        self.make_files(['a.py', 'b.txt'])
+        file_list.include_pattern('*')
+        file_list.sort()
+        assert file_list.files == ['a.py', 'b.txt']
+
+    def test_process_template_line_invalid(self):
+        # invalid lines
+        file_list = FileList()
+        for action in ('include', 'exclude', 'global-include',
+                       'global-exclude', 'recursive-include',
+                       'recursive-exclude', 'graft', 'prune', 'blarg'):
+            try:
+                file_list.process_template_line(action)
+            except DistutilsTemplateError:
+                pass
+            except Exception:
+                assert False, "Incorrect error thrown"
+            else:
+                assert False, "Should have thrown an error"
+
+    def test_include(self):
+        l = make_local_path
+        # include
+        file_list = FileList()
+        self.make_files(['a.py', 'b.txt', l('d/c.py')])
+
+        file_list.process_template_line('include *.py')
+        file_list.sort()
+        assert file_list.files == ['a.py']
+        self.assertNoWarnings()
+
+        file_list.process_template_line('include *.rb')
+        file_list.sort()
+        assert file_list.files == ['a.py']
+        self.assertWarnings()
+
+    def test_exclude(self):
+        l = make_local_path
+        # exclude
+        file_list = FileList()
+        file_list.files = ['a.py', 'b.txt', l('d/c.py')]
+
+        file_list.process_template_line('exclude *.py')
+        file_list.sort()
+        assert file_list.files == ['b.txt', l('d/c.py')]
+        self.assertNoWarnings()
+
+        file_list.process_template_line('exclude *.rb')
+        file_list.sort()
+        assert file_list.files == ['b.txt', l('d/c.py')]
+        self.assertWarnings()
+
+    def test_global_include(self):
+        l = make_local_path
+        # global-include
+        file_list = FileList()
+        self.make_files(['a.py', 'b.txt', l('d/c.py')])
+
+        file_list.process_template_line('global-include *.py')
+        file_list.sort()
+        assert file_list.files == ['a.py', l('d/c.py')]
+        self.assertNoWarnings()
+
+        file_list.process_template_line('global-include *.rb')
+        file_list.sort()
+        assert file_list.files == ['a.py', l('d/c.py')]
+        self.assertWarnings()
+
+    def test_global_exclude(self):
+        l = make_local_path
+        # global-exclude
+        file_list = FileList()
+        file_list.files = ['a.py', 'b.txt', l('d/c.py')]
+
+        file_list.process_template_line('global-exclude *.py')
+        file_list.sort()
+        assert file_list.files == ['b.txt']
+        self.assertNoWarnings()
+
+        file_list.process_template_line('global-exclude *.rb')
+        file_list.sort()
+        assert file_list.files == ['b.txt']
+        self.assertWarnings()
+
+    def test_recursive_include(self):
+        l = make_local_path
+        # recursive-include
+        file_list = FileList()
+        self.make_files(['a.py', l('d/b.py'), l('d/c.txt'), l('d/d/e.py')])
+
+        file_list.process_template_line('recursive-include d *.py')
+        file_list.sort()
+        assert file_list.files == [l('d/b.py'), l('d/d/e.py')]
+        self.assertNoWarnings()
+
+        file_list.process_template_line('recursive-include e *.py')
+        file_list.sort()
+        assert file_list.files == [l('d/b.py'), l('d/d/e.py')]
+        self.assertWarnings()
+
+    def test_recursive_exclude(self):
+        l = make_local_path
+        # recursive-exclude
+        file_list = FileList()
+        file_list.files = ['a.py', l('d/b.py'), l('d/c.txt'), l('d/d/e.py')]
+
+        file_list.process_template_line('recursive-exclude d *.py')
+        file_list.sort()
+        assert file_list.files == ['a.py', l('d/c.txt')]
+        self.assertNoWarnings()
+
+        file_list.process_template_line('recursive-exclude e *.py')
+        file_list.sort()
+        assert file_list.files == ['a.py', l('d/c.txt')]
+        self.assertWarnings()
+
+    def test_graft(self):
+        l = make_local_path
+        # graft
+        file_list = FileList()
+        self.make_files(['a.py', l('d/b.py'), l('d/d/e.py'), l('f/f.py')])
+
+        file_list.process_template_line('graft d')
+        file_list.sort()
+        assert file_list.files == [l('d/b.py'), l('d/d/e.py')]
+        self.assertNoWarnings()
+
+        file_list.process_template_line('graft e')
+        file_list.sort()
+        assert file_list.files == [l('d/b.py'), l('d/d/e.py')]
+        self.assertWarnings()
+
+    def test_prune(self):
+        l = make_local_path
+        # prune
+        file_list = FileList()
+        file_list.files = ['a.py', l('d/b.py'), l('d/d/e.py'), l('f/f.py')]
+
+        file_list.process_template_line('prune d')
+        file_list.sort()
+        assert file_list.files == ['a.py', l('f/f.py')]
+        self.assertNoWarnings()
+
+        file_list.process_template_line('prune e')
+        file_list.sort()
+        assert file_list.files == ['a.py', l('f/f.py')]
+        self.assertWarnings()
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_msvc.py b/vendor/setuptools-39.0.1/setuptools/tests/test_msvc.py
new file mode 100644
index 00000000..32d7a907
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_msvc.py
@@ -0,0 +1,178 @@
+"""
+Tests for msvc support module.
+"""
+
+import os
+import contextlib
+import distutils.errors
+import mock
+
+import pytest
+
+from . import contexts
+
+# importing only setuptools should apply the patch
+__import__('setuptools')
+
+pytest.importorskip("distutils.msvc9compiler")
+
+
+def mock_reg(hkcu=None, hklm=None):
+    """
+    Return a mock for distutils.msvc9compiler.Reg, patched
+    to mock out the functions that access the registry.
+    """
+
+    _winreg = getattr(distutils.msvc9compiler, '_winreg', None)
+    winreg = getattr(distutils.msvc9compiler, 'winreg', _winreg)
+
+    hives = {
+        winreg.HKEY_CURRENT_USER: hkcu or {},
+        winreg.HKEY_LOCAL_MACHINE: hklm or {},
+    }
+
+    @classmethod
+    def read_keys(cls, base, key):
+        """Return list of registry keys."""
+        hive = hives.get(base, {})
+        return [
+            k.rpartition('\\')[2]
+            for k in hive if k.startswith(key.lower())
+        ]
+
+    @classmethod
+    def read_values(cls, base, key):
+        """Return dict of registry keys and values."""
+        hive = hives.get(base, {})
+        return dict(
+            (k.rpartition('\\')[2], hive[k])
+            for k in hive if k.startswith(key.lower())
+        )
+
+    return mock.patch.multiple(distutils.msvc9compiler.Reg,
+        read_keys=read_keys, read_values=read_values)
+
+
+class TestModulePatch:
+    """
+    Ensure that importing setuptools is sufficient to replace
+    the standard find_vcvarsall function with a version that
+    recognizes the "Visual C++ for Python" package.
+    """
+
+    key_32 = r'software\microsoft\devdiv\vcforpython\9.0\installdir'
+    key_64 = r'software\wow6432node\microsoft\devdiv\vcforpython\9.0\installdir'
+
+    def test_patched(self):
+        "Test the module is actually patched"
+        mod_name = distutils.msvc9compiler.find_vcvarsall.__module__
+        assert mod_name == "setuptools.msvc", "find_vcvarsall unpatched"
+
+    def test_no_registry_entries_means_nothing_found(self):
+        """
+        No registry entries or environment variable should lead to an error
+        directing the user to download vcpython27.
+        """
+        find_vcvarsall = distutils.msvc9compiler.find_vcvarsall
+        query_vcvarsall = distutils.msvc9compiler.query_vcvarsall
+
+        with contexts.environment(VS90COMNTOOLS=None):
+            with mock_reg():
+                assert find_vcvarsall(9.0) is None
+
+                try:
+                    query_vcvarsall(9.0)
+                except Exception as exc:
+                    expected = distutils.errors.DistutilsPlatformError
+                    assert isinstance(exc, expected)
+                    assert 'aka.ms/vcpython27' in str(exc)
+
+    @pytest.yield_fixture
+    def user_preferred_setting(self):
+        """
+        Set up environment with different install dirs for user vs. system
+        and yield the user_install_dir for the expected result.
+        """
+        with self.mock_install_dir() as user_install_dir:
+            with self.mock_install_dir() as system_install_dir:
+                reg = mock_reg(
+                    hkcu={
+                        self.key_32: user_install_dir,
+                    },
+                    hklm={
+                        self.key_32: system_install_dir,
+                        self.key_64: system_install_dir,
+                    },
+                )
+                with reg:
+                    yield user_install_dir
+
+    def test_prefer_current_user(self, user_preferred_setting):
+        """
+        Ensure user's settings are preferred.
+        """
+        result = distutils.msvc9compiler.find_vcvarsall(9.0)
+        expected = os.path.join(user_preferred_setting, 'vcvarsall.bat')
+        assert expected == result
+
+    @pytest.yield_fixture
+    def local_machine_setting(self):
+        """
+        Set up environment with only the system environment configured.
+        """
+        with self.mock_install_dir() as system_install_dir:
+            reg = mock_reg(
+                hklm={
+                    self.key_32: system_install_dir,
+                },
+            )
+            with reg:
+                yield system_install_dir
+
+    def test_local_machine_recognized(self, local_machine_setting):
+        """
+        Ensure machine setting is honored if user settings are not present.
+        """
+        result = distutils.msvc9compiler.find_vcvarsall(9.0)
+        expected = os.path.join(local_machine_setting, 'vcvarsall.bat')
+        assert expected == result
+
+    @pytest.yield_fixture
+    def x64_preferred_setting(self):
+        """
+        Set up environment with 64-bit and 32-bit system settings configured
+        and yield the canonical location.
+        """
+        with self.mock_install_dir() as x32_dir:
+            with self.mock_install_dir() as x64_dir:
+                reg = mock_reg(
+                    hklm={
+                        # This *should* only exist on 32-bit machines
+                        self.key_32: x32_dir,
+                        # This *should* only exist on 64-bit machines
+                        self.key_64: x64_dir,
+                    },
+                )
+                with reg:
+                    yield x32_dir
+
+    def test_ensure_64_bit_preferred(self, x64_preferred_setting):
+        """
+        Ensure 64-bit system key is preferred.
+        """
+        result = distutils.msvc9compiler.find_vcvarsall(9.0)
+        expected = os.path.join(x64_preferred_setting, 'vcvarsall.bat')
+        assert expected == result
+
+    @staticmethod
+    @contextlib.contextmanager
+    def mock_install_dir():
+        """
+        Make a mock install dir in a unique location so that tests can
+        distinguish which dir was detected in a given scenario.
+        """
+        with contexts.tempdir() as result:
+            vcvarsall = os.path.join(result, 'vcvarsall.bat')
+            with open(vcvarsall, 'w'):
+                pass
+            yield result
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_namespaces.py b/vendor/setuptools-39.0.1/setuptools/tests/test_namespaces.py
new file mode 100644
index 00000000..1ac1b35e
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_namespaces.py
@@ -0,0 +1,111 @@
+from __future__ import absolute_import, unicode_literals
+
+import os
+import sys
+import subprocess
+
+import pytest
+
+from . import namespaces
+from setuptools.command import test
+
+
+class TestNamespaces:
+
+    @pytest.mark.xfail(sys.version_info < (3, 5),
+        reason="Requires importlib.util.module_from_spec")
+    @pytest.mark.skipif(bool(os.environ.get("APPVEYOR")),
+        reason="https://github.com/pypa/setuptools/issues/851")
+    def test_mixed_site_and_non_site(self, tmpdir):
+        """
+        Installing two packages sharing the same namespace, one installed
+        to a site dir and the other installed just to a path on PYTHONPATH
+        should leave the namespace in tact and both packages reachable by
+        import.
+        """
+        pkg_A = namespaces.build_namespace_package(tmpdir, 'myns.pkgA')
+        pkg_B = namespaces.build_namespace_package(tmpdir, 'myns.pkgB')
+        site_packages = tmpdir / 'site-packages'
+        path_packages = tmpdir / 'path-packages'
+        targets = site_packages, path_packages
+        # use pip to install to the target directory
+        install_cmd = [
+            sys.executable,
+            '-m',
+            'pip.__main__',
+            'install',
+            str(pkg_A),
+            '-t', str(site_packages),
+        ]
+        subprocess.check_call(install_cmd)
+        namespaces.make_site_dir(site_packages)
+        install_cmd = [
+            sys.executable,
+            '-m',
+            'pip.__main__',
+            'install',
+            str(pkg_B),
+            '-t', str(path_packages),
+        ]
+        subprocess.check_call(install_cmd)
+        try_import = [
+            sys.executable,
+            '-c', 'import myns.pkgA; import myns.pkgB',
+        ]
+        with test.test.paths_on_pythonpath(map(str, targets)):
+            subprocess.check_call(try_import)
+
+    @pytest.mark.skipif(bool(os.environ.get("APPVEYOR")),
+        reason="https://github.com/pypa/setuptools/issues/851")
+    def test_pkg_resources_import(self, tmpdir):
+        """
+        Ensure that a namespace package doesn't break on import
+        of pkg_resources.
+        """
+        pkg = namespaces.build_namespace_package(tmpdir, 'myns.pkgA')
+        target = tmpdir / 'packages'
+        target.mkdir()
+        install_cmd = [
+            sys.executable,
+            '-m', 'easy_install',
+            '-d', str(target),
+            str(pkg),
+        ]
+        with test.test.paths_on_pythonpath([str(target)]):
+            subprocess.check_call(install_cmd)
+        namespaces.make_site_dir(target)
+        try_import = [
+            sys.executable,
+            '-c', 'import pkg_resources',
+        ]
+        with test.test.paths_on_pythonpath([str(target)]):
+            subprocess.check_call(try_import)
+
+    @pytest.mark.skipif(bool(os.environ.get("APPVEYOR")),
+        reason="https://github.com/pypa/setuptools/issues/851")
+    def test_namespace_package_installed_and_cwd(self, tmpdir):
+        """
+        Installing a namespace packages but also having it in the current
+        working directory, only one version should take precedence.
+        """
+        pkg_A = namespaces.build_namespace_package(tmpdir, 'myns.pkgA')
+        target = tmpdir / 'packages'
+        # use pip to install to the target directory
+        install_cmd = [
+            sys.executable,
+            '-m',
+            'pip.__main__',
+            'install',
+            str(pkg_A),
+            '-t', str(target),
+        ]
+        subprocess.check_call(install_cmd)
+        namespaces.make_site_dir(target)
+
+        # ensure that package imports and pkg_resources imports
+        pkg_resources_imp = [
+            sys.executable,
+            '-c', 'import pkg_resources; import myns.pkgA',
+        ]
+        with test.test.paths_on_pythonpath([str(target)]):
+            subprocess.check_call(pkg_resources_imp, cwd=str(pkg_A))
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_packageindex.py b/vendor/setuptools-39.0.1/setuptools/tests/test_packageindex.py
new file mode 100644
index 00000000..53e20d44
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_packageindex.py
@@ -0,0 +1,275 @@
+from __future__ import absolute_import
+
+import sys
+import os
+import distutils.errors
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import urllib, http_client
+
+import pkg_resources
+import setuptools.package_index
+from setuptools.tests.server import IndexServer
+from .textwrap import DALS
+
+
+class TestPackageIndex:
+    def test_regex(self):
+        hash_url = 'http://other_url?:action=show_md5&amp;'
+        hash_url += 'digest=0123456789abcdef0123456789abcdef'
+        doc = """
+            <a href="http://some_url">Name</a>
+            (<a title="MD5 hash"
+            href="{hash_url}">md5</a>)
+        """.lstrip().format(**locals())
+        assert setuptools.package_index.PYPI_MD5.match(doc)
+
+    def test_bad_url_bad_port(self):
+        index = setuptools.package_index.PackageIndex()
+        url = 'http://127.0.0.1:0/nonesuch/test_package_index'
+        try:
+            v = index.open_url(url)
+        except Exception as v:
+            assert url in str(v)
+        else:
+            assert isinstance(v, urllib.error.HTTPError)
+
+    def test_bad_url_typo(self):
+        # issue 16
+        # easy_install inquant.contentmirror.plone breaks because of a typo
+        # in its home URL
+        index = setuptools.package_index.PackageIndex(
+            hosts=('www.example.com',)
+        )
+
+        url = 'url:%20https://svn.plone.org/svn/collective/inquant.contentmirror.plone/trunk'
+        try:
+            v = index.open_url(url)
+        except Exception as v:
+            assert url in str(v)
+        else:
+            assert isinstance(v, urllib.error.HTTPError)
+
+    def test_bad_url_bad_status_line(self):
+        index = setuptools.package_index.PackageIndex(
+            hosts=('www.example.com',)
+        )
+
+        def _urlopen(*args):
+            raise http_client.BadStatusLine('line')
+
+        index.opener = _urlopen
+        url = 'http://example.com'
+        try:
+            v = index.open_url(url)
+        except Exception as v:
+            assert 'line' in str(v)
+        else:
+            raise AssertionError('Should have raise here!')
+
+    def test_bad_url_double_scheme(self):
+        """
+        A bad URL with a double scheme should raise a DistutilsError.
+        """
+        index = setuptools.package_index.PackageIndex(
+            hosts=('www.example.com',)
+        )
+
+        # issue 20
+        url = 'http://http://svn.pythonpaste.org/Paste/wphp/trunk'
+        try:
+            index.open_url(url)
+        except distutils.errors.DistutilsError as error:
+            msg = six.text_type(error)
+            assert 'nonnumeric port' in msg or 'getaddrinfo failed' in msg or 'Name or service not known' in msg
+            return
+        raise RuntimeError("Did not raise")
+
+    def test_bad_url_screwy_href(self):
+        index = setuptools.package_index.PackageIndex(
+            hosts=('www.example.com',)
+        )
+
+        # issue #160
+        if sys.version_info[0] == 2 and sys.version_info[1] == 7:
+            # this should not fail
+            url = 'http://example.com'
+            page = ('<a href="http://www.famfamfam.com]('
+                    'http://www.famfamfam.com/">')
+            index.process_index(url, page)
+
+    def test_url_ok(self):
+        index = setuptools.package_index.PackageIndex(
+            hosts=('www.example.com',)
+        )
+        url = 'file:///tmp/test_package_index'
+        assert index.url_ok(url, True)
+
+    def test_links_priority(self):
+        """
+        Download links from the pypi simple index should be used before
+        external download links.
+        https://bitbucket.org/tarek/distribute/issue/163
+
+        Usecase :
+        - someone uploads a package on pypi, a md5 is generated
+        - someone manually copies this link (with the md5 in the url) onto an
+          external page accessible from the package page.
+        - someone reuploads the package (with a different md5)
+        - while easy_installing, an MD5 error occurs because the external link
+          is used
+        -> Setuptools should use the link from pypi, not the external one.
+        """
+        if sys.platform.startswith('java'):
+            # Skip this test on jython because binding to :0 fails
+            return
+
+        # start an index server
+        server = IndexServer()
+        server.start()
+        index_url = server.base_url() + 'test_links_priority/simple/'
+
+        # scan a test index
+        pi = setuptools.package_index.PackageIndex(index_url)
+        requirement = pkg_resources.Requirement.parse('foobar')
+        pi.find_packages(requirement)
+        server.stop()
+
+        # the distribution has been found
+        assert 'foobar' in pi
+        # we have only one link, because links are compared without md5
+        assert len(pi['foobar']) == 1
+        # the link should be from the index
+        assert 'correct_md5' in pi['foobar'][0].location
+
+    def test_parse_bdist_wininst(self):
+        parse = setuptools.package_index.parse_bdist_wininst
+
+        actual = parse('reportlab-2.5.win32-py2.4.exe')
+        expected = 'reportlab-2.5', '2.4', 'win32'
+        assert actual == expected
+
+        actual = parse('reportlab-2.5.win32.exe')
+        expected = 'reportlab-2.5', None, 'win32'
+        assert actual == expected
+
+        actual = parse('reportlab-2.5.win-amd64-py2.7.exe')
+        expected = 'reportlab-2.5', '2.7', 'win-amd64'
+        assert actual == expected
+
+        actual = parse('reportlab-2.5.win-amd64.exe')
+        expected = 'reportlab-2.5', None, 'win-amd64'
+        assert actual == expected
+
+    def test__vcs_split_rev_from_url(self):
+        """
+        Test the basic usage of _vcs_split_rev_from_url
+        """
+        vsrfu = setuptools.package_index.PackageIndex._vcs_split_rev_from_url
+        url, rev = vsrfu('https://example.com/bar@2995')
+        assert url == 'https://example.com/bar'
+        assert rev == '2995'
+
+    def test_local_index(self, tmpdir):
+        """
+        local_open should be able to read an index from the file system.
+        """
+        index_file = tmpdir / 'index.html'
+        with index_file.open('w') as f:
+            f.write('<div>content</div>')
+        url = 'file:' + urllib.request.pathname2url(str(tmpdir)) + '/'
+        res = setuptools.package_index.local_open(url)
+        assert 'content' in res.read()
+
+    def test_egg_fragment(self):
+        """
+        EGG fragments must comply to PEP 440
+        """
+        epoch = [
+            '',
+            '1!',
+        ]
+        releases = [
+            '0',
+            '0.0',
+            '0.0.0',
+        ]
+        pre = [
+            'a0',
+            'b0',
+            'rc0',
+        ]
+        post = [
+            '.post0'
+        ]
+        dev = [
+            '.dev0',
+        ]
+        local = [
+            ('', ''),
+            ('+ubuntu.0', '+ubuntu.0'),
+            ('+ubuntu-0', '+ubuntu.0'),
+            ('+ubuntu_0', '+ubuntu.0'),
+        ]
+        versions = [
+            [''.join([e, r, p, l]) for l in ll]
+            for e in epoch
+            for r in releases
+            for p in sum([pre, post, dev], [''])
+            for ll in local]
+        for v, vc in versions:
+            dists = list(setuptools.package_index.distros_for_url(
+                'http://example.com/example.zip#egg=example-' + v))
+            assert dists[0].version == ''
+            assert dists[1].version == vc
+
+
+class TestContentCheckers:
+    def test_md5(self):
+        checker = setuptools.package_index.HashChecker.from_url(
+            'http://foo/bar#md5=f12895fdffbd45007040d2e44df98478')
+        checker.feed('You should probably not be using MD5'.encode('ascii'))
+        assert checker.hash.hexdigest() == 'f12895fdffbd45007040d2e44df98478'
+        assert checker.is_valid()
+
+    def test_other_fragment(self):
+        "Content checks should succeed silently if no hash is present"
+        checker = setuptools.package_index.HashChecker.from_url(
+            'http://foo/bar#something%20completely%20different')
+        checker.feed('anything'.encode('ascii'))
+        assert checker.is_valid()
+
+    def test_blank_md5(self):
+        "Content checks should succeed if a hash is empty"
+        checker = setuptools.package_index.HashChecker.from_url(
+            'http://foo/bar#md5=')
+        checker.feed('anything'.encode('ascii'))
+        assert checker.is_valid()
+
+    def test_get_hash_name_md5(self):
+        checker = setuptools.package_index.HashChecker.from_url(
+            'http://foo/bar#md5=f12895fdffbd45007040d2e44df98478')
+        assert checker.hash_name == 'md5'
+
+    def test_report(self):
+        checker = setuptools.package_index.HashChecker.from_url(
+            'http://foo/bar#md5=f12895fdffbd45007040d2e44df98478')
+        rep = checker.report(lambda x: x, 'My message about %s')
+        assert rep == 'My message about md5'
+
+
+class TestPyPIConfig:
+    def test_percent_in_password(self, tmpdir, monkeypatch):
+        monkeypatch.setitem(os.environ, 'HOME', str(tmpdir))
+        pypirc = tmpdir / '.pypirc'
+        with pypirc.open('w') as strm:
+            strm.write(DALS("""
+                [pypi]
+                repository=https://pypi.python.org
+                username=jaraco
+                password=pity%
+            """))
+        cfg = setuptools.package_index.PyPIConfig()
+        cred = cfg.creds_by_repository['https://pypi.python.org']
+        assert cred.username == 'jaraco'
+        assert cred.password == 'pity%'
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_sandbox.py b/vendor/setuptools-39.0.1/setuptools/tests/test_sandbox.py
new file mode 100644
index 00000000..d8675422
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_sandbox.py
@@ -0,0 +1,133 @@
+"""develop tests
+"""
+import os
+import types
+
+import pytest
+
+import pkg_resources
+import setuptools.sandbox
+
+
+class TestSandbox:
+    def test_devnull(self, tmpdir):
+        with setuptools.sandbox.DirectorySandbox(str(tmpdir)):
+            self._file_writer(os.devnull)
+
+    @staticmethod
+    def _file_writer(path):
+        def do_write():
+            with open(path, 'w') as f:
+                f.write('xxx')
+
+        return do_write
+
+    def test_setup_py_with_BOM(self):
+        """
+        It should be possible to execute a setup.py with a Byte Order Mark
+        """
+        target = pkg_resources.resource_filename(__name__,
+            'script-with-bom.py')
+        namespace = types.ModuleType('namespace')
+        setuptools.sandbox._execfile(target, vars(namespace))
+        assert namespace.result == 'passed'
+
+    def test_setup_py_with_CRLF(self, tmpdir):
+        setup_py = tmpdir / 'setup.py'
+        with setup_py.open('wb') as stream:
+            stream.write(b'"degenerate script"\r\n')
+        setuptools.sandbox._execfile(str(setup_py), globals())
+
+
+class TestExceptionSaver:
+    def test_exception_trapped(self):
+        with setuptools.sandbox.ExceptionSaver():
+            raise ValueError("details")
+
+    def test_exception_resumed(self):
+        with setuptools.sandbox.ExceptionSaver() as saved_exc:
+            raise ValueError("details")
+
+        with pytest.raises(ValueError) as caught:
+            saved_exc.resume()
+
+        assert isinstance(caught.value, ValueError)
+        assert str(caught.value) == 'details'
+
+    def test_exception_reconstructed(self):
+        orig_exc = ValueError("details")
+
+        with setuptools.sandbox.ExceptionSaver() as saved_exc:
+            raise orig_exc
+
+        with pytest.raises(ValueError) as caught:
+            saved_exc.resume()
+
+        assert isinstance(caught.value, ValueError)
+        assert caught.value is not orig_exc
+
+    def test_no_exception_passes_quietly(self):
+        with setuptools.sandbox.ExceptionSaver() as saved_exc:
+            pass
+
+        saved_exc.resume()
+
+    def test_unpickleable_exception(self):
+        class CantPickleThis(Exception):
+            "This Exception is unpickleable because it's not in globals"
+            def __repr__(self):
+                return 'CantPickleThis%r' % (self.args,)
+
+        with setuptools.sandbox.ExceptionSaver() as saved_exc:
+            raise CantPickleThis('detail')
+
+        with pytest.raises(setuptools.sandbox.UnpickleableException) as caught:
+            saved_exc.resume()
+
+        assert str(caught.value) == "CantPickleThis('detail',)"
+
+    def test_unpickleable_exception_when_hiding_setuptools(self):
+        """
+        As revealed in #440, an infinite recursion can occur if an unpickleable
+        exception while setuptools is hidden. Ensure this doesn't happen.
+        """
+
+        class ExceptionUnderTest(Exception):
+            """
+            An unpickleable exception (not in globals).
+            """
+
+        with pytest.raises(setuptools.sandbox.UnpickleableException) as caught:
+            with setuptools.sandbox.save_modules():
+                setuptools.sandbox.hide_setuptools()
+                raise ExceptionUnderTest()
+
+        msg, = caught.value.args
+        assert msg == 'ExceptionUnderTest()'
+
+    def test_sandbox_violation_raised_hiding_setuptools(self, tmpdir):
+        """
+        When in a sandbox with setuptools hidden, a SandboxViolation
+        should reflect a proper exception and not be wrapped in
+        an UnpickleableException.
+        """
+
+        def write_file():
+            "Trigger a SandboxViolation by writing outside the sandbox"
+            with open('/etc/foo', 'w'):
+                pass
+
+        with pytest.raises(setuptools.sandbox.SandboxViolation) as caught:
+            with setuptools.sandbox.save_modules():
+                setuptools.sandbox.hide_setuptools()
+                with setuptools.sandbox.DirectorySandbox(str(tmpdir)):
+                    write_file()
+
+        cmd, args, kwargs = caught.value.args
+        assert cmd == 'open'
+        assert args == ('/etc/foo', 'w')
+        assert kwargs == {}
+
+        msg = str(caught.value)
+        assert 'open' in msg
+        assert "('/etc/foo', 'w')" in msg
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_sdist.py b/vendor/setuptools-39.0.1/setuptools/tests/test_sdist.py
new file mode 100644
index 00000000..02222da5
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_sdist.py
@@ -0,0 +1,427 @@
+# -*- coding: utf-8 -*-
+"""sdist tests"""
+
+import os
+import shutil
+import sys
+import tempfile
+import unicodedata
+import contextlib
+import io
+
+from setuptools.extern import six
+from setuptools.extern.six.moves import map
+
+import pytest
+
+import pkg_resources
+from setuptools.command.sdist import sdist
+from setuptools.command.egg_info import manifest_maker
+from setuptools.dist import Distribution
+from setuptools.tests import fail_on_ascii
+from .text import Filenames
+
+py3_only = pytest.mark.xfail(six.PY2, reason="Test runs on Python 3 only")
+
+SETUP_ATTRS = {
+    'name': 'sdist_test',
+    'version': '0.0',
+    'packages': ['sdist_test'],
+    'package_data': {'sdist_test': ['*.txt']},
+    'data_files': [("data", [os.path.join("d", "e.dat")])],
+}
+
+SETUP_PY = """\
+from setuptools import setup
+
+setup(**%r)
+""" % SETUP_ATTRS
+
+
+@contextlib.contextmanager
+def quiet():
+    old_stdout, old_stderr = sys.stdout, sys.stderr
+    sys.stdout, sys.stderr = six.StringIO(), six.StringIO()
+    try:
+        yield
+    finally:
+        sys.stdout, sys.stderr = old_stdout, old_stderr
+
+
+# Convert to POSIX path
+def posix(path):
+    if six.PY3 and not isinstance(path, str):
+        return path.replace(os.sep.encode('ascii'), b'/')
+    else:
+        return path.replace(os.sep, '/')
+
+
+# HFS Plus uses decomposed UTF-8
+def decompose(path):
+    if isinstance(path, six.text_type):
+        return unicodedata.normalize('NFD', path)
+    try:
+        path = path.decode('utf-8')
+        path = unicodedata.normalize('NFD', path)
+        path = path.encode('utf-8')
+    except UnicodeError:
+        pass  # Not UTF-8
+    return path
+
+
+def read_all_bytes(filename):
+    with io.open(filename, 'rb') as fp:
+        return fp.read()
+
+
+def latin1_fail():
+    try:
+        desc, filename = tempfile.mkstemp(suffix=Filenames.latin_1)
+        os.close(desc)
+        os.remove(filename)
+    except Exception:
+        return True
+
+
+fail_on_latin1_encoded_filenames = pytest.mark.xfail(
+    latin1_fail(),
+    reason="System does not support latin-1 filenames",
+)
+
+
+class TestSdistTest:
+    def setup_method(self, method):
+        self.temp_dir = tempfile.mkdtemp()
+        f = open(os.path.join(self.temp_dir, 'setup.py'), 'w')
+        f.write(SETUP_PY)
+        f.close()
+
+        # Set up the rest of the test package
+        test_pkg = os.path.join(self.temp_dir, 'sdist_test')
+        os.mkdir(test_pkg)
+        data_folder = os.path.join(self.temp_dir, "d")
+        os.mkdir(data_folder)
+        # *.rst was not included in package_data, so c.rst should not be
+        # automatically added to the manifest when not under version control
+        for fname in ['__init__.py', 'a.txt', 'b.txt', 'c.rst',
+                      os.path.join(data_folder, "e.dat")]:
+            # Just touch the files; their contents are irrelevant
+            open(os.path.join(test_pkg, fname), 'w').close()
+
+        self.old_cwd = os.getcwd()
+        os.chdir(self.temp_dir)
+
+    def teardown_method(self, method):
+        os.chdir(self.old_cwd)
+        shutil.rmtree(self.temp_dir)
+
+    def test_package_data_in_sdist(self):
+        """Regression test for pull request #4: ensures that files listed in
+        package_data are included in the manifest even if they're not added to
+        version control.
+        """
+
+        dist = Distribution(SETUP_ATTRS)
+        dist.script_name = 'setup.py'
+        cmd = sdist(dist)
+        cmd.ensure_finalized()
+
+        with quiet():
+            cmd.run()
+
+        manifest = cmd.filelist.files
+        assert os.path.join('sdist_test', 'a.txt') in manifest
+        assert os.path.join('sdist_test', 'b.txt') in manifest
+        assert os.path.join('sdist_test', 'c.rst') not in manifest
+        assert os.path.join('d', 'e.dat') in manifest
+
+    def test_defaults_case_sensitivity(self):
+        """
+        Make sure default files (README.*, etc.) are added in a case-sensitive
+        way to avoid problems with packages built on Windows.
+        """
+
+        open(os.path.join(self.temp_dir, 'readme.rst'), 'w').close()
+        open(os.path.join(self.temp_dir, 'SETUP.cfg'), 'w').close()
+
+        dist = Distribution(SETUP_ATTRS)
+        # the extension deliberately capitalized for this test
+        # to make sure the actual filename (not capitalized) gets added
+        # to the manifest
+        dist.script_name = 'setup.PY'
+        cmd = sdist(dist)
+        cmd.ensure_finalized()
+
+        with quiet():
+            cmd.run()
+
+        # lowercase all names so we can test in a
+        # case-insensitive way to make sure the files
+        # are not included.
+        manifest = map(lambda x: x.lower(), cmd.filelist.files)
+        assert 'readme.rst' not in manifest, manifest
+        assert 'setup.py' not in manifest, manifest
+        assert 'setup.cfg' not in manifest, manifest
+
+    @fail_on_ascii
+    def test_manifest_is_written_with_utf8_encoding(self):
+        # Test for #303.
+        dist = Distribution(SETUP_ATTRS)
+        dist.script_name = 'setup.py'
+        mm = manifest_maker(dist)
+        mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
+        os.mkdir('sdist_test.egg-info')
+
+        # UTF-8 filename
+        filename = os.path.join('sdist_test', 'smörbröd.py')
+
+        # Must create the file or it will get stripped.
+        open(filename, 'w').close()
+
+        # Add UTF-8 filename and write manifest
+        with quiet():
+            mm.run()
+            mm.filelist.append(filename)
+            mm.write_manifest()
+
+        contents = read_all_bytes(mm.manifest)
+
+        # The manifest should be UTF-8 encoded
+        u_contents = contents.decode('UTF-8')
+
+        # The manifest should contain the UTF-8 filename
+        if six.PY2:
+            fs_enc = sys.getfilesystemencoding()
+            filename = filename.decode(fs_enc)
+
+        assert posix(filename) in u_contents
+
+    @py3_only
+    @fail_on_ascii
+    def test_write_manifest_allows_utf8_filenames(self):
+        # Test for #303.
+        dist = Distribution(SETUP_ATTRS)
+        dist.script_name = 'setup.py'
+        mm = manifest_maker(dist)
+        mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
+        os.mkdir('sdist_test.egg-info')
+
+        filename = os.path.join(b'sdist_test', Filenames.utf_8)
+
+        # Must touch the file or risk removal
+        open(filename, "w").close()
+
+        # Add filename and write manifest
+        with quiet():
+            mm.run()
+            u_filename = filename.decode('utf-8')
+            mm.filelist.files.append(u_filename)
+            # Re-write manifest
+            mm.write_manifest()
+
+        contents = read_all_bytes(mm.manifest)
+
+        # The manifest should be UTF-8 encoded
+        contents.decode('UTF-8')
+
+        # The manifest should contain the UTF-8 filename
+        assert posix(filename) in contents
+
+        # The filelist should have been updated as well
+        assert u_filename in mm.filelist.files
+
+    @py3_only
+    def test_write_manifest_skips_non_utf8_filenames(self):
+        """
+        Files that cannot be encoded to UTF-8 (specifically, those that
+        weren't originally successfully decoded and have surrogate
+        escapes) should be omitted from the manifest.
+        See https://bitbucket.org/tarek/distribute/issue/303 for history.
+        """
+        dist = Distribution(SETUP_ATTRS)
+        dist.script_name = 'setup.py'
+        mm = manifest_maker(dist)
+        mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
+        os.mkdir('sdist_test.egg-info')
+
+        # Latin-1 filename
+        filename = os.path.join(b'sdist_test', Filenames.latin_1)
+
+        # Add filename with surrogates and write manifest
+        with quiet():
+            mm.run()
+            u_filename = filename.decode('utf-8', 'surrogateescape')
+            mm.filelist.append(u_filename)
+            # Re-write manifest
+            mm.write_manifest()
+
+        contents = read_all_bytes(mm.manifest)
+
+        # The manifest should be UTF-8 encoded
+        contents.decode('UTF-8')
+
+        # The Latin-1 filename should have been skipped
+        assert posix(filename) not in contents
+
+        # The filelist should have been updated as well
+        assert u_filename not in mm.filelist.files
+
+    @fail_on_ascii
+    def test_manifest_is_read_with_utf8_encoding(self):
+        # Test for #303.
+        dist = Distribution(SETUP_ATTRS)
+        dist.script_name = 'setup.py'
+        cmd = sdist(dist)
+        cmd.ensure_finalized()
+
+        # Create manifest
+        with quiet():
+            cmd.run()
+
+        # Add UTF-8 filename to manifest
+        filename = os.path.join(b'sdist_test', Filenames.utf_8)
+        cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
+        manifest = open(cmd.manifest, 'ab')
+        manifest.write(b'\n' + filename)
+        manifest.close()
+
+        # The file must exist to be included in the filelist
+        open(filename, 'w').close()
+
+        # Re-read manifest
+        cmd.filelist.files = []
+        with quiet():
+            cmd.read_manifest()
+
+        # The filelist should contain the UTF-8 filename
+        if six.PY3:
+            filename = filename.decode('utf-8')
+        assert filename in cmd.filelist.files
+
+    @py3_only
+    @fail_on_latin1_encoded_filenames
+    def test_read_manifest_skips_non_utf8_filenames(self):
+        # Test for #303.
+        dist = Distribution(SETUP_ATTRS)
+        dist.script_name = 'setup.py'
+        cmd = sdist(dist)
+        cmd.ensure_finalized()
+
+        # Create manifest
+        with quiet():
+            cmd.run()
+
+        # Add Latin-1 filename to manifest
+        filename = os.path.join(b'sdist_test', Filenames.latin_1)
+        cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
+        manifest = open(cmd.manifest, 'ab')
+        manifest.write(b'\n' + filename)
+        manifest.close()
+
+        # The file must exist to be included in the filelist
+        open(filename, 'w').close()
+
+        # Re-read manifest
+        cmd.filelist.files = []
+        with quiet():
+            cmd.read_manifest()
+
+        # The Latin-1 filename should have been skipped
+        filename = filename.decode('latin-1')
+        assert filename not in cmd.filelist.files
+
+    @fail_on_ascii
+    @fail_on_latin1_encoded_filenames
+    def test_sdist_with_utf8_encoded_filename(self):
+        # Test for #303.
+        dist = Distribution(SETUP_ATTRS)
+        dist.script_name = 'setup.py'
+        cmd = sdist(dist)
+        cmd.ensure_finalized()
+
+        filename = os.path.join(b'sdist_test', Filenames.utf_8)
+        open(filename, 'w').close()
+
+        with quiet():
+            cmd.run()
+
+        if sys.platform == 'darwin':
+            filename = decompose(filename)
+
+        if six.PY3:
+            fs_enc = sys.getfilesystemencoding()
+
+            if sys.platform == 'win32':
+                if fs_enc == 'cp1252':
+                    # Python 3 mangles the UTF-8 filename
+                    filename = filename.decode('cp1252')
+                    assert filename in cmd.filelist.files
+                else:
+                    filename = filename.decode('mbcs')
+                    assert filename in cmd.filelist.files
+            else:
+                filename = filename.decode('utf-8')
+                assert filename in cmd.filelist.files
+        else:
+            assert filename in cmd.filelist.files
+
+    @fail_on_latin1_encoded_filenames
+    def test_sdist_with_latin1_encoded_filename(self):
+        # Test for #303.
+        dist = Distribution(SETUP_ATTRS)
+        dist.script_name = 'setup.py'
+        cmd = sdist(dist)
+        cmd.ensure_finalized()
+
+        # Latin-1 filename
+        filename = os.path.join(b'sdist_test', Filenames.latin_1)
+        open(filename, 'w').close()
+        assert os.path.isfile(filename)
+
+        with quiet():
+            cmd.run()
+
+        if six.PY3:
+            # not all windows systems have a default FS encoding of cp1252
+            if sys.platform == 'win32':
+                # Latin-1 is similar to Windows-1252 however
+                # on mbcs filesys it is not in latin-1 encoding
+                fs_enc = sys.getfilesystemencoding()
+                if fs_enc != 'mbcs':
+                    fs_enc = 'latin-1'
+                filename = filename.decode(fs_enc)
+
+                assert filename in cmd.filelist.files
+            else:
+                # The Latin-1 filename should have been skipped
+                filename = filename.decode('latin-1')
+                filename not in cmd.filelist.files
+        else:
+            # Under Python 2 there seems to be no decoded string in the
+            # filelist.  However, due to decode and encoding of the
+            # file name to get utf-8 Manifest the latin1 maybe excluded
+            try:
+                # fs_enc should match how one is expect the decoding to
+                # be proformed for the manifest output.
+                fs_enc = sys.getfilesystemencoding()
+                filename.decode(fs_enc)
+                assert filename in cmd.filelist.files
+            except UnicodeDecodeError:
+                filename not in cmd.filelist.files
+
+
+def test_default_revctrl():
+    """
+    When _default_revctrl was removed from the `setuptools.command.sdist`
+    module in 10.0, it broke some systems which keep an old install of
+    setuptools (Distribute) around. Those old versions require that the
+    setuptools package continue to implement that interface, so this
+    function provides that interface, stubbed. See #320 for details.
+
+    This interface must be maintained until Ubuntu 12.04 is no longer
+    supported (by Setuptools).
+    """
+    ep_def = 'svn_cvs = setuptools.command.sdist:_default_revctrl'
+    ep = pkg_resources.EntryPoint.parse(ep_def)
+    res = ep.resolve()
+    assert hasattr(res, '__iter__')
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_setuptools.py b/vendor/setuptools-39.0.1/setuptools/tests/test_setuptools.py
new file mode 100644
index 00000000..26e37a6c
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_setuptools.py
@@ -0,0 +1,368 @@
+"""Tests for the 'setuptools' package"""
+
+import sys
+import os
+import distutils.core
+import distutils.cmd
+from distutils.errors import DistutilsOptionError, DistutilsPlatformError
+from distutils.errors import DistutilsSetupError
+from distutils.core import Extension
+from distutils.version import LooseVersion
+
+import pytest
+
+import setuptools
+import setuptools.dist
+import setuptools.depends as dep
+from setuptools import Feature
+from setuptools.depends import Require
+from setuptools.extern import six
+
+
+def makeSetup(**args):
+    """Return distribution from 'setup(**args)', without executing commands"""
+
+    distutils.core._setup_stop_after = "commandline"
+
+    # Don't let system command line leak into tests!
+    args.setdefault('script_args', ['install'])
+
+    try:
+        return setuptools.setup(**args)
+    finally:
+        distutils.core._setup_stop_after = None
+
+
+needs_bytecode = pytest.mark.skipif(
+    not hasattr(dep, 'get_module_constant'),
+    reason="bytecode support not available",
+)
+
+
+class TestDepends:
+    def testExtractConst(self):
+        if not hasattr(dep, 'extract_constant'):
+            # skip on non-bytecode platforms
+            return
+
+        def f1():
+            global x, y, z
+            x = "test"
+            y = z
+
+        fc = six.get_function_code(f1)
+
+        # unrecognized name
+        assert dep.extract_constant(fc, 'q', -1) is None
+
+        # constant assigned
+        dep.extract_constant(fc, 'x', -1) == "test"
+
+        # expression assigned
+        dep.extract_constant(fc, 'y', -1) == -1
+
+        # recognized name, not assigned
+        dep.extract_constant(fc, 'z', -1) is None
+
+    def testFindModule(self):
+        with pytest.raises(ImportError):
+            dep.find_module('no-such.-thing')
+        with pytest.raises(ImportError):
+            dep.find_module('setuptools.non-existent')
+        f, p, i = dep.find_module('setuptools.tests')
+        f.close()
+
+    @needs_bytecode
+    def testModuleExtract(self):
+        from json import __version__
+        assert dep.get_module_constant('json', '__version__') == __version__
+        assert dep.get_module_constant('sys', 'version') == sys.version
+        assert dep.get_module_constant('setuptools.tests.test_setuptools', '__doc__') == __doc__
+
+    @needs_bytecode
+    def testRequire(self):
+        req = Require('Json', '1.0.3', 'json')
+
+        assert req.name == 'Json'
+        assert req.module == 'json'
+        assert req.requested_version == '1.0.3'
+        assert req.attribute == '__version__'
+        assert req.full_name() == 'Json-1.0.3'
+
+        from json import __version__
+        assert req.get_version() == __version__
+        assert req.version_ok('1.0.9')
+        assert not req.version_ok('0.9.1')
+        assert not req.version_ok('unknown')
+
+        assert req.is_present()
+        assert req.is_current()
+
+        req = Require('Json 3000', '03000', 'json', format=LooseVersion)
+        assert req.is_present()
+        assert not req.is_current()
+        assert not req.version_ok('unknown')
+
+        req = Require('Do-what-I-mean', '1.0', 'd-w-i-m')
+        assert not req.is_present()
+        assert not req.is_current()
+
+        req = Require('Tests', None, 'tests', homepage="http://example.com")
+        assert req.format is None
+        assert req.attribute is None
+        assert req.requested_version is None
+        assert req.full_name() == 'Tests'
+        assert req.homepage == 'http://example.com'
+
+        from setuptools.tests import __path__
+        paths = [os.path.dirname(p) for p in __path__]
+        assert req.is_present(paths)
+        assert req.is_current(paths)
+
+
+class TestDistro:
+    def setup_method(self, method):
+        self.e1 = Extension('bar.ext', ['bar.c'])
+        self.e2 = Extension('c.y', ['y.c'])
+
+        self.dist = makeSetup(
+            packages=['a', 'a.b', 'a.b.c', 'b', 'c'],
+            py_modules=['b.d', 'x'],
+            ext_modules=(self.e1, self.e2),
+            package_dir={},
+        )
+
+    def testDistroType(self):
+        assert isinstance(self.dist, setuptools.dist.Distribution)
+
+    def testExcludePackage(self):
+        self.dist.exclude_package('a')
+        assert self.dist.packages == ['b', 'c']
+
+        self.dist.exclude_package('b')
+        assert self.dist.packages == ['c']
+        assert self.dist.py_modules == ['x']
+        assert self.dist.ext_modules == [self.e1, self.e2]
+
+        self.dist.exclude_package('c')
+        assert self.dist.packages == []
+        assert self.dist.py_modules == ['x']
+        assert self.dist.ext_modules == [self.e1]
+
+        # test removals from unspecified options
+        makeSetup().exclude_package('x')
+
+    def testIncludeExclude(self):
+        # remove an extension
+        self.dist.exclude(ext_modules=[self.e1])
+        assert self.dist.ext_modules == [self.e2]
+
+        # add it back in
+        self.dist.include(ext_modules=[self.e1])
+        assert self.dist.ext_modules == [self.e2, self.e1]
+
+        # should not add duplicate
+        self.dist.include(ext_modules=[self.e1])
+        assert self.dist.ext_modules == [self.e2, self.e1]
+
+    def testExcludePackages(self):
+        self.dist.exclude(packages=['c', 'b', 'a'])
+        assert self.dist.packages == []
+        assert self.dist.py_modules == ['x']
+        assert self.dist.ext_modules == [self.e1]
+
+    def testEmpty(self):
+        dist = makeSetup()
+        dist.include(packages=['a'], py_modules=['b'], ext_modules=[self.e2])
+        dist = makeSetup()
+        dist.exclude(packages=['a'], py_modules=['b'], ext_modules=[self.e2])
+
+    def testContents(self):
+        assert self.dist.has_contents_for('a')
+        self.dist.exclude_package('a')
+        assert not self.dist.has_contents_for('a')
+
+        assert self.dist.has_contents_for('b')
+        self.dist.exclude_package('b')
+        assert not self.dist.has_contents_for('b')
+
+        assert self.dist.has_contents_for('c')
+        self.dist.exclude_package('c')
+        assert not self.dist.has_contents_for('c')
+
+    def testInvalidIncludeExclude(self):
+        with pytest.raises(DistutilsSetupError):
+            self.dist.include(nonexistent_option='x')
+        with pytest.raises(DistutilsSetupError):
+            self.dist.exclude(nonexistent_option='x')
+        with pytest.raises(DistutilsSetupError):
+            self.dist.include(packages={'x': 'y'})
+        with pytest.raises(DistutilsSetupError):
+            self.dist.exclude(packages={'x': 'y'})
+        with pytest.raises(DistutilsSetupError):
+            self.dist.include(ext_modules={'x': 'y'})
+        with pytest.raises(DistutilsSetupError):
+            self.dist.exclude(ext_modules={'x': 'y'})
+
+        with pytest.raises(DistutilsSetupError):
+            self.dist.include(package_dir=['q'])
+        with pytest.raises(DistutilsSetupError):
+            self.dist.exclude(package_dir=['q'])
+
+
+class TestFeatures:
+    def setup_method(self, method):
+        self.req = Require('Distutils', '1.0.3', 'distutils')
+        self.dist = makeSetup(
+            features={
+                'foo': Feature("foo", standard=True, require_features=['baz', self.req]),
+                'bar': Feature("bar", standard=True, packages=['pkg.bar'],
+                               py_modules=['bar_et'], remove=['bar.ext'],
+                               ),
+                'baz': Feature(
+                        "baz", optional=False, packages=['pkg.baz'],
+                        scripts=['scripts/baz_it'],
+                        libraries=[('libfoo', 'foo/foofoo.c')]
+                       ),
+                'dwim': Feature("DWIM", available=False, remove='bazish'),
+            },
+            script_args=['--without-bar', 'install'],
+            packages=['pkg.bar', 'pkg.foo'],
+            py_modules=['bar_et', 'bazish'],
+            ext_modules=[Extension('bar.ext', ['bar.c'])]
+        )
+
+    def testDefaults(self):
+        assert not Feature(
+            "test", standard=True, remove='x', available=False
+        ).include_by_default()
+        assert Feature("test", standard=True, remove='x').include_by_default()
+        # Feature must have either kwargs, removes, or require_features
+        with pytest.raises(DistutilsSetupError):
+            Feature("test")
+
+    def testAvailability(self):
+        with pytest.raises(DistutilsPlatformError):
+            self.dist.features['dwim'].include_in(self.dist)
+
+    def testFeatureOptions(self):
+        dist = self.dist
+        assert (
+            ('with-dwim', None, 'include DWIM') in dist.feature_options
+        )
+        assert (
+            ('without-dwim', None, 'exclude DWIM (default)') in dist.feature_options
+        )
+        assert (
+            ('with-bar', None, 'include bar (default)') in dist.feature_options
+        )
+        assert (
+            ('without-bar', None, 'exclude bar') in dist.feature_options
+        )
+        assert dist.feature_negopt['without-foo'] == 'with-foo'
+        assert dist.feature_negopt['without-bar'] == 'with-bar'
+        assert dist.feature_negopt['without-dwim'] == 'with-dwim'
+        assert ('without-baz' not in dist.feature_negopt)
+
+    def testUseFeatures(self):
+        dist = self.dist
+        assert dist.with_foo == 1
+        assert dist.with_bar == 0
+        assert dist.with_baz == 1
+        assert ('bar_et' not in dist.py_modules)
+        assert ('pkg.bar' not in dist.packages)
+        assert ('pkg.baz' in dist.packages)
+        assert ('scripts/baz_it' in dist.scripts)
+        assert (('libfoo', 'foo/foofoo.c') in dist.libraries)
+        assert dist.ext_modules == []
+        assert dist.require_features == [self.req]
+
+        # If we ask for bar, it should fail because we explicitly disabled
+        # it on the command line
+        with pytest.raises(DistutilsOptionError):
+            dist.include_feature('bar')
+
+    def testFeatureWithInvalidRemove(self):
+        with pytest.raises(SystemExit):
+            makeSetup(features={'x': Feature('x', remove='y')})
+
+
+class TestCommandTests:
+    def testTestIsCommand(self):
+        test_cmd = makeSetup().get_command_obj('test')
+        assert (isinstance(test_cmd, distutils.cmd.Command))
+
+    def testLongOptSuiteWNoDefault(self):
+        ts1 = makeSetup(script_args=['test', '--test-suite=foo.tests.suite'])
+        ts1 = ts1.get_command_obj('test')
+        ts1.ensure_finalized()
+        assert ts1.test_suite == 'foo.tests.suite'
+
+    def testDefaultSuite(self):
+        ts2 = makeSetup(test_suite='bar.tests.suite').get_command_obj('test')
+        ts2.ensure_finalized()
+        assert ts2.test_suite == 'bar.tests.suite'
+
+    def testDefaultWModuleOnCmdLine(self):
+        ts3 = makeSetup(
+            test_suite='bar.tests',
+            script_args=['test', '-m', 'foo.tests']
+        ).get_command_obj('test')
+        ts3.ensure_finalized()
+        assert ts3.test_module == 'foo.tests'
+        assert ts3.test_suite == 'foo.tests.test_suite'
+
+    def testConflictingOptions(self):
+        ts4 = makeSetup(
+            script_args=['test', '-m', 'bar.tests', '-s', 'foo.tests.suite']
+        ).get_command_obj('test')
+        with pytest.raises(DistutilsOptionError):
+            ts4.ensure_finalized()
+
+    def testNoSuite(self):
+        ts5 = makeSetup().get_command_obj('test')
+        ts5.ensure_finalized()
+        assert ts5.test_suite is None
+
+
+@pytest.fixture
+def example_source(tmpdir):
+    tmpdir.mkdir('foo')
+    (tmpdir / 'foo/bar.py').write('')
+    (tmpdir / 'readme.txt').write('')
+    return tmpdir
+
+
+def test_findall(example_source):
+    found = list(setuptools.findall(str(example_source)))
+    expected = ['readme.txt', 'foo/bar.py']
+    expected = [example_source.join(fn) for fn in expected]
+    assert found == expected
+
+
+def test_findall_curdir(example_source):
+    with example_source.as_cwd():
+        found = list(setuptools.findall())
+    expected = ['readme.txt', os.path.join('foo', 'bar.py')]
+    assert found == expected
+
+
+@pytest.fixture
+def can_symlink(tmpdir):
+    """
+    Skip if cannot create a symbolic link
+    """
+    link_fn = 'link'
+    target_fn = 'target'
+    try:
+        os.symlink(target_fn, link_fn)
+    except (OSError, NotImplementedError, AttributeError):
+        pytest.skip("Cannot create symbolic links")
+    os.remove(link_fn)
+
+
+def test_findall_missing_symlink(tmpdir, can_symlink):
+    with tmpdir.as_cwd():
+        os.symlink('foo', 'bar')
+        found = list(setuptools.findall())
+        assert found == []
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_test.py b/vendor/setuptools-39.0.1/setuptools/tests/test_test.py
new file mode 100644
index 00000000..960527bc
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_test.py
@@ -0,0 +1,131 @@
+# -*- coding: UTF-8 -*-
+
+from __future__ import unicode_literals
+
+from distutils import log
+import os
+import sys
+
+import pytest
+
+from setuptools.command.test import test
+from setuptools.dist import Distribution
+
+from .textwrap import DALS
+from . import contexts
+
+SETUP_PY = DALS("""
+    from setuptools import setup
+
+    setup(name='foo',
+        packages=['name', 'name.space', 'name.space.tests'],
+        namespace_packages=['name'],
+        test_suite='name.space.tests.test_suite',
+    )
+    """)
+
+NS_INIT = DALS("""
+    # -*- coding: Latin-1 -*-
+    # Söme Arbiträry Ünicode to test Distribute Issüé 310
+    try:
+        __import__('pkg_resources').declare_namespace(__name__)
+    except ImportError:
+        from pkgutil import extend_path
+        __path__ = extend_path(__path__, __name__)
+    """)
+
+TEST_PY = DALS("""
+    import unittest
+
+    class TestTest(unittest.TestCase):
+        def test_test(self):
+            print "Foo" # Should fail under Python 3 unless 2to3 is used
+
+    test_suite = unittest.makeSuite(TestTest)
+    """)
+
+
+@pytest.fixture
+def sample_test(tmpdir_cwd):
+    os.makedirs('name/space/tests')
+
+    # setup.py
+    with open('setup.py', 'wt') as f:
+        f.write(SETUP_PY)
+
+    # name/__init__.py
+    with open('name/__init__.py', 'wb') as f:
+        f.write(NS_INIT.encode('Latin-1'))
+
+    # name/space/__init__.py
+    with open('name/space/__init__.py', 'wt') as f:
+        f.write('#empty\n')
+
+    # name/space/tests/__init__.py
+    with open('name/space/tests/__init__.py', 'wt') as f:
+        f.write(TEST_PY)
+
+
+@pytest.fixture
+def quiet_log():
+    # Running some of the other tests will automatically
+    # change the log level to info, messing our output.
+    log.set_verbosity(0)
+
+
+@pytest.mark.usefixtures('sample_test', 'quiet_log')
+def test_test(capfd):
+    params = dict(
+        name='foo',
+        packages=['name', 'name.space', 'name.space.tests'],
+        namespace_packages=['name'],
+        test_suite='name.space.tests.test_suite',
+        use_2to3=True,
+    )
+    dist = Distribution(params)
+    dist.script_name = 'setup.py'
+    cmd = test(dist)
+    cmd.ensure_finalized()
+    # The test runner calls sys.exit
+    with contexts.suppress_exceptions(SystemExit):
+        cmd.run()
+    out, err = capfd.readouterr()
+    assert out == 'Foo\n'
+
+
+@pytest.mark.xfail(
+    sys.version_info < (2, 7),
+    reason="No discover support for unittest on Python 2.6",
+)
+@pytest.mark.usefixtures('tmpdir_cwd', 'quiet_log')
+def test_tests_are_run_once(capfd):
+    params = dict(
+        name='foo',
+        packages=['dummy'],
+    )
+    with open('setup.py', 'wt') as f:
+        f.write('from setuptools import setup; setup(\n')
+        for k, v in sorted(params.items()):
+            f.write('    %s=%r,\n' % (k, v))
+        f.write(')\n')
+    os.makedirs('dummy')
+    with open('dummy/__init__.py', 'wt'):
+        pass
+    with open('dummy/test_dummy.py', 'wt') as f:
+        f.write(DALS(
+            """
+            from __future__ import print_function
+            import unittest
+            class TestTest(unittest.TestCase):
+                def test_test(self):
+                    print('Foo')
+             """))
+    dist = Distribution(params)
+    dist.script_name = 'setup.py'
+    cmd = test(dist)
+    cmd.ensure_finalized()
+    # The test runner calls sys.exit
+    with contexts.suppress_exceptions(SystemExit):
+        cmd.run()
+    out, err = capfd.readouterr()
+    assert out == 'Foo\n'
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_unicode_utils.py b/vendor/setuptools-39.0.1/setuptools/tests/test_unicode_utils.py
new file mode 100644
index 00000000..a24a9bd5
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_unicode_utils.py
@@ -0,0 +1,10 @@
+from setuptools import unicode_utils
+
+
+def test_filesys_decode_fs_encoding_is_None(monkeypatch):
+    """
+    Test filesys_decode does not raise TypeError when
+    getfilesystemencoding returns None.
+    """
+    monkeypatch.setattr('sys.getfilesystemencoding', lambda: None)
+    unicode_utils.filesys_decode(b'test')
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_upload_docs.py b/vendor/setuptools-39.0.1/setuptools/tests/test_upload_docs.py
new file mode 100644
index 00000000..a26e32a6
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_upload_docs.py
@@ -0,0 +1,71 @@
+import os
+import zipfile
+import contextlib
+
+import pytest
+
+from setuptools.command.upload_docs import upload_docs
+from setuptools.dist import Distribution
+
+from .textwrap import DALS
+from . import contexts
+
+SETUP_PY = DALS(
+    """
+    from setuptools import setup
+
+    setup(name='foo')
+    """)
+
+
+@pytest.fixture
+def sample_project(tmpdir_cwd):
+    # setup.py
+    with open('setup.py', 'wt') as f:
+        f.write(SETUP_PY)
+
+    os.mkdir('build')
+
+    # A test document.
+    with open('build/index.html', 'w') as f:
+        f.write("Hello world.")
+
+    # An empty folder.
+    os.mkdir('build/empty')
+
+
+@pytest.mark.usefixtures('sample_project')
+@pytest.mark.usefixtures('user_override')
+class TestUploadDocsTest:
+    def test_create_zipfile(self):
+        """
+        Ensure zipfile creation handles common cases, including a folder
+        containing an empty folder.
+        """
+
+        dist = Distribution()
+
+        cmd = upload_docs(dist)
+        cmd.target_dir = cmd.upload_dir = 'build'
+        with contexts.tempdir() as tmp_dir:
+            tmp_file = os.path.join(tmp_dir, 'foo.zip')
+            zip_file = cmd.create_zipfile(tmp_file)
+
+            assert zipfile.is_zipfile(tmp_file)
+
+            with contextlib.closing(zipfile.ZipFile(tmp_file)) as zip_file:
+                assert zip_file.namelist() == ['index.html']
+
+    def test_build_multipart(self):
+        data = dict(
+            a="foo",
+            b="bar",
+            file=('file.txt', b'content'),
+        )
+        body, content_type = upload_docs._build_multipart(data)
+        assert 'form-data' in content_type
+        assert "b'" not in content_type
+        assert 'b"' not in content_type
+        assert isinstance(body, bytes)
+        assert b'foo' in body
+        assert b'content' in body
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_virtualenv.py b/vendor/setuptools-39.0.1/setuptools/tests/test_virtualenv.py
new file mode 100644
index 00000000..b66a311d
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_virtualenv.py
@@ -0,0 +1,139 @@
+import glob
+import os
+import sys
+
+import pytest
+from pytest import yield_fixture
+from pytest_fixture_config import yield_requires_config
+
+import pytest_virtualenv
+
+from .textwrap import DALS
+from .test_easy_install import make_nspkg_sdist
+
+
+@pytest.fixture(autouse=True)
+def pytest_virtualenv_works(virtualenv):
+    """
+    pytest_virtualenv may not work. if it doesn't, skip these
+    tests. See #1284.
+    """
+    venv_prefix = virtualenv.run(
+        'python -c "import sys; print(sys.prefix)"',
+        capture=True,
+    ).strip()
+    if venv_prefix == sys.prefix:
+        pytest.skip("virtualenv is broken (see pypa/setuptools#1284)")
+
+
+@yield_requires_config(pytest_virtualenv.CONFIG, ['virtualenv_executable'])
+@yield_fixture(scope='function')
+def bare_virtualenv():
+    """ Bare virtualenv (no pip/setuptools/wheel).
+    """
+    with pytest_virtualenv.VirtualEnv(args=(
+        '--no-wheel',
+        '--no-pip',
+        '--no-setuptools',
+    )) as venv:
+        yield venv
+
+
+SOURCE_DIR = os.path.join(os.path.dirname(__file__), '../..')
+
+
+def test_clean_env_install(bare_virtualenv):
+    """
+    Check setuptools can be installed in a clean environment.
+    """
+    bare_virtualenv.run(' && '.join((
+        'cd {source}',
+        'python setup.py install',
+    )).format(source=SOURCE_DIR))
+
+
+def test_pip_upgrade_from_source(virtualenv):
+    """
+    Check pip can upgrade setuptools from source.
+    """
+    dist_dir = virtualenv.workspace
+    if sys.version_info < (2, 7):
+        # Python 2.6 support was dropped in wheel 0.30.0.
+        virtualenv.run('pip install -U "wheel<0.30.0"')
+    # Generate source distribution / wheel.
+    virtualenv.run(' && '.join((
+        'cd {source}',
+        'python setup.py -q sdist -d {dist}',
+        'python setup.py -q bdist_wheel -d {dist}',
+    )).format(source=SOURCE_DIR, dist=dist_dir))
+    sdist = glob.glob(os.path.join(dist_dir, '*.zip'))[0]
+    wheel = glob.glob(os.path.join(dist_dir, '*.whl'))[0]
+    # Then update from wheel.
+    virtualenv.run('pip install ' + wheel)
+    # And finally try to upgrade from source.
+    virtualenv.run('pip install --no-cache-dir --upgrade ' + sdist)
+
+
+def test_test_command_install_requirements(bare_virtualenv, tmpdir):
+    """
+    Check the test command will install all required dependencies.
+    """
+    bare_virtualenv.run(' && '.join((
+        'cd {source}',
+        'python setup.py develop',
+    )).format(source=SOURCE_DIR))
+
+    def sdist(distname, version):
+        dist_path = tmpdir.join('%s-%s.tar.gz' % (distname, version))
+        make_nspkg_sdist(str(dist_path), distname, version)
+        return dist_path
+    dependency_links = [
+        str(dist_path)
+        for dist_path in (
+            sdist('foobar', '2.4'),
+            sdist('bits', '4.2'),
+            sdist('bobs', '6.0'),
+            sdist('pieces', '0.6'),
+        )
+    ]
+    with tmpdir.join('setup.py').open('w') as fp:
+        fp.write(DALS(
+            '''
+            from setuptools import setup
+
+            setup(
+                dependency_links={dependency_links!r},
+                install_requires=[
+                    'barbazquux1; sys_platform in ""',
+                    'foobar==2.4',
+                ],
+                setup_requires='bits==4.2',
+                tests_require="""
+                    bobs==6.0
+                """,
+                extras_require={{
+                    'test': ['barbazquux2'],
+                    ':"" in sys_platform': 'pieces==0.6',
+                    ':python_version > "1"': """
+                        pieces
+                        foobar
+                    """,
+                }}
+            )
+            '''.format(dependency_links=dependency_links)))
+    with tmpdir.join('test.py').open('w') as fp:
+        fp.write(DALS(
+            '''
+            import foobar
+            import bits
+            import bobs
+            import pieces
+
+            open('success', 'w').close()
+            '''))
+    # Run test command for test package.
+    bare_virtualenv.run(' && '.join((
+        'cd {tmpdir}',
+        'python setup.py test -s test',
+    )).format(tmpdir=tmpdir))
+    assert tmpdir.join('success').check()
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_wheel.py b/vendor/setuptools-39.0.1/setuptools/tests/test_wheel.py
new file mode 100644
index 00000000..b6be6f1f
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_wheel.py
@@ -0,0 +1,508 @@
+# -*- coding: utf-8 -*-
+
+"""wheel tests
+"""
+
+from distutils.sysconfig import get_config_var
+from distutils.util import get_platform
+import contextlib
+import glob
+import inspect
+import os
+import subprocess
+import sys
+
+import pytest
+
+from pkg_resources import Distribution, PathMetadata, PY_MAJOR
+from setuptools.wheel import Wheel
+
+from .contexts import tempdir
+from .files import build_files
+from .textwrap import DALS
+
+
+WHEEL_INFO_TESTS = (
+    ('invalid.whl', ValueError),
+    ('simplewheel-2.0-1-py2.py3-none-any.whl', {
+        'project_name': 'simplewheel',
+        'version': '2.0',
+        'build': '1',
+        'py_version': 'py2.py3',
+        'abi': 'none',
+        'platform': 'any',
+    }),
+    ('simple.dist-0.1-py2.py3-none-any.whl', {
+        'project_name': 'simple.dist',
+        'version': '0.1',
+        'build': None,
+        'py_version': 'py2.py3',
+        'abi': 'none',
+        'platform': 'any',
+    }),
+    ('example_pkg_a-1-py3-none-any.whl', {
+        'project_name': 'example_pkg_a',
+        'version': '1',
+        'build': None,
+        'py_version': 'py3',
+        'abi': 'none',
+        'platform': 'any',
+    }),
+    ('PyQt5-5.9-5.9.1-cp35.cp36.cp37-abi3-manylinux1_x86_64.whl', {
+        'project_name': 'PyQt5',
+        'version': '5.9',
+        'build': '5.9.1',
+        'py_version': 'cp35.cp36.cp37',
+        'abi': 'abi3',
+        'platform': 'manylinux1_x86_64',
+    }),
+)
+
+@pytest.mark.parametrize(
+    ('filename', 'info'), WHEEL_INFO_TESTS,
+    ids=[t[0] for t in WHEEL_INFO_TESTS]
+)
+def test_wheel_info(filename, info):
+    if inspect.isclass(info):
+        with pytest.raises(info):
+            Wheel(filename)
+        return
+    w = Wheel(filename)
+    assert {k: getattr(w, k) for k in info.keys()} == info
+
+
+@contextlib.contextmanager
+def build_wheel(extra_file_defs=None, **kwargs):
+    file_defs = {
+        'setup.py': (DALS(
+            '''
+            # -*- coding: utf-8 -*-
+            from setuptools import setup
+            import setuptools
+            setup(**%r)
+            '''
+        ) % kwargs).encode('utf-8'),
+    }
+    if extra_file_defs:
+        file_defs.update(extra_file_defs)
+    with tempdir() as source_dir:
+        build_files(file_defs, source_dir)
+        subprocess.check_call((sys.executable, 'setup.py',
+                               '-q', 'bdist_wheel'), cwd=source_dir)
+        yield glob.glob(os.path.join(source_dir, 'dist', '*.whl'))[0]
+
+
+def tree(root):
+    def depth(path):
+        return len(path.split(os.path.sep))
+    def prefix(path_depth):
+        if not path_depth:
+            return ''
+        return '|  ' * (path_depth - 1) + '|-- '
+    lines = []
+    root_depth = depth(root)
+    for dirpath, dirnames, filenames in os.walk(root):
+        dirnames.sort()
+        filenames.sort()
+        dir_depth = depth(dirpath) - root_depth
+        if dir_depth > 0:
+            lines.append('%s%s/' % (prefix(dir_depth - 1),
+                                    os.path.basename(dirpath)))
+        for f in filenames:
+            lines.append('%s%s' % (prefix(dir_depth), f))
+    return '\n'.join(lines) + '\n'
+
+
+def _check_wheel_install(filename, install_dir, install_tree,
+                         project_name, version, requires_txt):
+    w = Wheel(filename)
+    egg_path = os.path.join(install_dir, w.egg_name())
+    w.install_as_egg(egg_path)
+    if install_tree is not None:
+        install_tree = install_tree.format(
+            py_version=PY_MAJOR,
+            platform=get_platform(),
+            shlib_ext=get_config_var('EXT_SUFFIX') or get_config_var('SO')
+        )
+        assert install_tree == tree(install_dir)
+    metadata = PathMetadata(egg_path, os.path.join(egg_path, 'EGG-INFO'))
+    dist = Distribution.from_filename(egg_path, metadata=metadata)
+    assert dist.project_name == project_name
+    assert dist.version == version
+    if requires_txt is None:
+        assert not dist.has_metadata('requires.txt')
+    else:
+        assert requires_txt == dist.get_metadata('requires.txt').lstrip()
+
+
+class Record(object):
+
+    def __init__(self, id, **kwargs):
+        self._id = id
+        self._fields = kwargs
+
+    def __repr__(self):
+        return '%s(**%r)' % (self._id, self._fields)
+
+
+WHEEL_INSTALL_TESTS = (
+
+    dict(
+        id='basic',
+        file_defs={
+            'foo': {
+                '__init__.py': ''
+            }
+        },
+        setup_kwargs=dict(
+            packages=['foo'],
+        ),
+        install_tree=DALS(
+            '''
+            foo-1.0-py{py_version}.egg/
+            |-- EGG-INFO/
+            |  |-- DESCRIPTION.rst
+            |  |-- PKG-INFO
+            |  |-- RECORD
+            |  |-- WHEEL
+            |  |-- metadata.json
+            |  |-- top_level.txt
+            |-- foo/
+            |  |-- __init__.py
+            '''
+        ),
+    ),
+
+    dict(
+        id='utf-8',
+        setup_kwargs=dict(
+            description='Description accentuée',
+        )
+    ),
+
+    dict(
+        id='data',
+        file_defs={
+            'data.txt': DALS(
+                '''
+                Some data...
+                '''
+            ),
+        },
+        setup_kwargs=dict(
+            data_files=[('data_dir', ['data.txt'])],
+        ),
+        install_tree=DALS(
+            '''
+            foo-1.0-py{py_version}.egg/
+            |-- EGG-INFO/
+            |  |-- DESCRIPTION.rst
+            |  |-- PKG-INFO
+            |  |-- RECORD
+            |  |-- WHEEL
+            |  |-- metadata.json
+            |  |-- top_level.txt
+            |-- data_dir/
+            |  |-- data.txt
+            '''
+        ),
+    ),
+
+    dict(
+        id='extension',
+        file_defs={
+            'extension.c': DALS(
+                '''
+                #include "Python.h"
+
+                #if PY_MAJOR_VERSION >= 3
+
+                static struct PyModuleDef moduledef = {
+                        PyModuleDef_HEAD_INIT,
+                        "extension",
+                        NULL,
+                        0,
+                        NULL,
+                        NULL,
+                        NULL,
+                        NULL,
+                        NULL
+                };
+
+                #define INITERROR return NULL
+
+                PyMODINIT_FUNC PyInit_extension(void)
+
+                #else
+
+                #define INITERROR return
+
+                void initextension(void)
+
+                #endif
+                {
+                #if PY_MAJOR_VERSION >= 3
+                    PyObject *module = PyModule_Create(&moduledef);
+                #else
+                    PyObject *module = Py_InitModule("extension", NULL);
+                #endif
+                    if (module == NULL)
+                        INITERROR;
+                #if PY_MAJOR_VERSION >= 3
+                    return module;
+                #endif
+                }
+                '''
+            ),
+        },
+        setup_kwargs=dict(
+            ext_modules=[
+                Record('setuptools.Extension',
+                       name='extension',
+                       sources=['extension.c'])
+            ],
+        ),
+        install_tree=DALS(
+            '''
+            foo-1.0-py{py_version}-{platform}.egg/
+            |-- extension{shlib_ext}
+            |-- EGG-INFO/
+            |  |-- DESCRIPTION.rst
+            |  |-- PKG-INFO
+            |  |-- RECORD
+            |  |-- WHEEL
+            |  |-- metadata.json
+            |  |-- top_level.txt
+            '''
+        ),
+    ),
+
+    dict(
+        id='header',
+        file_defs={
+            'header.h': DALS(
+                '''
+                '''
+            ),
+        },
+        setup_kwargs=dict(
+            headers=['header.h'],
+        ),
+        install_tree=DALS(
+            '''
+            foo-1.0-py{py_version}.egg/
+            |-- header.h
+            |-- EGG-INFO/
+            |  |-- DESCRIPTION.rst
+            |  |-- PKG-INFO
+            |  |-- RECORD
+            |  |-- WHEEL
+            |  |-- metadata.json
+            |  |-- top_level.txt
+            '''
+        ),
+    ),
+
+    dict(
+        id='script',
+        file_defs={
+            'script.py': DALS(
+                '''
+                #/usr/bin/python
+                print('hello world!')
+                '''
+            ),
+            'script.sh': DALS(
+                '''
+                #/bin/sh
+                echo 'hello world!'
+                '''
+            ),
+        },
+        setup_kwargs=dict(
+            scripts=['script.py', 'script.sh'],
+        ),
+        install_tree=DALS(
+            '''
+            foo-1.0-py{py_version}.egg/
+            |-- EGG-INFO/
+            |  |-- DESCRIPTION.rst
+            |  |-- PKG-INFO
+            |  |-- RECORD
+            |  |-- WHEEL
+            |  |-- metadata.json
+            |  |-- top_level.txt
+            |  |-- scripts/
+            |  |  |-- script.py
+            |  |  |-- script.sh
+            '''
+        ),
+    ),
+
+    dict(
+        id='requires1',
+        install_requires='foobar==2.0',
+        install_tree=DALS(
+            '''
+            foo-1.0-py{py_version}.egg/
+            |-- EGG-INFO/
+            |  |-- DESCRIPTION.rst
+            |  |-- PKG-INFO
+            |  |-- RECORD
+            |  |-- WHEEL
+            |  |-- metadata.json
+            |  |-- requires.txt
+            |  |-- top_level.txt
+            '''),
+        requires_txt=DALS(
+            '''
+            foobar==2.0
+            '''
+        ),
+    ),
+
+    dict(
+        id='requires2',
+        install_requires='''
+        bar
+        foo<=2.0; %r in sys_platform
+        ''' % sys.platform,
+        requires_txt=DALS(
+            '''
+            bar
+            foo<=2.0
+            '''
+        ),
+    ),
+
+    dict(
+        id='requires3',
+        install_requires='''
+        bar; %r != sys_platform
+        ''' % sys.platform,
+    ),
+
+    dict(
+        id='requires4',
+        install_requires='''
+        foo
+        ''',
+        extras_require={
+            'extra': 'foobar>3',
+        },
+        requires_txt=DALS(
+            '''
+            foo
+
+            [extra]
+            foobar>3
+            '''
+        ),
+    ),
+
+    dict(
+        id='requires5',
+        extras_require={
+            'extra': 'foobar; %r != sys_platform' % sys.platform,
+        },
+        requires_txt=DALS(
+            '''
+            [extra]
+            '''
+        ),
+    ),
+
+    dict(
+        id='namespace_package',
+        file_defs={
+            'foo': {
+                'bar': {
+                    '__init__.py': ''
+                },
+            },
+        },
+        setup_kwargs=dict(
+            namespace_packages=['foo'],
+            packages=['foo.bar'],
+        ),
+        install_tree=DALS(
+            '''
+            foo-1.0-py{py_version}.egg/
+            |-- foo-1.0-py{py_version}-nspkg.pth
+            |-- EGG-INFO/
+            |  |-- DESCRIPTION.rst
+            |  |-- PKG-INFO
+            |  |-- RECORD
+            |  |-- WHEEL
+            |  |-- metadata.json
+            |  |-- namespace_packages.txt
+            |  |-- top_level.txt
+            |-- foo/
+            |  |-- __init__.py
+            |  |-- bar/
+            |  |  |-- __init__.py
+            '''),
+    ),
+
+    dict(
+        id='data_in_package',
+        file_defs={
+            'foo': {
+                '__init__.py': '',
+                'data_dir': {
+                    'data.txt': DALS(
+                        '''
+                        Some data...
+                        '''
+                    ),
+                }
+            }
+        },
+        setup_kwargs=dict(
+            packages=['foo'],
+            data_files=[('foo/data_dir', ['foo/data_dir/data.txt'])],
+        ),
+        install_tree=DALS(
+            '''
+            foo-1.0-py{py_version}.egg/
+            |-- EGG-INFO/
+            |  |-- DESCRIPTION.rst
+            |  |-- PKG-INFO
+            |  |-- RECORD
+            |  |-- WHEEL
+            |  |-- metadata.json
+            |  |-- top_level.txt
+            |-- foo/
+            |  |-- __init__.py
+            |  |-- data_dir/
+            |  |  |-- data.txt
+            '''
+        ),
+    ),
+
+)
+
+@pytest.mark.parametrize(
+    'params', WHEEL_INSTALL_TESTS,
+    ids=list(params['id'] for params in WHEEL_INSTALL_TESTS),
+)
+def test_wheel_install(params):
+    project_name = params.get('name', 'foo')
+    version = params.get('version', '1.0')
+    install_requires = params.get('install_requires', [])
+    extras_require = params.get('extras_require', {})
+    requires_txt = params.get('requires_txt', None)
+    install_tree = params.get('install_tree')
+    file_defs = params.get('file_defs', {})
+    setup_kwargs = params.get('setup_kwargs', {})
+    with build_wheel(
+        name=project_name,
+        version=version,
+        install_requires=install_requires,
+        extras_require=extras_require,
+        extra_file_defs=file_defs,
+        **setup_kwargs
+    ) as filename, tempdir() as install_dir:
+        _check_wheel_install(filename, install_dir,
+                             install_tree, project_name,
+                             version, requires_txt)
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/test_windows_wrappers.py b/vendor/setuptools-39.0.1/setuptools/tests/test_windows_wrappers.py
new file mode 100644
index 00000000..d2871c0f
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/test_windows_wrappers.py
@@ -0,0 +1,181 @@
+"""
+Python Script Wrapper for Windows
+=================================
+
+setuptools includes wrappers for Python scripts that allows them to be
+executed like regular windows programs.  There are 2 wrappers, one
+for command-line programs, cli.exe, and one for graphical programs,
+gui.exe.  These programs are almost identical, function pretty much
+the same way, and are generated from the same source file.  The
+wrapper programs are used by copying them to the directory containing
+the script they are to wrap and with the same name as the script they
+are to wrap.
+"""
+
+from __future__ import absolute_import
+
+import sys
+import textwrap
+import subprocess
+
+import pytest
+
+from setuptools.command.easy_install import nt_quote_arg
+import pkg_resources
+
+pytestmark = pytest.mark.skipif(sys.platform != 'win32', reason="Windows only")
+
+
+class WrapperTester:
+    @classmethod
+    def prep_script(cls, template):
+        python_exe = nt_quote_arg(sys.executable)
+        return template % locals()
+
+    @classmethod
+    def create_script(cls, tmpdir):
+        """
+        Create a simple script, foo-script.py
+
+        Note that the script starts with a Unix-style '#!' line saying which
+        Python executable to run.  The wrapper will use this line to find the
+        correct Python executable.
+        """
+
+        script = cls.prep_script(cls.script_tmpl)
+
+        with (tmpdir / cls.script_name).open('w') as f:
+            f.write(script)
+
+        # also copy cli.exe to the sample directory
+        with (tmpdir / cls.wrapper_name).open('wb') as f:
+            w = pkg_resources.resource_string('setuptools', cls.wrapper_source)
+            f.write(w)
+
+
+class TestCLI(WrapperTester):
+    script_name = 'foo-script.py'
+    wrapper_source = 'cli-32.exe'
+    wrapper_name = 'foo.exe'
+    script_tmpl = textwrap.dedent("""
+        #!%(python_exe)s
+        import sys
+        input = repr(sys.stdin.read())
+        print(sys.argv[0][-14:])
+        print(sys.argv[1:])
+        print(input)
+        if __debug__:
+            print('non-optimized')
+        """).lstrip()
+
+    def test_basic(self, tmpdir):
+        """
+        When the copy of cli.exe, foo.exe in this example, runs, it examines
+        the path name it was run with and computes a Python script path name
+        by removing the '.exe' suffix and adding the '-script.py' suffix. (For
+        GUI programs, the suffix '-script.pyw' is added.)  This is why we
+        named out script the way we did.  Now we can run out script by running
+        the wrapper:
+
+        This example was a little pathological in that it exercised windows
+        (MS C runtime) quoting rules:
+
+        - Strings containing spaces are surrounded by double quotes.
+
+        - Double quotes in strings need to be escaped by preceding them with
+          back slashes.
+
+        - One or more backslashes preceding double quotes need to be escaped
+          by preceding each of them with back slashes.
+        """
+        self.create_script(tmpdir)
+        cmd = [
+            str(tmpdir / 'foo.exe'),
+            'arg1',
+            'arg 2',
+            'arg "2\\"',
+            'arg 4\\',
+            'arg5 a\\\\b',
+        ]
+        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
+        stdout, stderr = proc.communicate('hello\nworld\n'.encode('ascii'))
+        actual = stdout.decode('ascii').replace('\r\n', '\n')
+        expected = textwrap.dedent(r"""
+            \foo-script.py
+            ['arg1', 'arg 2', 'arg "2\\"', 'arg 4\\', 'arg5 a\\\\b']
+            'hello\nworld\n'
+            non-optimized
+            """).lstrip()
+        assert actual == expected
+
+    def test_with_options(self, tmpdir):
+        """
+        Specifying Python Command-line Options
+        --------------------------------------
+
+        You can specify a single argument on the '#!' line.  This can be used
+        to specify Python options like -O, to run in optimized mode or -i
+        to start the interactive interpreter.  You can combine multiple
+        options as usual. For example, to run in optimized mode and
+        enter the interpreter after running the script, you could use -Oi:
+        """
+        self.create_script(tmpdir)
+        tmpl = textwrap.dedent("""
+            #!%(python_exe)s  -Oi
+            import sys
+            input = repr(sys.stdin.read())
+            print(sys.argv[0][-14:])
+            print(sys.argv[1:])
+            print(input)
+            if __debug__:
+                print('non-optimized')
+            sys.ps1 = '---'
+            """).lstrip()
+        with (tmpdir / 'foo-script.py').open('w') as f:
+            f.write(self.prep_script(tmpl))
+        cmd = [str(tmpdir / 'foo.exe')]
+        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
+        stdout, stderr = proc.communicate()
+        actual = stdout.decode('ascii').replace('\r\n', '\n')
+        expected = textwrap.dedent(r"""
+            \foo-script.py
+            []
+            ''
+            ---
+            """).lstrip()
+        assert actual == expected
+
+
+class TestGUI(WrapperTester):
+    """
+    Testing the GUI Version
+    -----------------------
+    """
+    script_name = 'bar-script.pyw'
+    wrapper_source = 'gui-32.exe'
+    wrapper_name = 'bar.exe'
+
+    script_tmpl = textwrap.dedent("""
+        #!%(python_exe)s
+        import sys
+        f = open(sys.argv[1], 'wb')
+        bytes_written = f.write(repr(sys.argv[2]).encode('utf-8'))
+        f.close()
+        """).strip()
+
+    def test_basic(self, tmpdir):
+        """Test the GUI version with the simple scipt, bar-script.py"""
+        self.create_script(tmpdir)
+
+        cmd = [
+            str(tmpdir / 'bar.exe'),
+            str(tmpdir / 'test_output.txt'),
+            'Test Argument',
+        ]
+        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
+        stdout, stderr = proc.communicate()
+        assert not stdout
+        assert not stderr
+        with (tmpdir / 'test_output.txt').open('rb') as f_out:
+            actual = f_out.read().decode('ascii')
+        assert actual == repr('Test Argument')
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/text.py b/vendor/setuptools-39.0.1/setuptools/tests/text.py
new file mode 100644
index 00000000..ad2c6249
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/text.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import unicode_literals
+
+
+class Filenames:
+    unicode = 'smörbröd.py'
+    latin_1 = unicode.encode('latin-1')
+    utf_8 = unicode.encode('utf-8')
diff --git a/vendor/setuptools-39.0.1/setuptools/tests/textwrap.py b/vendor/setuptools-39.0.1/setuptools/tests/textwrap.py
new file mode 100644
index 00000000..5cd9e5bc
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/tests/textwrap.py
@@ -0,0 +1,8 @@
+from __future__ import absolute_import
+
+import textwrap
+
+
+def DALS(s):
+    "dedent and left-strip"
+    return textwrap.dedent(s).lstrip()
diff --git a/vendor/setuptools-39.0.1/setuptools/unicode_utils.py b/vendor/setuptools-39.0.1/setuptools/unicode_utils.py
new file mode 100644
index 00000000..7c63efd2
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/unicode_utils.py
@@ -0,0 +1,44 @@
+import unicodedata
+import sys
+
+from setuptools.extern import six
+
+
+# HFS Plus uses decomposed UTF-8
+def decompose(path):
+    if isinstance(path, six.text_type):
+        return unicodedata.normalize('NFD', path)
+    try:
+        path = path.decode('utf-8')
+        path = unicodedata.normalize('NFD', path)
+        path = path.encode('utf-8')
+    except UnicodeError:
+        pass  # Not UTF-8
+    return path
+
+
+def filesys_decode(path):
+    """
+    Ensure that the given path is decoded,
+    NONE when no expected encoding works
+    """
+
+    if isinstance(path, six.text_type):
+        return path
+
+    fs_enc = sys.getfilesystemencoding() or 'utf-8'
+    candidates = fs_enc, 'utf-8'
+
+    for enc in candidates:
+        try:
+            return path.decode(enc)
+        except UnicodeDecodeError:
+            continue
+
+
+def try_encode(string, enc):
+    "turn unicode encoding into a functional routine"
+    try:
+        return string.encode(enc)
+    except UnicodeEncodeError:
+        return None
diff --git a/vendor/setuptools-39.0.1/setuptools/version.py b/vendor/setuptools-39.0.1/setuptools/version.py
new file mode 100644
index 00000000..95e18696
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/version.py
@@ -0,0 +1,6 @@
+import pkg_resources
+
+try:
+    __version__ = pkg_resources.get_distribution('setuptools').version
+except Exception:
+    __version__ = 'unknown'
diff --git a/vendor/setuptools-39.0.1/setuptools/wheel.py b/vendor/setuptools-39.0.1/setuptools/wheel.py
new file mode 100644
index 00000000..37dfa531
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/wheel.py
@@ -0,0 +1,163 @@
+'''Wheels support.'''
+
+from distutils.util import get_platform
+import email
+import itertools
+import os
+import re
+import zipfile
+
+from pkg_resources import Distribution, PathMetadata, parse_version
+from setuptools.extern.six import PY3
+from setuptools import Distribution as SetuptoolsDistribution
+from setuptools import pep425tags
+from setuptools.command.egg_info import write_requirements
+
+
+WHEEL_NAME = re.compile(
+    r"""^(?P<project_name>.+?)-(?P<version>\d.*?)
+    ((-(?P<build>\d.*?))?-(?P<py_version>.+?)-(?P<abi>.+?)-(?P<platform>.+?)
+    )\.whl$""",
+re.VERBOSE).match
+
+NAMESPACE_PACKAGE_INIT = '''\
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    __path__ = __import__('pkgutil').extend_path(__path__, __name__)
+'''
+
+
+def unpack(src_dir, dst_dir):
+    '''Move everything under `src_dir` to `dst_dir`, and delete the former.'''
+    for dirpath, dirnames, filenames in os.walk(src_dir):
+        subdir = os.path.relpath(dirpath, src_dir)
+        for f in filenames:
+            src = os.path.join(dirpath, f)
+            dst = os.path.join(dst_dir, subdir, f)
+            os.renames(src, dst)
+        for n, d in reversed(list(enumerate(dirnames))):
+            src = os.path.join(dirpath, d)
+            dst = os.path.join(dst_dir, subdir, d)
+            if not os.path.exists(dst):
+                # Directory does not exist in destination,
+                # rename it and prune it from os.walk list.
+                os.renames(src, dst)
+                del dirnames[n]
+    # Cleanup.
+    for dirpath, dirnames, filenames in os.walk(src_dir, topdown=True):
+        assert not filenames
+        os.rmdir(dirpath)
+
+
+class Wheel(object):
+
+    def __init__(self, filename):
+        match = WHEEL_NAME(os.path.basename(filename))
+        if match is None:
+            raise ValueError('invalid wheel name: %r' % filename)
+        self.filename = filename
+        for k, v in match.groupdict().items():
+            setattr(self, k, v)
+
+    def tags(self):
+        '''List tags (py_version, abi, platform) supported by this wheel.'''
+        return itertools.product(self.py_version.split('.'),
+                                 self.abi.split('.'),
+                                 self.platform.split('.'))
+
+    def is_compatible(self):
+        '''Is the wheel is compatible with the current platform?'''
+        supported_tags = pep425tags.get_supported()
+        return next((True for t in self.tags() if t in supported_tags), False)
+
+    def egg_name(self):
+        return Distribution(
+            project_name=self.project_name, version=self.version,
+            platform=(None if self.platform == 'any' else get_platform()),
+        ).egg_name() + '.egg'
+
+    def install_as_egg(self, destination_eggdir):
+        '''Install wheel as an egg directory.'''
+        with zipfile.ZipFile(self.filename) as zf:
+            dist_basename = '%s-%s' % (self.project_name, self.version)
+            dist_info = '%s.dist-info' % dist_basename
+            dist_data = '%s.data' % dist_basename
+            def get_metadata(name):
+                with zf.open('%s/%s' % (dist_info, name)) as fp:
+                    value = fp.read().decode('utf-8') if PY3 else fp.read()
+                    return email.parser.Parser().parsestr(value)
+            wheel_metadata = get_metadata('WHEEL')
+            dist_metadata = get_metadata('METADATA')
+            # Check wheel format version is supported.
+            wheel_version = parse_version(wheel_metadata.get('Wheel-Version'))
+            if not parse_version('1.0') <= wheel_version < parse_version('2.0dev0'):
+                raise ValueError('unsupported wheel format version: %s' % wheel_version)
+            # Extract to target directory.
+            os.mkdir(destination_eggdir)
+            zf.extractall(destination_eggdir)
+            # Convert metadata.
+            dist_info = os.path.join(destination_eggdir, dist_info)
+            dist = Distribution.from_location(
+                destination_eggdir, dist_info,
+                metadata=PathMetadata(destination_eggdir, dist_info)
+            )
+            # Note: we need to evaluate and strip markers now,
+            # as we can't easily convert back from the syntax:
+            # foobar; "linux" in sys_platform and extra == 'test'
+            def raw_req(req):
+                req.marker = None
+                return str(req)
+            install_requires = list(sorted(map(raw_req, dist.requires())))
+            extras_require = {
+                extra: list(sorted(
+                    req
+                    for req in map(raw_req, dist.requires((extra,)))
+                    if req not in install_requires
+                ))
+                for extra in dist.extras
+            }
+            egg_info = os.path.join(destination_eggdir, 'EGG-INFO')
+            os.rename(dist_info, egg_info)
+            os.rename(os.path.join(egg_info, 'METADATA'),
+                      os.path.join(egg_info, 'PKG-INFO'))
+            setup_dist = SetuptoolsDistribution(attrs=dict(
+                install_requires=install_requires,
+                extras_require=extras_require,
+            ))
+            write_requirements(setup_dist.get_command_obj('egg_info'),
+                               None, os.path.join(egg_info, 'requires.txt'))
+            # Move data entries to their correct location.
+            dist_data = os.path.join(destination_eggdir, dist_data)
+            dist_data_scripts = os.path.join(dist_data, 'scripts')
+            if os.path.exists(dist_data_scripts):
+                egg_info_scripts = os.path.join(destination_eggdir,
+                                                'EGG-INFO', 'scripts')
+                os.mkdir(egg_info_scripts)
+                for entry in os.listdir(dist_data_scripts):
+                    # Remove bytecode, as it's not properly handled
+                    # during easy_install scripts install phase.
+                    if entry.endswith('.pyc'):
+                        os.unlink(os.path.join(dist_data_scripts, entry))
+                    else:
+                        os.rename(os.path.join(dist_data_scripts, entry),
+                                  os.path.join(egg_info_scripts, entry))
+                os.rmdir(dist_data_scripts)
+            for subdir in filter(os.path.exists, (
+                os.path.join(dist_data, d)
+                for d in ('data', 'headers', 'purelib', 'platlib')
+            )):
+                unpack(subdir, destination_eggdir)
+            if os.path.exists(dist_data):
+                os.rmdir(dist_data)
+            # Fix namespace packages.
+            namespace_packages = os.path.join(egg_info, 'namespace_packages.txt')
+            if os.path.exists(namespace_packages):
+                with open(namespace_packages) as fp:
+                    namespace_packages = fp.read().split()
+                for mod in namespace_packages:
+                    mod_dir = os.path.join(destination_eggdir, *mod.split('.'))
+                    mod_init = os.path.join(mod_dir, '__init__.py')
+                    if os.path.exists(mod_dir) and not os.path.exists(mod_init):
+                        with open(mod_init, 'w') as fp:
+                            fp.write(NAMESPACE_PACKAGE_INIT)
diff --git a/vendor/setuptools-39.0.1/setuptools/windows_support.py b/vendor/setuptools-39.0.1/setuptools/windows_support.py
new file mode 100644
index 00000000..cb977cff
--- /dev/null
+++ b/vendor/setuptools-39.0.1/setuptools/windows_support.py
@@ -0,0 +1,29 @@
+import platform
+import ctypes
+
+
+def windows_only(func):
+    if platform.system() != 'Windows':
+        return lambda *args, **kwargs: None
+    return func
+
+
+@windows_only
+def hide_file(path):
+    """
+    Set the hidden attribute on a file or directory.
+
+    From http://stackoverflow.com/questions/19622133/
+
+    `path` must be text.
+    """
+    __import__('ctypes.wintypes')
+    SetFileAttributes = ctypes.windll.kernel32.SetFileAttributesW
+    SetFileAttributes.argtypes = ctypes.wintypes.LPWSTR, ctypes.wintypes.DWORD
+    SetFileAttributes.restype = ctypes.wintypes.BOOL
+
+    FILE_ATTRIBUTE_HIDDEN = 0x02
+
+    ret = SetFileAttributes(path, FILE_ATTRIBUTE_HIDDEN)
+    if not ret:
+        raise ctypes.WinError()
diff --git a/vendor/setuptools-39.0.1/tests/manual_test.py b/vendor/setuptools-39.0.1/tests/manual_test.py
new file mode 100644
index 00000000..e5aaf179
--- /dev/null
+++ b/vendor/setuptools-39.0.1/tests/manual_test.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+
+import sys
+import os
+import shutil
+import tempfile
+import subprocess
+from distutils.command.install import INSTALL_SCHEMES
+from string import Template
+
+from six.moves import urllib
+
+
+def _system_call(*args):
+    assert subprocess.call(args) == 0
+
+
+def tempdir(func):
+    def _tempdir(*args, **kwargs):
+        test_dir = tempfile.mkdtemp()
+        old_dir = os.getcwd()
+        os.chdir(test_dir)
+        try:
+            return func(*args, **kwargs)
+        finally:
+            os.chdir(old_dir)
+            shutil.rmtree(test_dir)
+
+    return _tempdir
+
+
+SIMPLE_BUILDOUT = """\
+[buildout]
+
+parts = eggs
+
+[eggs]
+recipe = zc.recipe.egg
+
+eggs =
+    extensions
+"""
+
+BOOTSTRAP = 'http://downloads.buildout.org/1/bootstrap.py'
+PYVER = sys.version.split()[0][:3]
+
+_VARS = {'base': '.',
+         'py_version_short': PYVER}
+
+scheme = 'nt' if sys.platform == 'win32' else 'unix_prefix'
+PURELIB = INSTALL_SCHEMES[scheme]['purelib']
+
+
+@tempdir
+def test_virtualenv():
+    """virtualenv with setuptools"""
+    purelib = os.path.abspath(Template(PURELIB).substitute(**_VARS))
+    _system_call('virtualenv', '--no-site-packages', '.')
+    _system_call('bin/easy_install', 'setuptools==dev')
+    # linux specific
+    site_pkg = os.listdir(purelib)
+    site_pkg.sort()
+    assert 'setuptools' in site_pkg[0]
+    easy_install = os.path.join(purelib, 'easy-install.pth')
+    with open(easy_install) as f:
+        res = f.read()
+    assert 'setuptools' in res
+
+
+@tempdir
+def test_full():
+    """virtualenv + pip + buildout"""
+    _system_call('virtualenv', '--no-site-packages', '.')
+    _system_call('bin/easy_install', '-q', 'setuptools==dev')
+    _system_call('bin/easy_install', '-qU', 'setuptools==dev')
+    _system_call('bin/easy_install', '-q', 'pip')
+    _system_call('bin/pip', 'install', '-q', 'zc.buildout')
+
+    with open('buildout.cfg', 'w') as f:
+        f.write(SIMPLE_BUILDOUT)
+
+    with open('bootstrap.py', 'w') as f:
+        f.write(urllib.request.urlopen(BOOTSTRAP).read())
+
+    _system_call('bin/python', 'bootstrap.py')
+    _system_call('bin/buildout', '-q')
+    eggs = os.listdir('eggs')
+    eggs.sort()
+    assert len(eggs) == 3
+    assert eggs[1].startswith('setuptools')
+    del eggs[1]
+    assert eggs == ['extensions-0.3-py2.6.egg',
+        'zc.recipe.egg-1.2.2-py2.6.egg']
+
+
+if __name__ == '__main__':
+    test_virtualenv()
+    test_full()
diff --git a/vendor/setuptools-39.0.1/tests/test_pypi.py b/vendor/setuptools-39.0.1/tests/test_pypi.py
new file mode 100644
index 00000000..b3425e53
--- /dev/null
+++ b/vendor/setuptools-39.0.1/tests/test_pypi.py
@@ -0,0 +1,82 @@
+import os
+import subprocess
+
+import virtualenv
+from setuptools.extern.six.moves import http_client
+from setuptools.extern.six.moves import xmlrpc_client
+
+TOP = 200
+PYPI_HOSTNAME = 'pypi.python.org'
+
+
+def rpc_pypi(method, *args):
+    """Call an XML-RPC method on the Pypi server."""
+    conn = http_client.HTTPSConnection(PYPI_HOSTNAME)
+    headers = {'Content-Type': 'text/xml'}
+    payload = xmlrpc_client.dumps(args, method)
+
+    conn.request("POST", "/pypi", payload, headers)
+    response = conn.getresponse()
+    if response.status == 200:
+        result = xmlrpc_client.loads(response.read())[0][0]
+        return result
+    else:
+        raise RuntimeError("Unable to download the list of top "
+                           "packages from Pypi.")
+
+
+def get_top_packages(limit):
+    """Collect the name of the top packages on Pypi."""
+    packages = rpc_pypi('top_packages')
+    return packages[:limit]
+
+
+def _package_install(package_name, tmp_dir=None, local_setuptools=True):
+    """Try to install a package and return the exit status.
+
+    This function creates a virtual environment, install setuptools using pip
+    and then install the required package. If local_setuptools is True, it
+    will install the local version of setuptools.
+    """
+    package_dir = os.path.join(tmp_dir, "test_%s" % package_name)
+    if not local_setuptools:
+        package_dir = package_dir + "_baseline"
+
+    virtualenv.create_environment(package_dir)
+
+    pip_path = os.path.join(package_dir, "bin", "pip")
+    if local_setuptools:
+        subprocess.check_call([pip_path, "install", "."])
+    returncode = subprocess.call([pip_path, "install", package_name])
+    return returncode
+
+
+def test_package_install(package_name, tmpdir):
+    """Test to verify the outcome of installing a package.
+
+    This test compare that the return code when installing a package is the
+    same as with the current stable version of setuptools.
+    """
+    new_exit_status = _package_install(package_name, tmp_dir=str(tmpdir))
+    if new_exit_status:
+        print("Installation failed, testing against stable setuptools",
+              package_name)
+        old_exit_status = _package_install(package_name, tmp_dir=str(tmpdir),
+                                           local_setuptools=False)
+        assert new_exit_status == old_exit_status
+
+
+def pytest_generate_tests(metafunc):
+    """Generator function for test_package_install.
+
+    This function will generate calls to test_package_install. If a package
+    list has been specified on the command line, it will be used. Otherwise,
+    Pypi will be queried to get the current list of top packages.
+    """
+    if "package_name" in metafunc.fixturenames:
+        if not metafunc.config.option.package_name:
+            packages = get_top_packages(TOP)
+            packages = [name for name, downloads in packages]
+        else:
+            packages = metafunc.config.option.package_name
+        metafunc.parametrize("package_name", packages)
diff --git a/vendor/setuptools-39.0.1/tox.ini b/vendor/setuptools-39.0.1/tox.ini
new file mode 100644
index 00000000..2f7d4dc8
--- /dev/null
+++ b/vendor/setuptools-39.0.1/tox.ini
@@ -0,0 +1,11 @@
+# Note: Run "python bootstrap.py" before running Tox, to generate metadata.
+#
+# To run Tox against all supported Python interpreters, you can set:
+#
+# export TOXENV='py27,py3{3,4,5,6},pypy,pypy3'
+
+[testenv]
+deps=-rtests/requirements.txt
+passenv=APPDATA USERPROFILE HOMEDRIVE HOMEPATH windir APPVEYOR
+commands=py.test {posargs}
+usedevelop=True
-- 
GitLab