Parameters
    ----------
    plugin_package : str
        Name of plugin package hosted on MicroDrop plugin index. Version
        constraints are also supported (e.g., ``"foo", "foo==1.0",
        "foo>=1.0"``, etc.)  See `version specifiers`_ reference for more
        details.
    plugins_directory : str
        Path to MicroDrop user plugins directory.
    server_url : str
        URL of JSON request for MicroDrop plugins package index.  See
        ``DEFAULT_SERVER_URL`` for default.

    Returns
    -------
    (path, dict)
        Path to directory of installed plugin and plugin package metadata
        dictionary.


    .. _version specifiers:
        https://www.python.org/dev/peps/pep-0440/#version-specifiers

    .. versionchanged:: 0.25.2
        Import `pip_helpers` locally to avoid error `sci-bots/mpm#5`_.

        .. _sci-bots/mpm#5: https://github.com/sci-bots/mpm/issues/5

def install(plugin_package, plugins_directory, server_url=DEFAULT_SERVER_URL):
    '''
    Parameters
    ----------
    plugin_package : str
        Name of plugin package hosted on MicroDrop plugin index. Version
        constraints are also supported (e.g., ``"foo", "foo==1.0",
        "foo>=1.0"``, etc.)  See `version specifiers`_ reference for more
        details.
    plugins_directory : str
        Path to MicroDrop user plugins directory.
    server_url : str
        URL of JSON request for MicroDrop plugins package index.  See
        ``DEFAULT_SERVER_URL`` for default.

    Returns
    -------
    (path, dict)
        Path to directory of installed plugin and plugin package metadata
        dictionary.


    .. _version specifiers:
        https://www.python.org/dev/peps/pep-0440/#version-specifiers

    .. versionchanged:: 0.25.2
        Import `pip_helpers` locally to avoid error `sci-bots/mpm#5`_.

        .. _sci-bots/mpm#5: https://github.com/sci-bots/mpm/issues/5
    '''
    import pip_helpers

    if path(plugin_package).isfile():
        plugin_is_file = True
        with open(plugin_package, 'rb') as plugin_file:
            # Plugin package is a file.
            plugin_file_metadata = extract_metadata(plugin_file)
        name = plugin_file_metadata['package_name']
        version = plugin_file_metadata['version']
    else:
        plugin_is_file = False
        # Look up latest release matching specifiers.
        try:
            name, releases = pip_helpers.get_releases(plugin_package,
                                                      server_url=server_url)
            version, release = releases.items()[-1]
        except KeyError:
            raise

    # Check existing version (if any).
    plugin_path = plugins_directory.joinpath(name)

    if not plugin_path.isdir():
        existing_version = None
    else:
        plugin_metadata = yaml.load(plugin_path.joinpath('properties.yml')
                                    .bytes())
        existing_version = plugin_metadata['version']

    if version == existing_version:
        # Package already installed.
        raise ValueError('`{}=={}` is already installed.'.format(name,
                                                                 version))

    if existing_version is not None:
        # Uninstall existing package.
        uninstall(name, plugins_directory)

    # Install latest release
    # ======================
    print 'Installing `{}=={}`.'.format(name, version)

    if not plugin_is_file:
        # Download plugin release archive.
        download = requests.get(release['url'], stream=True)

        plugin_archive_bytes = StringIO.StringIO()
        total_bytes = int(download.headers['Content-length'])
        bytes_read = 0

        with progressbar.ProgressBar(max_value=total_bytes) as bar:
            while bytes_read < total_bytes:
                chunk_i = download.raw.read(1 << 8)
                bytes_read += len(chunk_i)
                plugin_archive_bytes.write(chunk_i)
                bar.update(bytes_read)

        # Extract downloaded plugin to install path.
        plugin_archive_bytes.seek(0)
    else:
        plugin_archive_bytes = open(plugin_package, 'rb')

    plugin_path, plugin_metadata = install_fileobj(plugin_archive_bytes,
                                                   plugin_path)
    # Ensure installed package and version does not match requested version.
    assert(all([plugin_metadata['package_name'] == name,
                plugin_metadata['version'] == version]))
    print '  \--> done'
    plugin_archive_bytes.close()
    return plugin_path, plugin_metadata