def namespace_index(
    analysis,
    nindex=True,
    nindex_usages=True,
    nrn=True,
    nrn_usages=True,
):
    """
    Index namespace definitions and usages.

    Definitions are indexed by name and file extension.

    Usages are indexed by name.

    Returns dict with keys 'nindex', 'nindex_usages', 'nrn', 'nrn_usages'.
    """

    namespace_definitions = analysis.get("namespace-definitions", [])

    # Namespace definitions indexed by name.
    nindex_ = {}

    # Namespace definitions indexed by row.
    nrn_ = {}

    if nindex or nrn:
        for namespace_definition in namespace_definitions:

            if nindex:
                name = namespace_definition.get("name")

                nindex_.setdefault(name, []).append(namespace_definition)

            if nrn:
                name_row = namespace_definition.get("name-row")

                nrn_.setdefault(name_row, []).append(namespace_definition)

    # Namespace usages indexed by name.
    nindex_usages_ = {}

    # Var usages indexed by row.
    nrn_usages_ = {}

    if nindex_usages or nrn_usages:
        for namespace_usage in analysis.get("namespace-usages", []):

            if nindex_usages:
                name = namespace_usage.get("to")

                nindex_usages_.setdefault(name, []).append(namespace_usage)

            if nrn_usages:
                name_row = namespace_usage.get("name-row")

                nrn_usages_.setdefault(name_row, []).append(namespace_usage)

                # Index alias row (in case there's one).
                # Note: It's possible to have both the name and alias in the same row.
                if namespace_usage.get("alias"):
                    alias_row = namespace_usage.get("alias-row")

                    nrn_usages_.setdefault(alias_row, []).append(namespace_usage)

    return {
        "nindex": nindex_,
        "nindex_usages": nindex_usages_,
        "nrn": nrn_,
        "nrn_usages": nrn_usages_,
    }