# Buggy code
def link(prefix, dist, linktype=LINK_HARD, index=None):
    """
    Set up a package in a specified (environment) prefix.  We assume that
    the package has been extracted (using extract() above).
    """
    index = index or {}
    source_dir = is_extracted(dist)
    assert source_dir is not None
    pkgs_dir = dirname(source_dir)
    log.debug(
        "pkgs_dir=%r, prefix=%r, dist=%r, linktype=%r"
        % (pkgs_dir, prefix, dist, linktype)
    )

    if not run_script(source_dir, dist, "pre-link", prefix):
        sys.exit("Error: pre-link failed: %s" % dist)

    info_dir = join(source_dir, "info")
    files = list(yield_lines(join(info_dir, "files")))
    has_prefix_files = read_has_prefix(join(info_dir, "has_prefix"))
    no_link = read_no_link(info_dir)

    with Locked(prefix), Locked(pkgs_dir):
        for f in files:
            src = join(source_dir, f)
            dst = join(prefix, f)
            dst_dir = dirname(dst)
            if not isdir(dst_dir):
                os.makedirs(dst_dir)
            if os.path.exists(dst):
                log.warn("file already exists: %r" % dst)
                try:
                    os.unlink(dst)
                except OSError:
                    log.error("failed to unlink: %r" % dst)
                    if on_win:
                        try:
                            move_path_to_trash(dst)
                        except ImportError:
                            # This shouldn't be an issue in the installer anyway
                            pass

            lt = linktype
            if f in has_prefix_files or f in no_link or islink(src):
                lt = LINK_COPY
            try:
                _link(src, dst, lt)
            except OSError as e:
                log.error(
                    "failed to link (src=%r, dst=%r, type=%r, error=%r)"
                    % (src, dst, lt, e)
                )

        if name_dist(dist) == "_cache":
            return

        for f in sorted(has_prefix_files):
            placeholder, mode = has_prefix_files[f]
            try:
                update_prefix(join(prefix, f), prefix, placeholder, mode)
            except PaddingError:
                sys.exit(
                    "ERROR: placeholder '%s' too short in: %s\n" % (placeholder, dist)
                )

        mk_menus(prefix, files, remove=False)

        if not run_script(prefix, dist, "post-link"):
            sys.exit("Error: post-link failed for: %s" % dist)

        meta_dict = index.get(dist + ".tar.bz2", {})
        meta_dict["url"] = read_url(dist)
        try:
            alt_files_path = join(prefix, "conda-meta", _dist2filename(dist, ".files"))
            meta_dict["files"] = list(yield_lines(alt_files_path))
            os.unlink(alt_files_path)
        except IOError:
            meta_dict["files"] = files
        meta_dict["link"] = {"source": source_dir, "type": link_name_map.get(linktype)}
        if "icon" in meta_dict:
            meta_dict["icondata"] = read_icondata(source_dir)

        create_meta(prefix, dist, info_dir, meta_dict)


# Traceback (TypeError)
Traceback (most recent call last):
File "/home/ilan/minonda/bin/conda", line 6, in <module>
sys.exit(main())
File "/home/ilan/conda/conda/cli/main.py", line 120, in main
args_func(args, p)
File "/home/ilan/conda/conda/cli/main.py", line 127, in args_func
args.func(args, p)
File "/home/ilan/conda/conda/cli/main_install.py", line 62, in execute
install.install(args, parser, 'install')
File "/home/ilan/conda/conda/cli/install.py", line 394, in install
plan.execute_actions(actions, index, verbose=not args.quiet)
File "/home/ilan/conda/conda/plan.py", line 555, in execute_actions
inst.execute_instructions(plan, index, verbose)
File "/home/ilan/conda/conda/instructions.py", line 133, in execute_instructions
cmd(state, arg)
File "/home/ilan/conda/conda/instructions.py", line 80, in UNLINK_CMD
install.unlink(state['prefix'], arg)
File "/home/ilan/conda/conda/install.py", line 1075, in unlink
mk_menus(prefix, meta['files'], remove=True)
TypeError: 'NoneType' object has no attribute '__getitem__'

# Fixed code
def link(prefix, dist, linktype=LINK_HARD, index=None):
    """
    Set up a package in a specified (environment) prefix.  We assume that
    the package has been extracted (using extract() above).
    """
    index = index or {}
    source_dir = is_extracted(dist)
    assert source_dir is not None
    pkgs_dir = dirname(source_dir)
    log.debug(
        "pkgs_dir=%r, prefix=%r, dist=%r, linktype=%r"
        % (pkgs_dir, prefix, dist, linktype)
    )

    if not run_script(source_dir, dist, "pre-link", prefix):
        sys.exit("Error: pre-link failed: %s" % dist)

    info_dir = join(source_dir, "info")
    files = list(yield_lines(join(info_dir, "files")))
    has_prefix_files = read_has_prefix(join(info_dir, "has_prefix"))
    no_link = read_no_link(info_dir)

    with Locked(prefix), Locked(pkgs_dir):
        for f in files:
            src = join(source_dir, f)
            dst = join(prefix, f)
            dst_dir = dirname(dst)
            if not isdir(dst_dir):
                os.makedirs(dst_dir)
            if os.path.exists(dst):
                log.warn("file already exists: %r" % dst)
                try:
                    os.unlink(dst)
                except OSError:
                    log.error("failed to unlink: %r" % dst)
                    if on_win:
                        try:
                            move_path_to_trash(dst)
                        except ImportError:
                            # This shouldn't be an issue in the installer anyway
                            pass

            lt = linktype
            if f in has_prefix_files or f in no_link or islink(src):
                lt = LINK_COPY
            try:
                _link(src, dst, lt)
            except OSError as e:
                log.error(
                    "failed to link (src=%r, dst=%r, type=%r, error=%r)"
                    % (src, dst, lt, e)
                )

        if name_dist(dist) == "_cache":
            return

        for f in sorted(has_prefix_files):
            placeholder, mode = has_prefix_files[f]
            try:
                update_prefix(join(prefix, f), prefix, placeholder, mode)
            except PaddingError:
                sys.exit(
                    "ERROR: placeholder '%s' too short in: %s\n" % (placeholder, dist)
                )

        mk_menus(prefix, files, remove=False)

        if not run_script(prefix, dist, "post-link"):
            sys.exit("Error: post-link failed for: %s" % dist)

        meta_dict = index.get(dist + ".tar.bz2", {})
        meta_dict["url"] = read_url(dist)
        try:
            alt_files_path = join(prefix, "conda-meta", dist2filename(dist, ".files"))
            meta_dict["files"] = list(yield_lines(alt_files_path))
            os.unlink(alt_files_path)
        except IOError:
            meta_dict["files"] = files
        meta_dict["link"] = {"source": source_dir, "type": link_name_map.get(linktype)}
        if "icon" in meta_dict:
            meta_dict["icondata"] = read_icondata(source_dir)

        create_meta(prefix, dist, info_dir, meta_dict)