private WeightedMultigraph<Vertex, LabeledWeightedEdge> step5(
      WeightedMultigraph<Vertex, LabeledWeightedEdge> g4) {

    logger.debug("<enter");

    WeightedMultigraph<Vertex, LabeledWeightedEdge> g5 = g4;

    List<Vertex> nonSteinerLeaves = new ArrayList<Vertex>();

    Set<Vertex> vertexSet = g4.vertexSet();
    for (Vertex vertex : vertexSet) {
      if (g5.degreeOf(vertex) == 1 && steinerNodes.indexOf(vertex) == -1) {
        nonSteinerLeaves.add(vertex);
      }
    }

    Vertex source, target;
    for (int i = 0; i < nonSteinerLeaves.size(); i++) {
      source = nonSteinerLeaves.get(i);
      do {
        LabeledWeightedEdge e = g5.edgesOf(source).toArray(new LabeledWeightedEdge[0])[0];
        target = this.graph.getEdgeTarget(e);

        // this should not happen, but just in case of ...
        if (target.equals(source)) target = e.getSource();

        g5.removeVertex(source);
        source = target;
      } while (g5.degreeOf(source) == 1 && steinerNodes.indexOf(source) == -1);
    }

    logger.debug("exit>");

    return g5;
  }
  private WeightedMultigraph<Vertex, LabeledWeightedEdge> step2(
      WeightedMultigraph<Vertex, LabeledWeightedEdge> g1) {

    logger.debug("<enter");

    KruskalMinimumSpanningTree<Vertex, LabeledWeightedEdge> mst =
        new KruskalMinimumSpanningTree<Vertex, LabeledWeightedEdge>(g1);

    //    	System.out.println("Total MST Cost: " + mst.getSpanningTreeCost());

    Set<LabeledWeightedEdge> edges = mst.getEdgeSet();

    WeightedMultigraph<Vertex, LabeledWeightedEdge> g2 =
        new WeightedMultigraph<Vertex, LabeledWeightedEdge>(LabeledWeightedEdge.class);

    List<LabeledWeightedEdge> edgesSortedByLabel = new ArrayList<LabeledWeightedEdge>();

    for (LabeledWeightedEdge e : edges) edgesSortedByLabel.add(e);

    Collections.sort(edgesSortedByLabel, new EdgeComparatorByLabel());

    for (LabeledWeightedEdge edge : edgesSortedByLabel) {

      //			//just for test, forcing to select another equal minimal spanning tree
      //			if (g1.getEdgeSource(edge).getLabel().equalsIgnoreCase("v1") &&
      //					g1.getEdgeTarget(edge).getLabel().equalsIgnoreCase("v3") ) {
      //				Vertex v2 = steinerNodes.get(1);
      //				g2.addVertex(g1.getEdgeTarget(edge));
      //				g2.addVertex(v2);
      //				LabeledWeightedEdge e = new LabeledWeightedEdge("e");
      //				g2.setEdgeWeight(e, g1.getEdgeWeight(edge));
      //				g2.addEdge(g1.getEdgeTarget(edge), v2, e);
      //			} else
      {
        g2.addVertex(edge.getSource());
        g2.addVertex(edge.getTarget());
        g2.addEdge(edge.getSource(), edge.getTarget(), edge);
      }
    }

    logger.debug("exit>");

    return g2;
  }
  private WeightedMultigraph<Vertex, LabeledWeightedEdge> step3(
      WeightedMultigraph<Vertex, LabeledWeightedEdge> g2) {

    logger.debug("<enter");

    WeightedMultigraph<Vertex, LabeledWeightedEdge> g3 =
        new WeightedMultigraph<Vertex, LabeledWeightedEdge>(LabeledWeightedEdge.class);

    Set<LabeledWeightedEdge> edges = g2.edgeSet();
    DijkstraShortestPath<Vertex, LabeledWeightedEdge> path;

    Vertex source, target;

    for (LabeledWeightedEdge edge : edges) {
      source = edge.getSource();
      target = edge.getTarget();

      path = new DijkstraShortestPath<Vertex, LabeledWeightedEdge>(this.graph, source, target);
      List<LabeledWeightedEdge> pathEdges = path.getPathEdgeList();

      if (pathEdges == null) continue;

      for (int i = 0; i < pathEdges.size(); i++) {

        if (g3.edgeSet().contains(pathEdges.get(i))) continue;

        source = pathEdges.get(i).getSource();
        target = pathEdges.get(i).getTarget();

        if (!g3.vertexSet().contains(source)) g3.addVertex(source);

        if (!g3.vertexSet().contains(target)) g3.addVertex(target);

        g3.addEdge(source, target, pathEdges.get(i));
      }
    }

    logger.debug("exit>");

    return g3;
  }