text: 
  """
  Listing of current dependencies for CCTBX and related applications (including
  LABELIT, xia2, DIALS, and Phenix with GUI).  Not all of these can be downloaded
  via the web (yet).
  """
  
  from __future__ import absolute_import, division, print_function
  
  import json
  import os
  import os.path as op
  import sys
  try: # Python 3
    from urllib.request import urlopen
  except ImportError: # Python 2
    from urllib2 import urlopen
  
  try:
    from .bootstrap import Toolbox
    from .installer_utils import *
  except (ValueError, ImportError):
    # When run from bootstrap the auto_build directory will be in the path
    from bootstrap import Toolbox
    from installer_utils import *
  
  BASE_CCI_PKG_URL = [
    "http://cci.lbl.gov/cctbx_dependencies",
    "https://gitcdn.link/repo/dials/dependencies/master",
    "https://github.com/dials/dependencies/raw/master",
  ]
  
  def get_pypi_package_information(package, version=None, information_only=False):
    '''Retrieve information about a PyPi package.'''
    metadata = 'https://pypi.python.org/pypi/' + package + '/json'
    try:
      pypidata = urlopen(metadata).read()
    except Exception: # TLS <1.2, ...
      if information_only:
        return {'name': '', 'version': '', 'summary': ''}
      raise
    pkginfo = json.loads(pypidata)
    if information_only:
      return pkginfo['info']
    if not version:
      version = pkginfo['info']['version']
    if version not in pkginfo['releases']:
      raise RuntimeError("Could not find release '%s' for %s on pypi." % (version, package))
    candidates = filter(lambda c: c.get('python_version') == 'source' and c.get('packagetype') == 'sdist', pkginfo['releases'][version])
    if not candidates:
      raise RuntimeError("Could not find a source release file for %s %s on pypi." % (package, version))
    package = candidates[0]
    for field in ('name', 'version', 'summary'):
      package[field] = pkginfo['info'][field]
    return package
  
  DEPENDENCIES_BASE = [
    "https://gitcdn.link/repo/dials/dependencies/master",
    "https://github.com/dials/dependencies/raw/master",
    "https://gitcdn.xyz/repo/dials/dependencies/master",
  ]
  OPENSSL_PKG = "openssl-1.0.2s.tar.gz"    # OpenSSL
  PYTHON3_PKG = "Python-3.7.2.tgz"
  PYTHON_PKG = "Python-2.7.18.tgz"
  
  # from CCI
  IMAGING_PKG = "Imaging-1.1.7.tar.gz"     # for labelit, gltbx
  REPORTLAB_PKG = "reportlab-3.5.12.tar.gz"   # for labelit
  ZLIB_PKG = "zlib-1.2.11.tar.gz"
  PYRTF_PKG = "PyRTF-0.45.tar.gz"          # for phenix.table_one, etc.
  BIOPYTHON_PKG = "biopython-1.73.tar.gz"  # used in iotbx
  IPYTHON_PKG = "ipython-5.8.0.tar.gz"     # IPython
  LIBSVM_PKG = "libsvm-3.17_cci.tar.gz"
  
  # from PyPi
  CYTHON_VERSION = "0.28.6"
  DOCUTILS_VERSION = "0.14"
  FUTURE_VERSION = "0.17.1"
  H5PY_VERSION = "2.10.0"
  JINJA2_VERSION = "2.10"
  MOCK_VERSION = "3.0.5"
  MPI4PY_VERSION = "3.0.0"
  MRCFILE_VERSION = "1.1.2"
  MSGPACK_VERSION = "0.6.1"
  NUMPY_VERSION="1.15.4"
  ORDEREDSET_VERSION = "2.0.1"
  PILLOW_VERSION = "5.4.1"
  PROCRUNNER_VERSION = "1.0.2"
  PY2APP_VERSION="0.7.3"
  PYTEST_VERSION = "4.6.5"
  PYTEST_XDIST_VERSION = "1.29.0"
  SCIKIT_LEARN_VERSION = "0.20.2"
  SCIPY_VERSION = "1.2.1"
  SEND2TRASH_VERSION = "1.5.0"
  SIX_VERSION = "1.12.0"
  SPHINX_VERSION = "1.8.4" # for documentation
  TABULATE_VERSION = "0.8.3"
  TQDM_VERSION = "4.23.4"
  PSUTIL_VERSION = "5.5.1"
  
  # HDF5
  BASE_HDF5_PKG_URL = "https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.10/hdf5-1.10.5/src/"
  HDF5_PKG = "hdf5-1.10.5.tar.bz2"
  
  # GUI dependencies
  LIBPNG_PKG = "libpng-1.6.36.tar.gz"
  FREETYPE_PKG = "freetype-2.6.3.tar.gz"
  
  # Linux-only
  # libraries based on X11R7.7 (http://www.x.org/releases/X11R7.7/src/everything/)
  WXPYTHON_PKG = "wxPython-src-3.0.2.0.tar.bz2"
  GETTEXT_PKG = "gettext-0.19.7.tar.gz"
  LIBFFI_PKG = "libffi-3.2.1.tar.gz"
  GLIB_PKG = "glib-2.46.2.tar.gz"
  EXPAT_PKG = "expat-2.1.0.tar.gz"
  FONTCONFIG_PKG = "fontconfig-2.11.1.tar.gz"
  RENDER_PKG = "renderproto-0.11.1.tar.gz"
  XRENDER_PKG = "libXrender-0.9.7.tar.gz"
  XFT_PKG = "libXft-2.3.2.tar.gz"
  
  CAIRO_PKG = "cairo-1.14.4.tar.gz"
  PIXMAN_PKG = "pixman-0.34.0.tar.gz"
  HARFBUZZ_PKG = "harfbuzz-1.1.3.tar.gz"
  GDK_PIXBUF_PKG = "gdk-pixbuf-2.32.3.tar.gz"
  PANGO_PKG = "pango-1.38.1.tar.gz"
  ATK_PKG = "atk-2.18.0.tar.gz"
  TIFF_PKG = "tiff-4.0.10.tar.gz"
  GTK_PKG = "gtk+-2.24.29.tar.gz"
  GTK_ENGINE_PKG = "clearlooks-0.6.2.tar.gz"
  GTK_THEME_PKG = "gtk_themes.tar.gz"
  # end Linux-only
  FONT_PKG = "fonts.tar.gz"
  
  MATPLOTLIB_PKG = "matplotlib-2.2.3.tar.gz"
  MATPLOTLIB_DEPS = [
    ("subprocess32", "3.5.4"),
    ("backports.functools-lru-cache", "1.6.1"),
    ("kiwisolver", "1.1.0"),
  ]
  
  PYOPENGL_PKG = "PyOpenGL-3.1.0.tar.gz"
  
  # Windows precompiled compiled base packages
  WIN64PYTHON_PKG = "Python2.7.15_x86_64_plus_relocatable.zip"
  WIN32PYTHON_PKG = "python2.7.12_x86_32_plus_relocatable.zip"
  WIN64HDF5_PKG = "HDF5-1.8.16-win64.zip"
  WIN32HDF5_PKG = "HDF5-1.8.16-win32.zip"
  VCREDIST64 = "vcredist_x64.exe"
  VCREDIST32 = "vcredist_x86.exe"
  WINLIBTIFF64 = "libtiff4.0.6x64.zip"
  WINLIBTIFF32 = "libtiff4.0.6x32.zip"
  
  # Various dependencies from external repositories, distributed as static
  # tarballs (since they are not under active development by us or our
  # collaborators)
  dependency_tarballs = {
    "scons":  ("http://cci.lbl.gov/hot", "scons_hot.tar.gz"),
  }
  # External SVN repositories that may be required for certain components of
  # CCTBX to work.  This includes forked versions (with minimal changes) of the
  # core CCP4 libraries, MUSCLE, and ksDSSP.
  subversion_repositories = {
    "ccp4io": "http://cci.lbl.gov/svn/ccp4io/trunk",
    "ccp4io_adaptbx": "http://cci.lbl.gov/svn/ccp4io_adaptbx/trunk",
    "gui_resources": "http://cci.lbl.gov/svn/gui_resources/trunk",
    "tntbx": "http://cci.lbl.gov/svn/tntbx/trunk",
    "ksdssp": "http://cci.lbl.gov/svn/ksdssp/trunk",
    "muscle": "http://cci.lbl.gov/svn/muscle/trunk",
    # adding for amber
    "amber_adaptbx": "http://cci.lbl.gov/svn/amber_adaptbx/trunk",
  }
  
  # External GIT repositories that may be required for certain components of
  # CCTBX to work. Note that the format for git repositories can be more
  # sophisticated than that for SVN, and can include multiple possible sources,
  # including .zip archives to fall back on when git is not available, and git
  # command line parameters
  git_repositories = {
    # lz4 and bitshuffle compressions for HDF5
    # The git repositories are disabled for both on purpose.
    # Reason: Repositories are deprecated and unlikely to change ever again.
    #         We currently patch the local copies of the repositories, which means
    #         that if they are cloned git repositories you cannot run bootstrap on
    #         them again without bootstrap detecting uncommitted changes and
    #         stopping with an error message.
    "hdf5_lz4": [#'git@github.com:dectris/HDF5Plugin.git',
                 #'https://github.com/dectris/HDF5Plugin.git',
                 'https://github.com/dectris/HDF5Plugin/archive/master.zip'],
    "bitshuffle": [#'git@github.com:kiyo-masui/bitshuffle.git',
                   #'https://github.com/kiyo-masui/bitshuffle.git',
                   'https://github.com/kiyo-masui/bitshuffle/archive/master.zip'],
  }
  
  class fetch_packages(object):
    """
    Download manager for the packages defined by this module - this is used by
    install_base_packages.py but also for setting up installer bundles.
    """
    def __init__(self, dest_dir, log, pkg_dirs=None, no_download=False,
        copy_files=False):
      self.dest_dir = dest_dir
      self.log = log
      self.pkg_dirs = pkg_dirs
      self.no_download = no_download
      self.copy_files = copy_files
      self.toolbox = Toolbox()
  
    def __call__(self,
                  pkg_name,
                  pkg_url=None,
                  output_file=None,
                  return_file_and_status=False,
                  download_url=None, # If given this is the URL used for downloading, otherwise construct using pkg_url and pkg_name
                  ):
      if (pkg_url is None):
        pkg_url = BASE_CCI_PKG_URL
      if (output_file is None):
        output_file = pkg_name
      os.chdir(self.dest_dir)
      print("  getting package %s..." % pkg_name, file=self.log)
      if (self.pkg_dirs is not None) and (len(self.pkg_dirs) > 0):
        for pkg_dir in self.pkg_dirs :
          static_file = op.join(pkg_dir, pkg_name)
          if (op.exists(static_file)):
            print("    using %s" % static_file, file=self.log)
            if self.copy_files :
              copy_file(static_file, op.join(self.dest_dir, output_file))
              if return_file_and_status:
                return op.join(self.dest_dir, output_file), 0
              return op.join(self.dest_dir, output_file)
            else :
              if return_file_and_status:
                return static_file, 0
              return static_file
      if (self.no_download):
        if (op.exists(pkg_name)):
          print("    using ./%s" % pkg_name, file=self.log)
          if return_file_and_status:
            return op.join(self.dest_dir, output_file), 0
          return op.join(self.dest_dir, pkg_name)
        else :
          raise RuntimeError(("Package '%s' not found on local filesystems.  ") %
            pkg_name)
  
      # Generate list of possible URL candidates
      if download_url:
        if isinstance(download_url, list):
          urls = download_url
        else:
          urls = [download_url]
      else:
        if isinstance(pkg_url, list):
          urls = ["%s/%s" % (p, pkg_name) for p in pkg_url]
        else:
          urls = ["%s/%s" % (pkg_url, pkg_name)]
  
      for url_attempt in urls:
        self.log.write("    downloading from %s : " % url_attempt)
        for retry in (3,3,0):
          try:
            size = self.toolbox.download_to_file(url_attempt, output_file, log=self.log)
            if (size == -2):
              print("    using ./%s (cached)" % pkg_name, file=self.log)
              if return_file_and_status:
                return op.join(self.dest_dir, output_file), size
              return op.join(self.dest_dir, output_file)
            assert size > 0, "File %s has size %d" % (pkg_name, size)
            if return_file_and_status:
              return op.join(self.dest_dir, output_file), size
            return op.join(self.dest_dir, output_file)
          except Exception as e:
            self.log.write("    download failed with %s" % str(e))
            if retry:
              self.log.write("    retrying in %d seconds" % retry)
              time.sleep(retry)
      raise RuntimeError("Could not download " + pkg_name)
  
  def fetch_all_dependencies(dest_dir,
      log,
      pkg_dirs=None,
      copy_files=True,
      gui_packages=True,
      dials_packages=True):
    """
    Download or copy all dependencies into a local directory (prepping for
    source installer bundling).
    """
    fetch_package = fetch_packages(
      dest_dir=dest_dir,
      log=log,
      pkg_dirs=pkg_dirs,
      copy_files=copy_files)
    for pkg_name in [
        PYTHON_PKG, IMAGING_PKG, REPORTLAB_PKG, ZLIB_PKG,
        PYRTF_PKG, BIOPYTHON_PKG,
        IPYTHON_PKG,
      ] :
      fetch_package(pkg_name)
    if (gui_packages):
      for pkg_name in [
          LIBPNG_PKG, FREETYPE_PKG, GETTEXT_PKG, GLIB_PKG, EXPAT_PKG,
          FONTCONFIG_PKG, RENDER_PKG, XRENDER_PKG, XFT_PKG, PIXMAN_PKG,
          CAIRO_PKG, HARFBUZZ_PKG, PANGO_PKG, ATK_PKG, TIFF_PKG, GTK_PKG,
          GTK_ENGINE_PKG, GTK_THEME_PKG, FONT_PKG, WXPYTHON_PKG,
          MATPLOTLIB_PKG, SEND2TRASH_PKG,
        ] :
        fetch_package(pkg_name)
  
  def fetch_svn_repository(pkg_name, pkg_url=None, working_copy=True,
      delete_if_present=False):
    """
    Download an SVN repository, with or without metadata required for ongoing
    development.
    """
    ## TODO: Merge this with _add_svn in bootstrap.py.
    #        Unnecessary code duplication
    if op.exists(pkg_name):
      if delete_if_present :
        shutil.rmtree(pkg_name)
      else :
        raise OSError("Directory '%s' already exists.")
    if (pkg_url is None):
      pkg_url = optional_repositories[pkg_name]
    if working_copy :
      call("svn co --non-interactive --trust-server-cert %s %s" % (pkg_url, pkg_name), sys.stdout)
    else :
      call("svn export --non-interactive --trust-server-cert %s %s" % (pkg_url, pkg_name), sys.stdout)
    assert op.isdir(pkg_name)
  
  def fetch_git_repository(package, use_ssh):
    """ Download a git repository """
    Toolbox.git(package, git_repositories[package], destination=os.path.join(os.getcwd(), package), use_ssh=use_ssh, verbose=True)
    assert op.isdir(package)
  
  def fetch_remote_package(module_name, log=sys.stdout, working_copy=False, use_ssh=False):
    if (module_name in git_repositories):
      fetch_git_repository(module_name, use_ssh)
    elif (module_name in dependency_tarballs):
      if op.isdir(module_name):
        shutil.rmtree(module_name)
      pkg_url, pkg_name = dependency_tarballs[module_name]
      tarfile = module_name + ".tar.gz"
      fetch_packages(
        dest_dir=os.getcwd(),
        log=log).__call__(
          pkg_name=pkg_name,
          pkg_url=pkg_url,
          output_file=tarfile)
      untar(tarfile, log)
      os.remove(tarfile)
    elif (module_name in subversion_repositories):
      if op.isdir(module_name):
        shutil.rmtree(module_name)
      pkg_url = subversion_repositories[module_name]
      fetch_svn_repository(
        pkg_name=module_name,
        pkg_url=pkg_url,
        working_copy=working_copy)
  