def check_circular_call_dependencies(manifests):
    """
    Check if there is a circular dependency between the partitions
    described by the manifests.
    A circular dependency might happen if there is a scenario in which a
    partition calls a Root of Trust Service in another partition which than
    calls another Root of Trust Service which resides in the
    originating partition.
    For example: Partition A has a Root of Trust Service A1 and extern sid B1,
                 partition B has a Root of Trust Service B1 and extern sid A1.

    :param manifests: List of the partition manifests.
    :return: True if a circular dependency exists, false otherwise.
    """

    # Construct a call graph.
    call_graph = {}
    for manifest in manifests:
        call_graph[manifest.name] = {
            'calls': manifest.find_dependencies(manifests),
            'called_by': set()
        }
    for manifest_name in call_graph:
        for called in call_graph[manifest_name]['calls']:
            call_graph[called]['called_by'].add(manifest_name)

    # Run topological sort on the call graph.
    while len(call_graph) > 0:
        # Find all the nodes that aren't called by anyone and
        # therefore can be removed.
        nodes_to_remove = [x for x in list(call_graph.keys()) if
                           len(call_graph[x]['called_by']) == 0]

        # If no node can be removed we have a circle.
        if not nodes_to_remove:
            return True

        # Remove the nodes.
        for node in nodes_to_remove:
            for called in call_graph[node]['calls']:
                call_graph[called]['called_by'].remove(node)
            call_graph.pop(node)

    return False