public Vertex[] pathDFS(Vertex source, Vertex target) {
        if (graph.containsKey(source) && graph.containsKey(target)) {
            Graph tree = new Graph();

            Stack<Vertex> S = new Stack<Vertex>();
            S.push(source);
            source.setVisited(true);
            boolean pathFound = false;

            // create a tree until target is reached 
            while (!S.empty() && !pathFound) {
                Vertex v = S.pop();
                ArrayList<Edge> E = new ArrayList<Edge>();
                // if v has an unvisited neighbour w                
                for (Edge edge : graph.get(v)) {
                    Vertex w = edge.getTarget();
                    if (w.equals(target)) {
                        w.setVisited(true);
                        w.setParent(v);
                        E.add(edge);
                        tree.addConnectedVertex(v, E);
                        tree.addVertex(w);
                        pathFound = true;
                        break;
                    }
                    else if (!w.isVisited()) {
                        w.setVisited(true);
                        w.setParent(v);
                        E.add(edge);
                        S.push(w);
                    }
                }
                tree.addConnectedVertex(v, E);
            }

            // from target retrieve the source
            Stack<Vertex> sPath = new Stack<Vertex>();
            sPath.push(target);
            while (sPath.peek().parent() != null) {
                sPath.push(sPath.peek().parent());
            }

            Vertex[] path = new Vertex[sPath.size()];
            return sPath.toArray(path);
        }
        else {
            throw new NullPointerException("Vertex source " + source + " or Vertex target "
                    + target + " does not belong to the graph");
        }
    }