def conditional_committors(source, sink, waypoint, msm):
    """
    Computes the conditional committors :math:`q^{ABC^+}` which are is the
    probability of starting in one state and visiting state B before A while
    also visiting state C at some point.

    Note that in the notation of Dickson et. al. this computes :math:`h_c(A,B)`,
    with ``sources = A``, ``sinks = B``, ``waypoint = C``

    Parameters
    ----------
    waypoint : int
        The index of the intermediate state
    source : int
        The index of the source state
    sink : int
        The index of the sink state
    msm : msmbuilder.MarkovStateModel
        MSM to analyze.

    Returns
    -------
    cond_committors : np.ndarray
        Conditional committors, i.e. the probability of visiting
        a waypoint when on a path between source and sink.

    See Also
    --------
    msmbuilder.tpt.fraction_visited : function
        Calculate the fraction of visits to a waypoint from a given
        source to a sink.
    msmbuilder.tpt.hub_scores : function
        Compute the 'hub score', the weighted fraction of visits for an
        entire network.

    Notes
    -----
    Employs dense linear algebra, memory use scales as N^2,
    and cycle use scales as N^3

    References
    ----------
    .. [1] Dickson & Brooks (2012), J. Chem. Theory Comput., 8, 3044-3052.
    """

    # typecheck
    for data in [source, sink, waypoint]:
        if not isinstance(data, int):
            raise ValueError("source, sink, and waypoint must be integers.")

    if (source == waypoint) or (sink == waypoint) or (sink == source):
        raise ValueError('source, sink, waypoint must all be disjoint!')

    if hasattr(msm, 'all_transmats_'):
        cond_committors = np.zeros(msm.all_transmats_.shape[:2])
        for i, tprob in enumerate(msm.all_transmats_):
            cond_committors[i, :] = _conditional_committors(source, sink,
                                                            waypoint, tprob)
        return np.median(cond_committors, axis=0)

    return _conditional_committors(source, sink, waypoint, msm.transmat_)