/**
   * This method initiates and populates the hashmap reqs, with all requirements in the graph. There
   * are two types of requirements: Ordinary and Variable. All of them are fetched by calling
   * getReqTagKey for all the edges and vertexes in the graph The Ordinary requirements are directly
   * put into the reqs hashmap. The Variable requirements are used as a lookup in the list of all
   * the variable values returned by getAllVariableValues and the value matching the the Variable
   * requirement are splitted with colon and put as keys into the reqs hashmap. The value for each
   * entity in the reqs hashmap will be set to null, since no requirement are tested yet. Its never
   * needed to call this method more than once.
   */
  public void populateReqHashMap() {
    reqs = new HashMap<String, Boolean>();
    Hashtable<String, String> reqsVariables = getAllVariableValues();

    for (Edge edge : model.getEdges()) {
      String reqTag = edge.getReqTagKey();
      if (reqTag.length() == 0) continue;
      String[] tmp = reqTag.split(",");
      for (int i = 0; i < tmp.length; i++) {
        if (tmp[i].matches("[$][{].*[}]")) {
          String[] reqNames =
              reqsVariables.get(tmp[i].substring(2, tmp[i].length() - 1)).split(":");
          for (String reqVar : reqNames) this.reqs.put(reqVar, null);
        } else this.reqs.put(tmp[i], null);
      }
    }
    for (Vertex vertex : model.getVertices()) {
      String reqTag = vertex.getReqTagKey();
      if (reqTag.length() == 0) continue;
      String[] tmp = reqTag.split(",");
      for (int i = 0; i < tmp.length; i++) {
        if (tmp[i].matches("[$][{].*[}]")) {
          String savedReq = reqsVariables.get(tmp[i].substring(2, tmp[i].length() - 1));
          if (savedReq == null) continue;
          String[] reqNames = savedReq.split(":");
          for (String reqVar : reqNames) this.reqs.put(reqVar, null);
        } else this.reqs.put(tmp[i], null);
      }
    }
  }
 public void setAllUnvisited() {
   logger.debug("setAllUnvisited");
   reset();
   for (Vertex vertex : model.getVertices()) {
     vertex.setVisitedKey(0);
   }
   for (Edge edge : model.getEdges()) {
     edge.setVisitedKey(0);
   }
 }
 public AbstractElement findElement(Integer index) {
   for (Vertex vertex : model.getVertices()) {
     if (vertex.getIndexKey().equals(index)) {
       return vertex;
     }
   }
   for (Edge edge : model.getEdges()) {
     if (edge.getIndexKey().equals(index)) {
       return edge;
     }
   }
   return null;
 }
  public int[] getStatistics() {
    Collection<Edge> e = model.getEdges();
    Collection<Vertex> v = model.getVertices();

    int[] retur = {
      e.size(),
      getEdgeCoverage(e),
      v.size(),
      getVertexCoverage(v),
      numberOfEdgesTravesed,
      getAllRequirements().size(),
      getCoveredRequirements().size()
    };
    return retur;
  }
 public Set<Edge> getCurrentOutEdges() throws FoundNoEdgeException {
   Set<Edge> retur = new HashSet<Edge>(model.getOutEdges(currentVertex));
   if (retur.size() == 0) {
     throw new FoundNoEdgeException("Cul-De-Sac, dead end found in '" + getCurrentVertex() + "'");
   }
   return retur;
 }
  public void setVertex(String vertexName) {
    logger.debug("Setting vertex to: '" + vertexName + "'");
    Vertex e = model.findVertex(vertexName);
    Util.AbortIf(e == null, "Vertex not Found: '" + vertexName + "'");

    currentVertex = e;
    setAsVisited(e);
  }
 public Vertex getStartVertex() {
   for (Vertex vertex : model.getVertices()) {
     if (vertex.getLabelKey().equals(Keywords.START_NODE)) {
       return vertex;
     }
   }
   return null;
 }
 public Edge findEdge(String edgeName) {
   for (Edge edge : model.getEdges()) {
     if ((edge.getLabelKey()).equals(edgeName)) {
       return edge;
     }
   }
   return null;
 }
  public boolean walkEdge(Edge edge) {
    if (model.isSource(currentVertex, edge)) {
      lastEdge = edge;
      if (isBacktrackPossible()) {
        track();
      }

      currentVertex = model.getDest(edge);
      setAsVisited(lastEdge);
      setAsVisited(currentVertex);
      numberOfEdgesTravesed++;
      logger.debug("No. of walked edges: " + numberOfEdgesTravesed);
      return true;
    } else {
      logger.error(edge + ", is not the source of: " + currentVertex);
    }
    return false;
  }
  public String getStatisticsVerbose() {
    String retur = "";
    String newLine = "\n";
    Vector<String> notCovered = new Vector<String>();

    for (Edge edge : model.getEdges()) {
      if (edge.getVisitedKey() <= 0) {
        notCovered.add("Edge not reached: " + edge + newLine);
      }
    }
    for (Vertex vertex : model.getVertices()) {
      if (vertex.getVisitedKey() <= 0) {
        notCovered.add("Vertex not reached: " + vertex + newLine);
      }
    }
    if (notCovered.size() > 0) {
      Collections.sort(notCovered);
      for (String string : notCovered) {
        retur += string;
      }
    }

    Iterator<Entry<String, Boolean>> it = reqs.entrySet().iterator();
    while (it.hasNext()) {
      Entry<String, Boolean> pairs = it.next();

      if (pairs.getValue() == null) {
        retur += "Requirement: " + pairs.getKey() + " is not tested." + newLine;
        continue;
      }
      if (pairs.getValue().booleanValue() == true) {
        retur += "Requirement: " + pairs.getKey() + " has passed." + newLine;
        continue;
      }
      if (pairs.getValue().booleanValue() == false) {
        retur += "Requirement: " + pairs.getKey() + " has failed." + newLine;
        continue;
      }
    }

    retur += getStatisticsString() + newLine;
    retur += "Execution time: " + ((System.currentTimeMillis() - start_time) / 1000) + " seconds";
    return retur;
  }
  protected void popVertex() {
    setAsUnvisited(getLastEdge());
    setAsUnvisited(getCurrentVertex());

    edgeStack.pop();
    if (lastEdge == null) {
      setVertex(Keywords.START_NODE);
    } else {
      currentVertex = model.getSource(lastEdge);
    }
    lastEdge = (edgeStack.size() > 0 ? edgeStack.peek() : null);
    numberOfEdgesTravesed--;
  }
 public boolean hasVertex(String vertexName) {
   return model.findVertex(vertexName) != null;
 }
 public Set<Edge> getCurrentInEdges() {
   Set<Edge> retur = new HashSet<Edge>(model.getInEdges(currentVertex));
   return retur;
 }
 public Collection<Edge> getAllEdgesExceptStartEdge() {
   Vector<Edge> list = new Vector<Edge>(model.getEdges());
   Edge e = (Edge) model.getOutEdges(getStartVertex()).toArray()[0];
   list.remove(e);
   return list;
 }
 public Collection<Edge> getAllEdges() {
   return model.getEdges();
 }
 public Collection<Vertex> getAllVertices() {
   return model.getVertices();
 }