// Path: src/main/java/org/laborra/beantrace/VertexFieldAdder.java
// public interface VertexFieldAdder {
//     void addField(Vertex vertex, String fieldName, Object item);
// }
// 
// Path: src/main/java/org/laborra/beantrace/handlers/VertexHandler.java
// public interface VertexHandler {
// 
//     /**
//      * Specifies if this handler can manage the subject.
//      */
//     boolean canHandle(Object subject);
// 
//     /**
//      * Handle the passed vertex based on the subject.
//      */
//     void handle(Vertex vertex, Object subject, VertexFieldAdder vertexFieldAdder);
// 
//     class Composite implements VertexHandler {
// 
//         private final List<VertexHandler> delegates;
// 
//         public Composite(List<VertexHandler> delegates) {
//             this.delegates = delegates;
//         }
// 
//         @Override
//         public boolean canHandle(Object subject) {
//             for (VertexHandler vertexHandler : delegates) {
//                 if (vertexHandler.canHandle(subject)) {
//                     return true;
//                 }
//             }
// 
//             return false;
//         }
// 
//         @Override
//         public void handle(Vertex vertex, Object subject, VertexFieldAdder vertexFieldAdder) {
//             for (VertexHandler vertexHandler : delegates) {
//                 if (vertexHandler.canHandle(subject)) {
//                     vertexHandler.handle(vertex, subject, vertexFieldAdder);
//                     return;
//                 }
//             }
//         }
//     }
// 
//     class MapVertexHandler extends TypeBasedHandler<Map<Object, Object>> {
// 
//         public MapVertexHandler() {
//             super(Map.class);
//         }
// 
//         @Override
//         public void typedHandle(Vertex vertex, Map<Object, Object> subject, VertexFieldAdder vertexFieldAdder) {
//             int i = -1;
//             for (Map.Entry<Object, Object> entry : subject.entrySet()) {
//                 i++;
//                 final Object key = entry.getKey();
//                 final Object value = entry.getValue();
//                 final boolean primitiveKey = ReflectUtils.isPrimitive(key.getClass());
// 
//                 if (primitiveKey) {
//                     vertexFieldAdder.addField(vertex, key.toString(), value);
//                 }
// 
//                 if (!primitiveKey) {
//                     final Vertex entryVertex = new Vertex(Map.Entry.class, System.identityHashCode(entry) + "");
//                     vertexFieldAdder.addField(entryVertex, "key", key);
//                     vertexFieldAdder.addField(entryVertex, "value", value);
//                     vertex.getReferences().add(new Edge("entry_" + i, entryVertex));
//                 }
//             }
//         }
//     }
// 
//     class ArrayHandler implements VertexHandler {
// 
//         public boolean canHandle(Object subject) {
//             return subject.getClass().isArray();
//         }
// 
//         public void handle(Vertex vertex, Object subject, VertexFieldAdder vertexFieldAdder) {
//             int arrayLength = Array.getLength(subject);
//             for (int i = 0; i < arrayLength; i++) {
//                 Object item = Array.get(subject, i);
//                 vertexFieldAdder.addField(vertex, i + "", item);
//             }
//         }
//     }
// 
//     class ClassTypeHandler extends TypeBasedHandler<Class> {
// 
//         public ClassTypeHandler() {
//             super(Class.class);
//         }
// 
//         @Override
//         protected void typedHandle(Vertex vertex, Class subject, VertexFieldAdder vertexFieldAdder) {
//             vertexFieldAdder.addField(vertex, "name", subject.getName());
//         }
//     }
// 
// }
// 
// Path: src/main/java/org/laborra/beantrace/model/Attribute.java
// public class Attribute<T> {
//     private String name;
//     private T value;
// 
//     public Attribute(String name, T value) {
//         this.name = name;
//         this.value = value;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public T getValue() {
//         return value;
//     }
// }
// 
// 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.VertexFieldAdder;
import org.laborra.beantrace.handlers.VertexHandler;
import org.laborra.beantrace.model.Attribute;
import org.laborra.beantrace.model.Edge;
import org.laborra.beantrace.model.Vertex;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;
package org.laborra.beantrace.internal;



public class DefaultVertexFactory implements VertexFactory {

    private final Map<Object, Vertex> visitedMap = new IdentityHashMap<>();
// Path: src/main/java/org/laborra/beantrace/VertexFieldAdder.java
// public interface VertexFieldAdder {
//     void addField(Vertex vertex, String fieldName, Object item);
// }
// 
// Path: src/main/java/org/laborra/beantrace/handlers/VertexHandler.java
// public interface VertexHandler {
// 
//     /**
//      * Specifies if this handler can manage the subject.
//      */
//     boolean canHandle(Object subject);
// 
//     /**
//      * Handle the passed vertex based on the subject.
//      */
//     void handle(Vertex vertex, Object subject, VertexFieldAdder vertexFieldAdder);
// 
//     class Composite implements VertexHandler {
// 
//         private final List<VertexHandler> delegates;
// 
//         public Composite(List<VertexHandler> delegates) {
//             this.delegates = delegates;
//         }
// 
//         @Override
//         public boolean canHandle(Object subject) {
//             for (VertexHandler vertexHandler : delegates) {
//                 if (vertexHandler.canHandle(subject)) {
//                     return true;
//                 }
//             }
// 
//             return false;
//         }
// 
//         @Override
//         public void handle(Vertex vertex, Object subject, VertexFieldAdder vertexFieldAdder) {
//             for (VertexHandler vertexHandler : delegates) {
//                 if (vertexHandler.canHandle(subject)) {
//                     vertexHandler.handle(vertex, subject, vertexFieldAdder);
//                     return;
//                 }
//             }
//         }
//     }
// 
//     class MapVertexHandler extends TypeBasedHandler<Map<Object, Object>> {
// 
//         public MapVertexHandler() {
//             super(Map.class);
//         }
// 
//         @Override
//         public void typedHandle(Vertex vertex, Map<Object, Object> subject, VertexFieldAdder vertexFieldAdder) {
//             int i = -1;
//             for (Map.Entry<Object, Object> entry : subject.entrySet()) {
//                 i++;
//                 final Object key = entry.getKey();
//                 final Object value = entry.getValue();
//                 final boolean primitiveKey = ReflectUtils.isPrimitive(key.getClass());
// 
//                 if (primitiveKey) {
//                     vertexFieldAdder.addField(vertex, key.toString(), value);
//                 }
// 
//                 if (!primitiveKey) {
//                     final Vertex entryVertex = new Vertex(Map.Entry.class, System.identityHashCode(entry) + "");
//                     vertexFieldAdder.addField(entryVertex, "key", key);
//                     vertexFieldAdder.addField(entryVertex, "value", value);
//                     vertex.getReferences().add(new Edge("entry_" + i, entryVertex));
//                 }
//             }
//         }
//     }
// 
//     class ArrayHandler implements VertexHandler {
// 
//         public boolean canHandle(Object subject) {
//             return subject.getClass().isArray();
//         }
// 
//         public void handle(Vertex vertex, Object subject, VertexFieldAdder vertexFieldAdder) {
//             int arrayLength = Array.getLength(subject);
//             for (int i = 0; i < arrayLength; i++) {
//                 Object item = Array.get(subject, i);
//                 vertexFieldAdder.addField(vertex, i + "", item);
//             }
//         }
//     }
// 
//     class ClassTypeHandler extends TypeBasedHandler<Class> {
// 
//         public ClassTypeHandler() {
//             super(Class.class);
//         }
// 
//         @Override
//         protected void typedHandle(Vertex vertex, Class subject, VertexFieldAdder vertexFieldAdder) {
//             vertexFieldAdder.addField(vertex, "name", subject.getName());
//         }
//     }
// 
// }
// 
// Path: src/main/java/org/laborra/beantrace/model/Attribute.java
// public class Attribute<T> {
//     private String name;
//     private T value;
// 
//     public Attribute(String name, T value) {
//         this.name = name;
//         this.value = value;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public T getValue() {
//         return value;
//     }
// }
// 
// 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/DefaultVertexFactory.java
import org.laborra.beantrace.VertexFieldAdder;
import org.laborra.beantrace.handlers.VertexHandler;
import org.laborra.beantrace.model.Attribute;
import org.laborra.beantrace.model.Edge;
import org.laborra.beantrace.model.Vertex;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;

package org.laborra.beantrace.internal;



public class DefaultVertexFactory implements VertexFactory {

    private final Map<Object, Vertex> visitedMap = new IdentityHashMap<>();
    private final VertexHandler vertexHandler;