Paginate through a query that returns a dict result, and return the
    combined result.

    Note that this function requires some special kwargs to be passed in:

    * __alc_marker_path__ - The dictionary path to the Marker for the next
      result set. If this path does not exist, the raw result will be returned.
    * __alc_data_path__ - The dictionary path to the list containing the query
      results. This will be updated with the results of subsequent queries.
    * __alc_marker_param__ - The parameter name to pass to ``function_ref``
      with the marker value.

    These paths should be lists, in a form usable by
    :py:func:`~._get_dict_value_by_path`.

    :param function_ref: the function to call
    :type function_ref: ``function``
    :param argv: the parameters to pass to the function
    :type argv: tuple
    :param kwargs: keyword arguments to pass to the function
    :type kwargs: dict

def paginate_dict(function_ref, *argv, **kwargs):
    """
    Paginate through a query that returns a dict result, and return the
    combined result.

    Note that this function requires some special kwargs to be passed in:

    * __alc_marker_path__ - The dictionary path to the Marker for the next
      result set. If this path does not exist, the raw result will be returned.
    * __alc_data_path__ - The dictionary path to the list containing the query
      results. This will be updated with the results of subsequent queries.
    * __alc_marker_param__ - The parameter name to pass to ``function_ref``
      with the marker value.

    These paths should be lists, in a form usable by
    :py:func:`~._get_dict_value_by_path`.

    :param function_ref: the function to call
    :type function_ref: ``function``
    :param argv: the parameters to pass to the function
    :type argv: tuple
    :param kwargs: keyword arguments to pass to the function
    :type kwargs: dict
    """
    if 'alc_marker_path' not in kwargs:
        raise Exception("alc_marker_path must be specified for queries "
                        "that return a dict.")
    if 'alc_data_path' not in kwargs:
        raise Exception("alc_data_path must be specified for queries "
                        "that return a dict.")
    if 'alc_marker_param' not in kwargs:
        raise Exception("alc_marker_param must be specified for queries "
                        "that return a dict.")

    marker_path = kwargs['alc_marker_path']
    data_path = kwargs['alc_data_path']
    marker_param = kwargs['alc_marker_param']

    # strip off "^alc_" args
    pass_kwargs = {}
    for k, v in kwargs.items():
        if not k.startswith('alc_'):
            pass_kwargs[k] = v

    # first function call
    result = function_ref(*argv, **pass_kwargs)

    # check for marker, return if not present
    marker = _get_dict_value_by_path(result, marker_path)
    if marker is None:
        return result
    logger.debug("Found marker (%s) in result; iterating for more results",
                 marker_path)
    # iterate results
    results = []
    results.extend(_get_dict_value_by_path(result, data_path))
    while marker is not None:
        logger.debug("Querying %s with %s=%s", function_ref, marker_param,
                     marker)
        pass_kwargs[marker_param] = marker
        result = function_ref(*argv, **pass_kwargs)
        data = _get_dict_value_by_path(result, data_path)
        results.extend(data)
        marker = _get_dict_value_by_path(result, marker_path)
    # drop the full results into the last result response
    res = _set_dict_value_by_path(result, results, data_path)
    return res