public DigraphLayout<V,E> layout(Digraph<V,E> digraph, DigraphLayoutDimensionProvider<V> dimensions, Digraph<V,?> feedback) {
		if (digraph.getVertexCount() == 0) {
			return new DigraphLayout<V,E>(Digraphs.<DigraphLayoutNode<V>,DigraphLayoutArc<V,E>>emptyDigraph(), new DigraphLayoutDimension(0, 0));
		}
		DoubledDigraph<SugiyamaNode<V>,SugiyamaArc<V,E>> graph = createLayoutGraph(digraph, dimensions, feedback);
		insertDummyNodes(graph, dimensions);
		if (transpose) {
			for (SugiyamaNode<V> source : graph.vertices()) {
				source.getDimension().transpose();
			}
		}
		List<List<SugiyamaNode<V>>> layers = createLayers(graph);
		minimizeCrossings(graph, layers);
		adjustNodePositions(graph, layers);
		computeNodePoints(graph, layers);
		DigraphLayoutDimension dimension = computeLayoutDimension(layers);
		routeArcs(graph, layers);
		removeDummyNodes(graph);
		fixEndPoints(graph);
		finalizeLayout(graph);
		if (transpose) {
			for (SugiyamaNode<V> source : graph.vertices()) {
				source.getPoint().transpose();
				source.getDimension().transpose();
				for (SugiyamaNode<V> target : graph.targets(source)) {
					SugiyamaArc<V, E> arc = graph.get(source, target);
					arc.getStartPoint().transpose();
					arc.getEndPoint().transpose();
					for (DigraphLayoutPoint point : arc.getBendPoints()) {
						point.transpose();
					}
				}
			}
			dimension.transpose();
		}
		return new DigraphLayout<V,E>(graph, dimension);
	}