def _deploy_zapp(conn, target, zapp_path, auth_opts, force=False):
    """Upload all of the necessary files for a zapp.

    Returns the name an uploaded index file, or the target if no
    index.html file was uploaded.

    :param bool force:
        Force deployment, even if the target container is not empty. This means
        that files could be overwritten and could cause consistency problems
        with these objects in Swift.
    """
    base_container = target.split('/')[0]
    try:
        _, objects = conn.get_container(base_container)
        if not len(objects) == 0:
            if not force:
                raise zpmlib.ZPMException(
                    "Target container ('%s') is not empty.\nDeploying to a "
                    "non-empty container can cause consistency problems with "
                    "overwritten objects.\nSpecify the flag `--force/-f` to "
                    "overwrite anyway."
                    % base_container
                )
    except swiftclient.exceptions.ClientException:
        # container doesn't exist; create it
        LOG.info("Container '%s' not found. Creating it...", base_container)
        conn.put_container(base_container)

    # If we get here, everything with the container is fine.
    index = target + '/'
    uploads = _generate_uploads(conn, target, zapp_path, auth_opts)
    for path, data, content_type in uploads:
        if path.endswith('/index.html'):
            index = path
        container, obj = path.split('/', 1)
        conn.put_object(container, obj, data, content_type=content_type)
    return index