class GraphAlgorithms {

	public static <V, E extends GEdge<V>> Set<V> getEntryPoints(GDirectedGraph<V, E> g) {

		Set<V> sources = getSources(g);
		Set<V> descendants = getDescendants(g, sources);
		Set<V> isolatedVertices = new HashSet<>(g.getVertices());
		isolatedVertices.removeAll(sources);
		isolatedVertices.removeAll(descendants);

		Set<V> entryPoints = new HashSet<>(sources);
		if (isolatedVertices.isEmpty()) {
			// no unconnected vertices 
			return entryPoints;
		}

		GDirectedGraph<V, E> isolatedGraph = createSubGraph(g, isolatedVertices);
		Set<Set<V>> strongs = getStronglyConnectedComponents(isolatedGraph);

		for (Set<V> set : strongs) {
			if (isSelfContainedStrongComponent(g, set)) {
				// just pick one to be the entry point
				entryPoints.add(set.iterator().next());
			}
		}

		return entryPoints;
	}

	private  GraphAlgorithms();

}