@Override
  public boolean addEdge(Integer edge, Pair<? extends Role> endpoints, EdgeType edgeType) {
    this.validateEdgeType(edgeType);
    Pair<Role> new_endpoints = getValidatedEndpoints(edge, endpoints);
    if (new_endpoints == null) return false;

    Role source = new_endpoints.getFirst();
    Role dest = new_endpoints.getSecond();

    if (findEdge(source, dest) != null) return false;

    if (makesCycle(source, dest)) {

      return false;
    }

    edges.put(edge, new_endpoints);

    if (!vertices.containsKey(source)) this.addVertex(source);

    if (!vertices.containsKey(dest)) this.addVertex(dest);

    // map source of this edge to <dest, edge> and vice versa
    vertices.get(source).getSecond().put(dest, edge);
    vertices.get(dest).getFirst().put(source, edge);

    // new edge, role map has unsaved changes
    map.setSaved(false);
    return true;
  }
 @Override
 public boolean removeVertex(Role vertex) {
   // vertex removed, role map has unsaved changes
   map.setSaved(false);
   return super.removeVertex(vertex);
 }
 @Override
 public boolean removeEdge(Integer edge) {
   // edge removed, role map has unsaved changes
   map.setSaved(false);
   return super.removeEdge(edge);
 }
 @Override
 public boolean addVertex(Role vertex) {
   // new vertex, role map has unsaved changes
   map.setSaved(false);
   return super.addVertex(vertex);
 }