// Path: src/main/java/com/groupon/vertx/utils/util/Digraph.java
// public class Digraph<E> {
//     private Set<E> nodes;
//     private final Map<E, Set<E>> adjacent;
// 
//     public Digraph() {
//         this(0);
//     }
// 
//     public Digraph(int initialCapacity) {
//         nodes = new HashSet<>(initialCapacity);
//         adjacent = new ConcurrentHashMap<>(initialCapacity);
//     }
// 
//     public void addNode(E v) {
//         nodes.add(v);
//     }
// 
//     public void addEdge(E v, E w) {
//         if (!nodes.contains(v) || !nodes.contains(w)) {
//             throw new IllegalStateException("Both nodes must already exist in the graph prior to adding a connecting edge");
//         }
// 
//         Set<E> set = adjacent.get(v);
// 
//         if (set == null) {
//             set = Collections.synchronizedSet(new HashSet<E>());
//             adjacent.put(v, set);
//         }
// 
//         set.add(w);
//     }
// 
//     public Set<E> getNodes() {
//         return Collections.unmodifiableSet(nodes);
//     }
// 
//     public Iterable<E> getAdjacent(E v) {
//         Set<E> set = adjacent.get(v);
// 
//         if (set == null) {
//             set = Collections.emptySet();
//         }
// 
//         return Collections.unmodifiableSet(set);
//     }
// 
//     @Override
//     public String toString() {
//         StringBuilder sb = new StringBuilder("Digraph[");
//         for (Map.Entry<E, Set<E>> entry : adjacent.entrySet()) {
//             E v = entry.getKey();
//             for (E w : entry.getValue()) {
//                 sb.append("[");
//                 sb.append(v.toString());
//                 sb.append(" --> ");
//                 sb.append(w.toString());
//                 sb.append("]");
//             }
//         }
//         sb.append("]");
//         return sb.toString();
//     }
// }
// 
// Path: src/main/java/com/groupon/vertx/utils/util/TopSorter.java
// public class TopSorter<E> {
//     private final Digraph<E> digraph;
// 
//     public TopSorter(Digraph<E> digraph) {
//         this.digraph = digraph;
//     }
// 
//     public List<E> sort() {
//         Set<E> nodes = digraph.getNodes();
// 
//         List<E> result = new ArrayList<>(nodes.size());
//         Set<E> flagged = new HashSet<>(nodes.size());
//         Set<E> visited = new HashSet<>(nodes.size());
// 
//         for (E node : nodes) {
//             visit(node, result, flagged, visited);
//         }
// 
//         return result;
//     }
// 
//     private void visit(E node, List<E> result, Set<E> flagged, Set<E> visited) {
//         if (flagged.contains(node)) {
//             throw new IllegalStateException("Cycle detected; can only sort directed acyclic graphs");
//         }
// 
//         if (!visited.contains(node)) {
// 
//             flagged.add(node);
//             for (E edgeNode : digraph.getAdjacent(node)) {
//                 visit(edgeNode, result, flagged, visited);
//             }
// 
//             flagged.remove(node);
//             visited.add(node);
//             result.add(node);
//         }
//     }
// }


import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import io.vertx.core.json.JsonObject;
import com.groupon.vertx.utils.util.Digraph;
import com.groupon.vertx.utils.util.TopSorter;
        verticles = new ConcurrentHashMap<>(total);

        for (String verticleName : verticleNames) {
            JsonObject verticleConfig = verticleJson.getJsonObject(verticleName);
            verticles.put(verticleName, new VerticleConfig(verticleName, verticleConfig));
        }

        determineLoadOrder();
    }

    private void determineLoadOrder() {
        Digraph<VerticleConfig> dependencyGraph = new Digraph<>(verticles.size());

        for (VerticleConfig verticle : verticles.values()) {
            dependencyGraph.addNode(verticle);

            if (verticle.getDependencies().size() > 0) {
                for (String dependencyName : verticle.getDependencies()) {
                    VerticleConfig dependency = verticles.get(dependencyName);

                    if (dependency != null) {
                        dependencyGraph.addNode(dependency);
                        dependencyGraph.addEdge(verticle, dependency);
                    } else {
                        throw new IllegalStateException(String.format("Verticle '%s' depends on unknown dependency '%s'", verticle.getName(), dependencyName));
                    }
                }
            }
        }

// Path: src/main/java/com/groupon/vertx/utils/util/Digraph.java
// public class Digraph<E> {
//     private Set<E> nodes;
//     private final Map<E, Set<E>> adjacent;
// 
//     public Digraph() {
//         this(0);
//     }
// 
//     public Digraph(int initialCapacity) {
//         nodes = new HashSet<>(initialCapacity);
//         adjacent = new ConcurrentHashMap<>(initialCapacity);
//     }
// 
//     public void addNode(E v) {
//         nodes.add(v);
//     }
// 
//     public void addEdge(E v, E w) {
//         if (!nodes.contains(v) || !nodes.contains(w)) {
//             throw new IllegalStateException("Both nodes must already exist in the graph prior to adding a connecting edge");
//         }
// 
//         Set<E> set = adjacent.get(v);
// 
//         if (set == null) {
//             set = Collections.synchronizedSet(new HashSet<E>());
//             adjacent.put(v, set);
//         }
// 
//         set.add(w);
//     }
// 
//     public Set<E> getNodes() {
//         return Collections.unmodifiableSet(nodes);
//     }
// 
//     public Iterable<E> getAdjacent(E v) {
//         Set<E> set = adjacent.get(v);
// 
//         if (set == null) {
//             set = Collections.emptySet();
//         }
// 
//         return Collections.unmodifiableSet(set);
//     }
// 
//     @Override
//     public String toString() {
//         StringBuilder sb = new StringBuilder("Digraph[");
//         for (Map.Entry<E, Set<E>> entry : adjacent.entrySet()) {
//             E v = entry.getKey();
//             for (E w : entry.getValue()) {
//                 sb.append("[");
//                 sb.append(v.toString());
//                 sb.append(" --> ");
//                 sb.append(w.toString());
//                 sb.append("]");
//             }
//         }
//         sb.append("]");
//         return sb.toString();
//     }
// }
// 
// Path: src/main/java/com/groupon/vertx/utils/util/TopSorter.java
// public class TopSorter<E> {
//     private final Digraph<E> digraph;
// 
//     public TopSorter(Digraph<E> digraph) {
//         this.digraph = digraph;
//     }
// 
//     public List<E> sort() {
//         Set<E> nodes = digraph.getNodes();
// 
//         List<E> result = new ArrayList<>(nodes.size());
//         Set<E> flagged = new HashSet<>(nodes.size());
//         Set<E> visited = new HashSet<>(nodes.size());
// 
//         for (E node : nodes) {
//             visit(node, result, flagged, visited);
//         }
// 
//         return result;
//     }
// 
//     private void visit(E node, List<E> result, Set<E> flagged, Set<E> visited) {
//         if (flagged.contains(node)) {
//             throw new IllegalStateException("Cycle detected; can only sort directed acyclic graphs");
//         }
// 
//         if (!visited.contains(node)) {
// 
//             flagged.add(node);
//             for (E edgeNode : digraph.getAdjacent(node)) {
//                 visit(edgeNode, result, flagged, visited);
//             }
// 
//             flagged.remove(node);
//             visited.add(node);
//             result.add(node);
//         }
//     }
// }


// Path: src/main/java/com/groupon/vertx/utils/config/Config.java
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import io.vertx.core.json.JsonObject;
import com.groupon.vertx.utils.util.Digraph;
import com.groupon.vertx.utils.util.TopSorter;

        verticles = new ConcurrentHashMap<>(total);

        for (String verticleName : verticleNames) {
            JsonObject verticleConfig = verticleJson.getJsonObject(verticleName);
            verticles.put(verticleName, new VerticleConfig(verticleName, verticleConfig));
        }

        determineLoadOrder();
    }

    private void determineLoadOrder() {
        Digraph<VerticleConfig> dependencyGraph = new Digraph<>(verticles.size());

        for (VerticleConfig verticle : verticles.values()) {
            dependencyGraph.addNode(verticle);

            if (verticle.getDependencies().size() > 0) {
                for (String dependencyName : verticle.getDependencies()) {
                    VerticleConfig dependency = verticles.get(dependencyName);

                    if (dependency != null) {
                        dependencyGraph.addNode(dependency);
                        dependencyGraph.addEdge(verticle, dependency);
                    } else {
                        throw new IllegalStateException(String.format("Verticle '%s' depends on unknown dependency '%s'", verticle.getName(), dependencyName));
                    }
                }
            }
        }

        orderedVerticles = new TopSorter<>(dependencyGraph).sort();