def do_lock(
    ctx=None,
    system=False,
    clear=False,
    pre=False,
    keep_outdated=False,
    write=True,
    pypi_mirror=None,
):
    """Executes the freeze functionality."""

    cached_lockfile = {}
    if not pre:
        pre = project.settings.get("allow_prereleases")
    if keep_outdated:
        if not project.lockfile_exists:
            raise exceptions.PipenvOptionsError(
                "--keep-outdated", ctx=ctx,
                message="Pipfile.lock must exist to use --keep-outdated!"
            )
        cached_lockfile = project.lockfile_content
    # Create the lockfile.
    lockfile = project._lockfile
    # Cleanup lockfile.
    for section in ("default", "develop"):
        for k, v in lockfile[section].copy().items():
            if not hasattr(v, "keys"):
                del lockfile[section][k]
    # Ensure that develop inherits from default.
    dev_packages = project.dev_packages.copy()
    dev_packages = overwrite_dev(project.packages, dev_packages)
    # Resolve dev-package dependencies, with pip-tools.
    for is_dev in [True, False]:
        pipfile_section = "dev-packages" if is_dev else "packages"
        lockfile_section = "develop" if is_dev else "default"
        if project.pipfile_exists:
            packages = project.parsed_pipfile.get(pipfile_section, {})
        else:
            packages = getattr(project, pipfile_section.replace("-", "_"))

        if write:
            # Alert the user of progress.
            click.echo(
                u"{0} {1} {2}".format(
                    crayons.normal(u"Locking"),
                    crayons.red(u"[{0}]".format(pipfile_section.replace("_", "-"))),
                    crayons.normal(fix_utf8("dependencies…")),
                ),
                err=True,
            )

        # Mutates the lockfile
        venv_resolve_deps(
            packages,
            which=which,
            project=project,
            dev=is_dev,
            clear=clear,
            pre=pre,
            allow_global=system,
            pypi_mirror=pypi_mirror,
            pipfile=packages,
            lockfile=lockfile,
            keep_outdated=keep_outdated
        )

    # Support for --keep-outdated…
    if keep_outdated:
        from pipenv.vendor.packaging.utils import canonicalize_name
        for section_name, section in (
            ("default", project.packages),
            ("develop", project.dev_packages),
        ):
            for package_specified in section.keys():
                if not is_pinned(section[package_specified]):
                    canonical_name = canonicalize_name(package_specified)
                    if canonical_name in cached_lockfile[section_name]:
                        lockfile[section_name][canonical_name] = cached_lockfile[
                            section_name
                        ][canonical_name].copy()
            for key in ["default", "develop"]:
                packages = set(cached_lockfile[key].keys())
                new_lockfile = set(lockfile[key].keys())
                missing = packages - new_lockfile
                for missing_pkg in missing:
                    lockfile[key][missing_pkg] = cached_lockfile[key][missing_pkg].copy()
    # Overwrite any develop packages with default packages.
    lockfile["develop"].update(overwrite_dev(lockfile.get("default", {}), lockfile["develop"]))
    if write:
        project.write_lockfile(lockfile)
        click.echo(
            "{0}".format(
                crayons.normal(
                    "Updated Pipfile.lock ({0})!".format(
                        lockfile["_meta"].get("hash", {}).get("sha256")[-6:]
                    ),
                    bold=True,
                )
            ),
            err=True,
        )
    else:
        return lockfile