/*
  * Print the elements of the main Map scope.
  */
 public void print(Scope scp) {
   Symbol aux1;
   Scope s;
   if (!scp.getMembers().isEmpty()) {
     System.out.println("\nScope: " + scp.getScopeName() + "\tsize=" + scp.getMembers().size());
     Iterator<Symbol> it = scp.getMembers().iterator();
     for (; it.hasNext(); ) {
       aux1 = it.next();
       if (aux1.getRootScope() != null) { // is a root of a new scope?
         s = aux1.getRootScope();
         s.print(s);
       }
     }
   } else {
     aux1 = scp.getScopeSymbol();
     System.out.println(
         "Name: "
             + aux1.getName()
             + "\t\tline: "
             + aux1.getCodeLine()
             + "\t\ttainted: "
             + aux1.getTainted()
             + "\t\tScope: "
             + aux1.getScope().getScopeName()
             + "\n");
   }
 }
 public void populateList(
     Scope scp_main,
     Scope scp_right,
     int num_var,
     TaintedTable mts,
     UntaintedTable mus,
     String filename) {
   Iterator<Symbol> it = this.getMembers().iterator();
   Iterator<Symbol> it1 = scp_right.getMembers().iterator();
   Symbol sym, sym1;
   for (int i = 1; i < num_var; i++) {
     sym1 = it1.next();
     sym = it.next();
     CallSymbol ms_aux =
         new CallSymbol(sym.getName(), sym.getCodeLine(), scp_main, 0, sym.getFileSymbol());
     VariableSymbol vs =
         new VariableSymbol(
             sym1.getName(), sym1.getTainted(), sym1.getCodeLine(), sym1.getFileSymbol()) {};
     ms_aux.define(vs, null, true);
     ms_aux.resolveSymbol(ms_aux, (Symbol) vs, mts, mus, filename);
     scp_main.define(ms_aux, ms_aux, false);
   }
 }
  /*
   * Resolve Symbol... Bottom-Up navegation
   * This method occur after all symbols of one assign/call function instruction
   * are inserted in scope. After that, one by one is analyse (taint/untaint)
   */
  public void resolveSymbol(
      Scope scp, Symbol sy, TaintedTable mts, UntaintedTable mus, String file) {
    Boolean b = scp.resolve(sy, mts, mus);
    Symbol sym = scp.getScopeSymbol();

    // if symbol is tainted, then insert the symbol scope in the main TaintedTable, if it don't
    // exist yet
    // if don't, then verify if it pass to taint to untaint, and insert in main UntaintedTable
    if (b == true) {
      sy.setTainted(1);
      if (mts.getTaintedMembers().containsKey(sym.getName())
          == false) { // verify if the tainted symbol exist in mts TaintedTable
        RootTaintedSymbol Rrt =
            new RootTaintedSymbol(
                sym.getName(),
                sym.getCodeLine(),
                sym.getTainted(),
                sym.getAlfanumeric(),
                sym.getFileSymbol());
        mts.define(Rrt); // insert in mts TaintedTable
      } else {
        RootTaintedSymbol Rrt = (RootTaintedSymbol) mts.getTaintedMembers().get(sym.getName());
        if (Rrt.getLinesList().contains(sym.getCodeLine()) == false
            || (Rrt.getLinesList().contains(sym.getCodeLine()) == true
                && Rrt.getFilesList().contains(sym.getFileSymbol()) == false)) {
          Rrt.setLineCode(sym.getCodeLine());
          Rrt.setFile(sym.getFileSymbol());
          RelatedTaintedSymbol rtt =
              new RelatedTaintedSymbol(sym.getCodeLine(), sym.getFileSymbol());
          Rrt.define(rtt);
        }
      }
      if (mus.existSymbol(sym.getName()) == true) // verify if symbol pass to untaint to taint
      mus.removeUntaintSymbol(sym);
    } else {
      // verify if symbol pertence to mts and not to mus, then pass to taint to untaint
      if (mts.getTaintedMembers().containsKey(sym.getName()) == true
          && mus.existSymbol(sym.getName()) == false) {
        RootTaintedSymbol Rrt = (RootTaintedSymbol) mts.getTaintedMembers().get(sym.getName());
        if (Rrt.getLinesList().contains(sy.getCodeLine()) == false) mus.insertUntaintSymbol(sym);
      }
    }
  }
  /*
   * Give if the symbol is taint or not.
   * This method occur after all symbols of one assign/call function instruction
   * are inserted in scope. After that, one by one symbol is analyse (taint/untaint)
   */
  public Boolean resolve(Symbol symb, TaintedTable mts, UntaintedTable mus) {
    Symbol aux;
    String s, nam;
    RelatedTaintedSymbol rtt;
    RootTaintedSymbol Rrt;
    Scope scp;

    // Caso o symbol ja seja tainted. Coloca o parent scope a taint
    Symbol sym = symb;
    nam = sym.getName();
    if (sym.getTainted() == 1 && sym.getAlfanumeric() == false) {
      scp = sym.getScope();
      scp.getScopeSymbol().setTainted(1);

      // No caso de nome da funcao ser tainted
      if (mts.getTaintedMembers().containsKey(nam) == true) {
        // Inserir o socpe parent como dependente da funcao tainted
        Rrt = (RootTaintedSymbol) mts.getTaintedMembers().get(nam);
        rtt =
            (RelatedTaintedSymbol)
                Rrt.getListTaintedMembers().get(Rrt.getListTaintedMembers().size() - 1);

        // Caso o parent nao pertenca 'a lista da funcao tainted
        if (rtt.getTaintedMembers().containsKey(scp.getScopeName()) == false) {
          VariableTaintedSymbol var =
              new VariableTaintedSymbol(
                  scp.getScopeName(),
                  scp.getScopeSymbol().getCodeLine(),
                  scp.getScopeSymbol().getTainted(),
                  scp.getScopeSymbol().getFileSymbol());
          rtt.define(var);
        } else { // Caso o parent pertenca 'a lista da funcao tainted
          VariableTaintedSymbol var =
              (VariableTaintedSymbol) rtt.getTaintedMembers().get(scp.getScopeName());
          var.InsertLine(scp.getScopeSymbol().getCodeLine());
          var.InsertFile(scp.getScopeSymbol().getFileSymbol());
        }
        return true;
      }

      // Se uma userfunction ver se os seus parametros sao tainted e inserir a function como
      // dependente deles
      if (sym.getIsUserFunction() == true) {
        Scope scp_aux = (Scope) sym;
        String sy_name;
        Symbol sy_aux;
        Iterator<Symbol> it;
        for (it = scp_aux.getMembers().iterator(); it.hasNext(); ) {
          sy_aux = it.next();
          sy_name = sy_aux.getName();
          if (sy_aux.getTainted() == 1) {
            if (mts.getTaintedMembers().containsKey(sy_name) == true) {
              // Inserir o nome da user function como dependente do seu parametro
              Rrt = (RootTaintedSymbol) mts.getTaintedMembers().get(sy_name);
              rtt =
                  (RelatedTaintedSymbol)
                      Rrt.getListTaintedMembers().get(Rrt.getListTaintedMembers().size() - 1);

              // Caso a user function nao pertenca 'a lista do parametro tainted
              if (rtt.getTaintedMembers().containsKey(sym.getName()) == false) {
                VariableTaintedSymbol var =
                    new VariableTaintedSymbol(
                        sym.getName(), sym.getCodeLine(), sym.getTainted(), sym.getFileSymbol());
                rtt.define(var);
              } else { // Caso a user function pertenca 'a lista do parametro tainted
                VariableTaintedSymbol var =
                    (VariableTaintedSymbol) rtt.getTaintedMembers().get(sym.getName());
                var.InsertLine(sym.getCodeLine());
                var.InsertFile(sym.getFileSymbol());
              }
            }
          }
        }

        // if (mts.getTaintedMembers().containsKey(nam) == false){ // verify if the tainted symbol
        // exist in mts TaintedTable
        Rrt =
            new RootTaintedSymbol(
                sym.getName(),
                sym.getCodeLine(),
                sym.getTainted(),
                sym.getAlfanumeric(),
                sym.getFileSymbol());
        mts.define(Rrt); // insert in mts TaintedTable
      }

      return true;
    }

    // Caso o symbol seja uma var ja tainted e pertenca a tabela das vars tainteds
    if (mts.getTaintedMembers().containsKey(nam) == true
        && mus.existSymbol(sym.getName()) == false) {
      // colocar scope parent tainted
      scp = sym.getScope();
      scp.getScopeSymbol().setTainted(1);

      // Inserir o socpe parent como dependente do symbol tainted
      Rrt = (RootTaintedSymbol) mts.getTaintedMembers().get(nam);
      rtt =
          (RelatedTaintedSymbol)
              Rrt.getListTaintedMembers().get(Rrt.getListTaintedMembers().size() - 1);

      // Caso o parent nao pertenca 'a lista do symbol tainted
      if (rtt.getTaintedMembers().containsKey(scp.getScopeName()) == false) {
        VariableTaintedSymbol var =
            new VariableTaintedSymbol(
                scp.getScopeName(),
                scp.getScopeSymbol().getCodeLine(),
                scp.getScopeSymbol().getTainted(),
                scp.getScopeSymbol().getFileSymbol());
        rtt.define(var);
      } else { // Caso o parent pertenca 'a lista do symbol tainted
        VariableTaintedSymbol var =
            (VariableTaintedSymbol) rtt.getTaintedMembers().get(scp.getScopeName());
        var.InsertLine(scp.getScopeSymbol().getCodeLine());
        var.InsertFile(scp.getScopeSymbol().getFileSymbol());
      }
      return true;
    }

    // Caso o symbol seja um alfanumeric e contenha uma var tainted da tabela das vars tainteds
    if (sym.getAlfanumeric() == true) {
      Boolean existe = false;
      Iterator<Symbol> it = mts.getTaintedMembers().values().iterator();
      for (; it.hasNext(); ) {
        s = it.next().getName();

        if (nam.contains("$" + s) == true && mus.existSymbol(s) == false) {
          // colocar scope parent tainted
          scp = sym.getScope();
          scp.getScopeSymbol().setTainted(1);

          // Inserir o socpe parent como dependente do symbol tainted
          Rrt = (RootTaintedSymbol) mts.getTaintedMembers().get(s);
          rtt =
              (RelatedTaintedSymbol)
                  Rrt.getListTaintedMembers().get(Rrt.getListTaintedMembers().size() - 1);

          // Caso o parent nao pertenca 'a lista do symbol tainted
          if (rtt.getTaintedMembers().containsKey(scp.getScopeName()) == false) {
            VariableTaintedSymbol var =
                new VariableTaintedSymbol(
                    scp.getScopeName(),
                    scp.getScopeSymbol().getCodeLine(),
                    scp.getScopeSymbol().getTainted(),
                    scp.getScopeSymbol().getFileSymbol());
            rtt.define(var);
          } else { // Caso o parent pertenca 'a lista do symbol tainted
            VariableTaintedSymbol var =
                (VariableTaintedSymbol) rtt.getTaintedMembers().get(scp.getScopeName());
            var.InsertLine(scp.getScopeSymbol().getCodeLine());
            var.InsertFile(scp.getScopeSymbol().getFileSymbol());
          }

          existe = true;
        }
      }

      if (sym.getTainted() == 1) {
        scp = sym.getScope();
        scp.getScopeSymbol().setTainted(1);

        // No caso de nome da funcao ser tainted
        if (mts.getTaintedMembers().containsKey(nam) == true) {
          // Inserir o socpe parent como dependente da funcao tainted
          Rrt = (RootTaintedSymbol) mts.getTaintedMembers().get(nam);
          rtt =
              (RelatedTaintedSymbol)
                  Rrt.getListTaintedMembers().get(Rrt.getListTaintedMembers().size() - 1);

          // Caso o parent nao pertenca 'a lista da funcao tainted
          if (rtt.getTaintedMembers().containsKey(scp.getScopeName()) == false) {
            VariableTaintedSymbol var =
                new VariableTaintedSymbol(
                    scp.getScopeName(),
                    scp.getScopeSymbol().getCodeLine(),
                    scp.getScopeSymbol().getTainted(),
                    scp.getScopeSymbol().getFileSymbol());
            rtt.define(var);
          } else { // Caso o parent pertenca 'a lista da funcao tainted
            VariableTaintedSymbol var =
                (VariableTaintedSymbol) rtt.getTaintedMembers().get(scp.getScopeName());
            var.InsertLine(scp.getScopeSymbol().getCodeLine());
            var.InsertFile(scp.getScopeSymbol().getFileSymbol());
          }
        }
        existe = true;
      }
      return existe;
    }

    return false; // nao e' tainted a var
  }