private DelaunayTriangle update(DelaunayVertex site,
            Set<DelaunayTriangle> cavity) {
        Set<Set<DelaunayVertex>> boundary = new HashSet<Set<DelaunayVertex>>();
        Set<DelaunayTriangle> theTriangles = new HashSet<DelaunayTriangle>();

        // Find boundary facets and adjacent triangles
        for (DelaunayTriangle triangle : cavity) {
            theTriangles.addAll(neighbors(triangle));
            for (DelaunayVertex vertex : triangle) {
                Set<DelaunayVertex> facet = triangle.facetOpposite(vertex);
                if (boundary.contains(facet)) {
                    boundary.remove(facet);
                } else {
                    boundary.add(facet);
                }
            }
        }
        theTriangles.removeAll(cavity); // Adj triangles only

        // Remove the cavity triangles from the triangulation
        for (DelaunayTriangle triangle : cavity) {
            triGraph.remove(triangle);
        }

        // Build each new triangle and add it to the triangulation
        Set<DelaunayTriangle> newTriangles = new HashSet<DelaunayTriangle>();
        for (Set<DelaunayVertex> vertices : boundary) {
            vertices.add(site);
            DelaunayTriangle tri = new DelaunayTriangle(vertices);
            triGraph.add(tri);
            newTriangles.add(tri);
        }

        // Update the graph links for each new triangle
        theTriangles.addAll(newTriangles); // Adj triangle + new triangles
        for (DelaunayTriangle triangle : newTriangles) {
            for (DelaunayTriangle other : theTriangles) {
                if (triangle.isNeighbor(other)) {
                    triGraph.connect(triangle, other);
                }
            }
        }

        // Return one of the new triangles
        return newTriangles.iterator().next();
    }