/**
   * Método recursivo para hacer un recorrido del grafo para obtener el valor de cada
   * vértice.
   *
   * @param v <code>Vertex<StructV></code>
   */
  public boolean recurse(Vertex<StructV> v) {

    if (v == null) return false;
    if (v.getValue() == null) return false;

    if (!(v.getValue().getSprite() instanceof SpriteUnion)) precondition(v);

    ArrayList<Vertex<StructV>> neighbors = v.getNeighbors();

    for (int i = 0; i < neighbors.size(); i++) {
      Vertex<StructV> tmp = neighbors.get(i);

      if (tmp == null) break;

      if (whileCase(tmp)) continue;
      if (forCase(tmp)) continue;
      if (ifCase(tmp)) continue;
      if (unionCase(tmp)) continue;

      recurse(tmp);
    }

    if (!(v.getValue().getSprite() instanceof SpriteIf)) postcondition(v);

    return false;
  }
  /**
   * M&eacute;todo para realizar comparaciones entre vertices.
   *
   * @param v <code>Vertex<V></code>
   * @return <code>boolean</code>
   */
  public boolean equals(Vertex<V> v) {

    if (v == null) return false;
    if (v.getValue() == null & value == null) return true;
    if (value == null) return false;
    StructV st = (StructV) value;
    return st.equalsTo((StructV) v.getValue());
  }
  /**
   * M&eacute;todo para agregar un vecino.
   *
   * @param neighbor <code>Vertex<V></code>
   */
  public boolean addNeighbor(Vertex<V> neighbor) {

    if (neighbor == null) return false;
    if (getNeighbor(neighbor.getValue()) == null) if (neighbors.add(neighbor)) return true;

    return false;
  }
  /**
   * M&eacute;todo que lleva el control sobre el recorrido para el caso especial del If
   *
   * @param tmp Vertice Acual <code>Vertex<StructV></code>
   */
  private boolean ifCase(Vertex<StructV> tmp) {

    if (tmp.getValue().getSprite() instanceof SpriteIf) {
      if (ifList.size() != 0) {
        Sprite currentIf = ifList.get(ifList.size() - 1).getValue().getSprite();

        if (!currentIf.equals(tmp.getValue().getSprite())) {
          ifList.add(tmp);
        }
      } else {
        ifList.add(tmp);
      }
    }

    return false;
  }
  public boolean removeNeighbor(V value) {

    for (int i = 0; i < getNumNeighbors(); i++) {
      Vertex<V> v = this.neighbors.get(i);
      if (v == null) continue;
      if (v.getValue() == null & value == null) {
        this.neighbors.remove(i);
        return true;
      }
      if (this.neighbors.get(i).getValue().equals(value)) {

        this.neighbors.remove(i);
        return true;
      }
    }
    return false;
  }
  /**
   * M&eacute;todo que lleva el control sobre el recorrido para el caso especial del For
   *
   * @param tmp Vertice Acual <code>Vertex<StructV></code>
   */
  private boolean forCase(Vertex<StructV> tmp) {

    if (tmp.getValue().getSprite() instanceof SpriteFor) {
      if (forList.size() != 0) {
        Sprite currentFor = forList.get(forList.size() - 1);

        if (!currentFor.equals(tmp.getValue().getSprite())) {
          forList.add(tmp.getValue().getSprite());
        } else {
          forList.remove(forList.size() - 1);
          return true;
        }
      } else {
        forList.add(tmp.getValue().getSprite());
      }
    }

    return false;
  }
  /**
   * M&eacute;todo que lleva el control sobre el recorrido para el caso especial del While
   *
   * @param tmp Vertice Acual <code>Vertex<StructV></code>
   */
  private boolean whileCase(Vertex<StructV> tmp) {

    if (tmp.getValue().getSprite() instanceof SpriteWhile) {
      if (whileList.size() != 0) {
        Sprite currentWhile = whileList.get(whileList.size() - 1);

        if (!currentWhile.equals(tmp.getValue().getSprite())) {
          whileList.add(tmp.getValue().getSprite());
        } else {
          whileList.remove(whileList.size() - 1);
          return true;
        }
      } else {
        whileList.add(tmp.getValue().getSprite());
      }
    }

    return false;
  }
  /**
   * M&eacute;todo que lleva el control sobre el recorrido para el caso especial de la Union
   *
   * @param tmp Vertice Acual <code>Vertex<StructV></code>
   */
  private boolean unionCase(Vertex<StructV> tmp) {

    if (tmp.getValue().getSprite() instanceof SpriteUnion) {
      if (unionList.size() != 0) {
        unionList.remove(unionList.size() - 1);
        precondition(tmp);
        return false;
      } else {
        if (ifList.size() > 0) {
          Vertex<StructV> ifTemp = ifList.get(ifList.size() - 1);
          postcondition(ifTemp);
          ifList.remove(ifList.size() - 1);
        }

        unionList.add(tmp.getValue().getSprite());
        return true;
      }
    }
    return false;
  }
  /**
   * M&eacute;todo que genera las postcondiciones para el vertice actual
   *
   * @param v Vertice Acual <code>Vertex<StructV></code>
   */
  public void postcondition(Vertex<StructV> v) {

    String name = (String) ((Hashtable) v.getValue().getValue()).get("name");

    int line = search(name);

    if (line == -1) {
      code += "\r";
      return;
    }

    if (!(template.get(line + 2).matches("[\\s]*"))) code += template.get(line + 2) + "\r";
  }
 /**
  * M&eacute;todo que genera las precondiciones para el vertice actual
  *
  * @param v Vertice Acual <code>Vertex<StructV></code>
  */
 public void precondition(Vertex<StructV> v) {
   replaceVars((Hashtable) v.getValue().getValue());
 }