static List<Map<String, Set<String>>> find_connected_subgraphs(Map<String, Set<String>> graph,
                                                                   Set<String> root_ids,
                                                                   Set<String> leaf_node_ids) {
        List<Set<String>> subgraph_id_sets = new ArrayList<Set<String>>();
        for (String leaf_id : leaf_node_ids) {
            subgraph_id_sets.add(allDescendants(graph, leaf_id));
        }

        //# Coalesce subgraphs which have common root nodes
        for(String key : root_ids) {
            Set<String> coalesced = new HashSet<String>();

            // # Deep copy the list so I can mutate while iterating
            List<Set<String>> copyForMutatingIteration = new ArrayList<Set<String>>();
            copyForMutatingIteration.addAll(subgraph_id_sets);
            for (Set<String> subgraph_id_set : copyForMutatingIteration) {
                if (!subgraph_id_set.contains(key)) {
                    continue;
                }

                coalesced.addAll(subgraph_id_set);
                subgraph_id_sets.remove(subgraph_id_set);
            }

            if (coalesced.size() > 0) {
                subgraph_id_sets.add(coalesced);
            }

            if (subgraph_id_sets.size() < 2) {
                break; //# Bail out if there is only one graph
            }
        }

        List<Map<String, Set<String>>> subgraphs = new ArrayList<Map<String, Set<String>>>();
        for (Set<String> subgraph_id_set : subgraph_id_sets) {
            Map<String, Set<String>>copy = new HashMap<String, Set<String>>();
            for (String id_value : subgraph_id_set) {
                if (graph.keySet().contains(id_value)) { // # handle unseen parents
                    Set<String> deepCopy = new HashSet<String>();
                    deepCopy.addAll(graph.get(id_value));
                    copy.put(id_value, deepCopy);
                }
            }
            //dumpGraph("subgraph", copy);
            subgraphs.add(copy);
        }
        return subgraphs;
    }