code: func (g *Graph) deleteEdges_locked(fromType, toType vertexType, toNamespace, toName string) {
  	// get the "to" side
  	toVert, exists := g.getVertex_rlocked(toType, toNamespace, toName)
  	if !exists {
  		return
  	}
  
  	// delete all edges between vertices of fromType and toVert
  	neighborsToRemove := []*namedVertex{}
  	neighborsToRecompute := []*namedVertex{}
  	g.graph.VisitTo(toVert, func(from graph.Node) bool {
  		fromVert := from.(*namedVertex)
  		if fromVert.vertexType != fromType {
  			return true
  		}
  		// remove the edge
  		g.graph.RemoveEdge(simple.Edge{F: fromVert, T: toVert})
  		// track vertexes that changed edges
  		if g.graph.Degree(fromVert) == 0 {
  			neighborsToRemove = append(neighborsToRemove, fromVert)
  		} else {
  			neighborsToRecompute = append(neighborsToRecompute, fromVert)
  		}
  		return true
  	})
  
  	// clean up orphaned verts
  	for _, v := range neighborsToRemove {
  		g.removeVertex_locked(v)
  	}
  
  	// recompute destination indexes for neighbors that dropped outbound edges
  	for _, v := range neighborsToRecompute {
  		g.recomputeDestinationIndex_locked(v)
  	}
  }
docs: // must be called under write lock
  // deletes edges from a given vertex type to a specific vertex
  // will delete each orphaned "from" vertex, but will never delete the "to" vertex