// Path: src/main/java/org/laborra/beantrace/model/Edge.java
// public class Edge {
//     private String name;
//     private Vertex to;
// 
//     public Edge(String name, Vertex to) {
//         this.name = name;
//         this.to = to;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public Vertex getTo() {
//         return to;
//     }
// }
// 
// Path: src/main/java/org/laborra/beantrace/model/Vertex.java
// public class Vertex {
//     private Class<?> clazz;
//     private String id;
//     private Set<Edge> references = new HashSet<>();
//     private Set<Attribute> attributes = new HashSet<>();
// 
//     public Vertex(Class<?> clazz, String id) {
//         this(clazz, id, new HashSet<Edge>(), new HashSet<Attribute>());
//     }
// 
//     public Vertex(Class<?> clazz, String id, Set<Edge> references, Set<Attribute> attributes) {
//         this.id = id;
//         this.clazz = clazz;
//         this.references = references;
//         this.attributes = attributes;
//     }
// 
//     public Set<Edge> getReferences() {
//         return references;
//     }
// 
//     public Set<Attribute> getAttributes() {
//         return attributes;
//     }
// 
//     public Class<?> getClazz() {
//         return clazz;
//     }
// 
//     public String getId() {
//         return id;
//     }
// }


import org.laborra.beantrace.model.Edge;
import org.laborra.beantrace.model.Vertex;
import java.util.*;
package org.laborra.beantrace.internal;



/**
 * Utility class to interact with vertex graphs.
 *
 */
public class Graphs {

    /**
     * Collect all vertices in the given graph.
     *
     * @param root A vertex contained in the graph
     * @return A collection with all vertices
     */
    public static Collection<Vertex> collectAllVertices(Vertex root) {
        final CollectorVisitor collectorVisitor = new CollectorVisitor();
        traverse(root, collectorVisitor);
        return collectorVisitor.getResult();
    }

    /**
     * Traverse the graph where the root is contained with the given visitor.
     *
     * @param root The starting vertex
     * @param visitor The visitor to apply to all vertices
     */
    public static void traverse(Vertex root, VertexVisitor visitor) {
        traverse(root, visitor, new HashSet<Vertex>());
    }

    private static void traverse(Vertex vertex, VertexVisitor visitor, Set<Vertex> visited) {
        if (visited.contains(vertex)) {
            return;
        }
        visited.add(vertex);

        visitor.visit(vertex);

        final Set<Edge> references = vertex.getReferences();
        for (Edge reference : references) {
            traverse(reference.getTo(), visitor, visited);
        }
    }

    /**
     * Return a map view of the graph edges, where each key is an edge and the value is the
     * vertex the edge start from.
     *
     * @param subject The root vertex of the graph
     * @return The map representing the graph
     */
    public static Map<Edge, Vertex> mapEdgeToStartingVertex(Vertex subject) {
// Path: src/main/java/org/laborra/beantrace/model/Edge.java
// public class Edge {
//     private String name;
//     private Vertex to;
// 
//     public Edge(String name, Vertex to) {
//         this.name = name;
//         this.to = to;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public Vertex getTo() {
//         return to;
//     }
// }
// 
// Path: src/main/java/org/laborra/beantrace/model/Vertex.java
// public class Vertex {
//     private Class<?> clazz;
//     private String id;
//     private Set<Edge> references = new HashSet<>();
//     private Set<Attribute> attributes = new HashSet<>();
// 
//     public Vertex(Class<?> clazz, String id) {
//         this(clazz, id, new HashSet<Edge>(), new HashSet<Attribute>());
//     }
// 
//     public Vertex(Class<?> clazz, String id, Set<Edge> references, Set<Attribute> attributes) {
//         this.id = id;
//         this.clazz = clazz;
//         this.references = references;
//         this.attributes = attributes;
//     }
// 
//     public Set<Edge> getReferences() {
//         return references;
//     }
// 
//     public Set<Attribute> getAttributes() {
//         return attributes;
//     }
// 
//     public Class<?> getClazz() {
//         return clazz;
//     }
// 
//     public String getId() {
//         return id;
//     }
// }


// Path: src/main/java/org/laborra/beantrace/internal/Graphs.java
import org.laborra.beantrace.model.Edge;
import org.laborra.beantrace.model.Vertex;
import java.util.*;

package org.laborra.beantrace.internal;



/**
 * Utility class to interact with vertex graphs.
 *
 */
public class Graphs {

    /**
     * Collect all vertices in the given graph.
     *
     * @param root A vertex contained in the graph
     * @return A collection with all vertices
     */
    public static Collection<Vertex> collectAllVertices(Vertex root) {
        final CollectorVisitor collectorVisitor = new CollectorVisitor();
        traverse(root, collectorVisitor);
        return collectorVisitor.getResult();
    }

    /**
     * Traverse the graph where the root is contained with the given visitor.
     *
     * @param root The starting vertex
     * @param visitor The visitor to apply to all vertices
     */
    public static void traverse(Vertex root, VertexVisitor visitor) {
        traverse(root, visitor, new HashSet<Vertex>());
    }

    private static void traverse(Vertex vertex, VertexVisitor visitor, Set<Vertex> visited) {
        if (visited.contains(vertex)) {
            return;
        }
        visited.add(vertex);

        visitor.visit(vertex);

        final Set<Edge> references = vertex.getReferences();
        for (Edge reference : references) {
            traverse(reference.getTo(), visitor, visited);
        }
    }

    /**
     * Return a map view of the graph edges, where each key is an edge and the value is the
     * vertex the edge start from.
     *
     * @param subject The root vertex of the graph
     * @return The map representing the graph
     */
    public static Map<Edge, Vertex> mapEdgeToStartingVertex(Vertex subject) {
        final Map<Edge, Vertex> edgeMap = new HashMap<>();