@Override
    public AlgorithmResult<V, E> start(final V vertex, final V startVertex, final V endVertex) throws IllegalGraphException
    {
        if (startVertex == null)
        {
            throw new IllegalArgumentException("The start vertex can not be null");
        }

        if (endVertex == null)
        {
            throw new IllegalArgumentException("The end vertex can not be null");
        }

        if (startVertex == endVertex)
        {
            throw new IllegalArgumentException("The start and end vertices could not be the same");
        }

        final AlgorithmResult<V, E> algorithmResult = algorithmExecutor.start("breadthfirst", vertex);

        final List<E> edges = algorithmResult.getBreadthFirstResult().getEdges();

        for (final E edge : edges)
        {
            addResidualEdge(algorithmExecutor.retrieveStartVertex(edge),
                    algorithmExecutor.retrieveEndVertex(edge),
                    algorithmExecutor.retrieveEdgeWeight(edge), 0);
        }

        Set<ResidualEdge<V>> path = findPath(startVertex, endVertex);
        while (path != null)
        {
            double minFlow = Double.MAX_VALUE;
            for (ResidualEdge e : path)
            {
                minFlow = Math.min(minFlow, e.residualCapacity);
            }
            for (ResidualEdge<V> e : path)
            {
                flow.put(e, flow.get(e) + minFlow);
                flow.put(e.reverseEdge, flow.get(e.reverseEdge) - minFlow);
            }
            path = findPath(startVertex, endVertex);
        }

        double maxFlow = 0;
        for (ResidualEdge residualEdge : adj.get(startVertex))
        {
            maxFlow += flow.get(residualEdge);
        }

        return new AlgorithmResult<>(new MaxFlowResult(maxFlow));
    }