public class GlobalDataApp {
    /**
     * args Flags
     * index 0: presence of -a
     *          analysis without automatic correction
     * index 1: presence of -p
     *          analysis of a project
     * index 2: presence of files
     *          analysis of one or more php files
     * index 3: presence of -sqli
     *          SQLI analysis
     * index 4: presence of -out
     *          stdout forward to output file
     * index 5: presence of -s
     *          show only global summary
     * index 6: presence of -ci
     *          RFI/LFI/DT SCD, OS, Eval analysis 
     * index 7: presence of -xss
     *          XSS Reflected, Store and DOM??
     * index 8: presence of --dbms <dbms>
     *          select DBMS: db2, PostgreSQL, MySQL. If not specify any, MySQL is selected
     *          -dbms mysql; -dbms bd2; -dbms pg
     * index 9: presence of -all
     *          presence of all types of detection
     */
    public static int args_flags[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    public static int numAnalysis = 0;
    public static String dbms = "mysql";
    public static Classifier cf_lr;
    public static Classifier cf_rt;
    public static Classifier cf_svm;
    public static Classifier cf_jrip;
    public static JRip jrip;
    public static Boolean isWindows = false;

    /*
     * Load dataset and build classifier to data mining
     */
    public static Classifier loadClassifier(String nameClassifier) throws IOException{      
        Classifier javaml = null;
        
        /* Load the data set */
        // VERSAO FINAL
        Dataset data;
        if (nameClassifier.equals("svm") == true)
            data = FileHandler.loadDataset(new File("data" + File.separator + "dataset_balanced.data"), 15, ",");
        else
            data = FileHandler.loadDataset(new File("data" + File.separator + "dataset.data"), 15, ",");
        
        
        //Dataset data = FileHandler.loadDataset(new File(".." + File.separator + "data" + File.separator + "dataset.data"), 15, ",");
               
        // Create Weka classifier
        if (nameClassifier.equals("lr") == true){
            Logistic lr = new weka.classifiers.functions.Logistic();
            lr.setDebug(false);
            lr.setMaxIts(-1);
            lr.setRidge(1.0E-8);

            // Wrap Weka classifier in bridge 
            Classifier javaml_lr = new WekaClassifier(lr);
            
            // Build the classifier         
            javaml_lr.buildClassifier(data);
            javaml = javaml_lr;
        }
        
        // Create Weka classifier
        if (nameClassifier.equals("rt") == true){
            RandomTree rt = new weka.classifiers.trees.RandomTree();
            rt.setKValue(0);
            rt.setDebug(false);
            rt.setMaxDepth(0);
            rt.setMinNum(1.0);
            rt.setSeed(1);
            
            // Wrap Weka classifier in bridge 
            Classifier javaml_rt = new WekaClassifier(rt);
            
            // Build the classifier         
            javaml_rt.buildClassifier(data);
            javaml = javaml_rt;
        }
        
        // Create Weka classifier
        if (nameClassifier.equals("jrip") == true){
            jrip = new weka.classifiers.rules.JRip();
            jrip.setCheckErrorRate(true);
            jrip.setDebug(false);
            jrip.setFolds(3);
            jrip.setMinNo(2.0);
            jrip.setOptimizations(2);
            jrip.setSeed(1);
            jrip.setUsePruning(true);
            
          
            // Wrap Weka classifier in bridge 
            Classifier javaml_jrip = new WekaClassifier(jrip);
            
            // Build the classifier         
            javaml_jrip.buildClassifier(data);
            javaml = javaml_jrip;
        }        

        // Create Weka classifier
        if (nameClassifier.equals("svm") == true){
            // SMOTE filter applied to dataset
            /*
            SMOTE smote = new weka.filters.supervised.instance.SMOTE();
            smote.setClassValue("Yes");
            smote.setNearestNeighbors(5);
            smote.setPercentage(100.0);
            smote.setRandomSeed(1);
            */
            
            //kernel
            PolyKernel kernel = new weka.classifiers.functions.supportVector.PolyKernel();
            kernel.setCacheSize(250007);
            kernel.setExponent(1.0);           
            
            SMO svm = new weka.classifiers.functions.SMO();
            svm.setBuildLogisticModels(false);
            svm.setC(1.0);
            svm.setChecksTurnedOff(false);
            svm.setDebug(false);
            svm.setEpsilon(1.0E-12);
            svm.setNumFolds(-1);
            svm.setRandomSeed(1);
            svm.setToleranceParameter(0.001);
            //svm.setFilterType(0);
            svm.setKernel(kernel);
            
            // Wrap Weka classifier in bridge 
            Classifier javaml_svm = new WekaClassifier(svm);
            
            // Build the classifier         
            javaml_svm.buildClassifier(data);
            javaml = javaml_svm;
        } 
        
        return javaml;
    }
} public class Dates {
    public static String DiffDates(Long seconds){
        String diff_date = "", m, s, h;
        int horas, min;
        
        if (seconds >= 1000){
            seconds = seconds/1000;
            horas = (int)Math.floor(seconds / 3600);
            seconds -= horas * 3600;
            min = (int)Math.floor(seconds / 60);
            seconds -= min * 60;
            
            if (horas < 10)
                h = "0"+ Integer.toString(horas);
            else
                h = Integer.toString(horas);
            
            if (min < 10)
                m = "0"+ Integer.toString(min);
            else
                m = Integer.toString(min);

            if (seconds < 10)
                s = "0"+ Long.toString(seconds);
            else
                s = Long.toString(seconds);
            
            diff_date = h + ":" + m + ":" + s + " H";
        }
        else
            //System.out.println("Tempo decorrido " + (end_date - begin_date) + " ms");
            diff_date = seconds + " ms";
        
        return diff_date;
    }
} public class ManageFiles{
    private File f;

    // *** CONSTRUCTORS
    public ManageFiles (String filename){
        //super(filename);
        f = new File(filename);
    }


    // *** METHODS
    /*
     * give base directory of te file
     */
    public File getBaseDir(){
        File baseDir = new File(f.getParent());
        return baseDir;
    }
    
    /*
     * Give just the name of the file
     */
    public File getFileName(){
        File f1 = new File (f.getName());
        return f1;
    }

     /*
     * Give all name of the file (path and name)
     */
    public File getAllFile(){
        File f1 = new File(this.getBaseDir().toString(),this.getFileName().toString());
        return f1;
    }

    /*
     * Verify if file exist
     */
    public Boolean existFile(String filename){
        if (f.exists())
            return true;
        else{
            //String s = "File or directory not found... " + filename;
            //System.out.println(s);
            return false;
        }
    }

    /*
     * Verify if directory exist
     */
    public Boolean existDirectory(String filename){
        if (f.isDirectory() && f.exists())
            return true;
        else{
            //String s = "File or directory not found... " + filename;
            //System.out.println(s);
            return false;
        }
    }
    
    /*
     * Verify if extension of file is php, Php or PHP
     */
    public Boolean validExtension(String filename, int IsSearchFile){
        // .inc include file
        // faltam: .tpl template; .cgi script Perl/C
        String Extensions[] = {".php", ".phps", ".php3", ".php4", ".php5", ".phtml", ".inc", ".phpsec"};
        List<String> ValidExtensionsPhp = Arrays.asList(Extensions);

        int dotPos = filename.lastIndexOf(".");
        if(dotPos == -1)
                return false;
        else{
            String extensionFile = (filename.substring(dotPos)).toLowerCase();
            //if (extension.equals(".php") == false && extension.equals(".PHP") == false && extension.equals(".Php") == false){
            //if (extension.equalsIgnoreCase(".php") == false){
            if (ValidExtensionsPhp.contains(extensionFile) == false){
                if (IsSearchFile == 0){
                    String s = "Type of file not permited... \n" + extensionFile;
                    System.out.println(s);
                }
                return false;
            }
            else
                return true;
        }

    }

    /*
     * Search php files in directory specified by user.
     * This method is recursive
     */
    public void searchPhpFiles(List lista){
        File l[] = this.getAllFile().listFiles();
            for(int i=0; i<l.length; i++){
                if (l[i].isFile() == true){
                    ManageFiles aux = new ManageFiles(l[i].toString());
                    if (aux.validExtension(l[i].toString(), 1) == true){
                        lista.add(l[i].toString());
                    }
                }
                if (l[i].isDirectory() == true){
                    ManageFiles aux = new ManageFiles(l[i].toString());
                    aux.searchPhpFiles(lista);
                }

            }
    }

    /*
     * Search the index.php file in list of files of the project directory
     */
    public void searchIndexPhp(List<String> lista){    
        for(int i=0; i<lista.size(); i++){
            String au = lista.get(i).toString();
            String[] a;
            if (GlobalDataApp.isWindows.booleanValue() == true)
                a = au.split(Pattern.quote(File.separator));
            else
                a = au.split(File.separator);
            String[] b = (a[(a.length)-1].toUpperCase()).split(".PHP");                      
            if(b[0].equalsIgnoreCase("INDEX") == true){
                String aux = lista.get(0).toString();
                lista.set(0, lista.get(i).toString());
                lista.set(i, aux);
                break;
            }
        }
    }

    public String composePathFile(String s, File baseDir) throws IOException{
        String final_file = "";

        if (s.startsWith("\"") || s.startsWith("\'"))
            s = s.substring(1, s.length()-1);
        
        File ff = new File(s);
        File base;
        if (ff.exists() == false){ // Se a path do file nao e' passada toda no include 
            String a[];
            if (GlobalDataApp.isWindows.booleanValue() == true)
                a = s.split(Pattern.quote(File.separator));
            else
                a = s.split(File.separator);
            base = new File(baseDir.toString());
            File b[] = base.listFiles();

            if (a.length == 0){ // se passou somente path sem file no include
                String ss = "File not specified in \"include\" instruction";
                System.out.println(ss);
            }
            else {
                int cont = 0;
                for (String aux : a){
                    if (aux.equals("..") == true)
                        cont++;
                }
                if (cont == 0){
                    if (a[0].equals(".") == true){ // se passou o file relativo a base.dir
                        String aux = s.substring(2);
                        final_file = base.toString() + File.separator + aux;
                    }
                    else // se passou no include uma path de subdirs de base.dir
                        final_file = base.toString() + File.separator + s;
                }
                else{ // se passou no include uma path de subdirs atras de base.dir
                    String[] c;
                    if (GlobalDataApp.isWindows.booleanValue() == true)
                        c = base.toString().split(Pattern.quote(File.separator));
                    else
                        c = base.toString().split(File.separator);
                    
                    //String c[] = base.toString().split(File.separator);
                    String d = File.separator;
                    int i;
                    for (i=0; i < c.length - cont; i++)
                        d = d + c[i] + File.separator;

                    for (i = cont; i < a.length - 1; i++)
                        d = d + a[i] + File.separator;

                    final_file = d + a[a.length-1];
                } // if (cont == 0){
            } // if (a.length == 0)
        }
        else {// if (ff.exists())
            final_file = s;
        }
        
        if (final_file.isEmpty() == false){
            //System.out.println("File not found...");
        //else{
            ff = new File(final_file);
            if (ff.exists() == false){
                //System.out.println("File not found..." + final_file);
                final_file = "";
            }
        }
        
        return final_file;
    }

    public int getNumberLinesFile() throws FileNotFoundException{
        String line = "";
        int count = 0;
        Scanner fscanner = new Scanner(new FileReader(this.f.toString()));
        while (fscanner.hasNextLine()) {
            line = fscanner.nextLine();
            count += 1;
        }
        fscanner.close();
        return count;
    }

   public String getLineOfCode(int line){
       String codeLine = "";
       Scanner fscanner = null;
       try {
            fscanner = new Scanner(new FileReader(this.f.toString()));


       for (int jj=1; jj<=line;jj++){
            codeLine = fscanner.nextLine();
       }
       
       String aux = codeLine;
       codeLine = "";
       while (aux.lastIndexOf(';') == -1){
            if (codeLine.isEmpty() == true)
                codeLine += aux.trim();
            else
                codeLine += " " + aux.trim();
            aux = fscanner.nextLine();
       }

       if (codeLine.isEmpty())
           codeLine = aux;
       else
           codeLine += " " + aux.trim();

       fscanner.close();
       } catch (Exception e){}       

       return codeLine;
   }

    /*
     * clean html code from a given file
     */
    public String cleanHTML(String f) throws FileNotFoundException, IOException{
        String[] filename;
        if (GlobalDataApp.isWindows.booleanValue() == true)
            filename = f.split(Pattern.quote(File.separator));
        else
            filename = f.split(File.separator);        
        
        //String[] filename = f.split(File.separator);
        String[] filename_parts = filename[filename.length-1].split("[.]");

        InputStream in = new FileInputStream(f);
        Scanner fscanner = new Scanner(in);
        String temp_file = this.getBaseDir().toString() + File.separator + filename_parts[0] + "_000." +filename_parts[1];
        File out = new File(temp_file);
        FileWriter outFile = new FileWriter(out);

        String aux[], auxx = null;
        Boolean firstOpen_bodyString = false;
        Boolean close_bodyString = false;
        Boolean more_bodyString = false;
        int lineLastClose = 0;
        
        Pattern open = Pattern.compile("<[?]"+"php");
        Pattern open1 = Pattern.compile("<[?]");
        Pattern close = Pattern.compile("[?]>");
        Matcher matcher_open;
        Matcher matcher_open1;
        Matcher matcher_close;

        String s = null, s1 = null, codeLine;
        int countLines = 0, blankLines = 0;
        
        for (; fscanner.hasNextLine();) {
            codeLine = fscanner.nextLine();
            countLines++;            
            matcher_open = open.matcher(codeLine);
            matcher_open1 = open1.matcher(codeLine);
            matcher_close = close.matcher(codeLine);

            if ((matcher_open.find() || matcher_open1.find()) && !matcher_close.find()){              
                if (firstOpen_bodyString == false){
                    firstOpen_bodyString=true;
                    close_bodyString = false;
                    outFile.write(codeLine+"\n");
                }
                else{
                    more_bodyString = true;
                    close_bodyString = false;
                    if (matcher_open.find())
                        aux = open.split(codeLine);
                    else
                        aux = open1.split(codeLine);

                    if (aux.length <= 1)
                        outFile.write("\n");
                    else{
                        if (aux[1].startsWith("php")){
                            aux = aux[1].split("php");
                            try{
                                outFile.write(aux[1] + "\n");
                            }catch (Exception e) {
                                outFile.write("\n");
                            }
                        }
                        else{
                            if (aux[1].startsWith(" ")){
                                try{
                                    outFile.write(aux[1] + "\n");
                                }catch (Exception e) {
                                    outFile.write("\n");
                                }                                
                            }
                        }
                    }
                }
            }
            else{             
                if (matcher_open.find() || matcher_open1.find()) {
                    lineLastClose = countLines;
                    if (matcher_open.find())
                        aux = open.split(codeLine);
                    else
                        aux = open1.split(codeLine);
                    
                    if (aux[1].startsWith("php "))
                        auxx = aux[1].substring(3);
                    else
                        auxx = aux[1];

                    aux = close.split(auxx);
                    if (!aux[0].endsWith(";"))
                        aux[0] = aux[0] + ";";                  
                    
                    if (firstOpen_bodyString == false){
                           // s = "<?php " + aux[0] + " ?>" + "\n";
                            s = "<?php " + aux[0];
                            outFile.write(s + "\n");
                            firstOpen_bodyString = true;
                            close_bodyString = true;
                    }
                    else{
                        more_bodyString = false;
                        close_bodyString = true;
                        outFile.write(aux[0] + "\n");
                    }
                }
                else{
                    if(matcher_close.find()){
                        lineLastClose = countLines;
                        //if (more_bodyString == true)
                            more_bodyString = false;
                        //else
                            close_bodyString = true;

                        aux = close.split(codeLine);
                        try{
                            outFile.write(aux[0] + "\n");
                        } catch (Exception e) {
                            outFile.write("\n");
                        }

                    }
                    else{
                        if ((more_bodyString == true || close_bodyString == false) && firstOpen_bodyString == true)
                            outFile.write(codeLine+"\n");
                        else{
                            outFile.write("\n");
                            blankLines++;
                        }
                    }
                }
            }
        }


        fscanner.close();
        outFile.close();

        // Para escrever a tag end_php na linha que aparece por ultimo
        in = new FileInputStream(temp_file);
        fscanner = new Scanner(in);
        String final_file = this.getBaseDir().toString() + File.separator + filename_parts[0] + "_0." +filename_parts[1];
        out = new File(final_file);
        outFile = new FileWriter(out);         
        countLines = 0;
        for (; fscanner.hasNextLine();) {
            codeLine = fscanner.nextLine();
            countLines++;
            if (countLines == lineLastClose)
                outFile.write(codeLine + "?>\n");
            else
                outFile.write(codeLine + "\n");
        }        
        fscanner.close();
        outFile.close();
        File t = new File(temp_file);
        t.delete();
          
        
        if (countLines == blankLines){
            out = new File(final_file);
            outFile = new FileWriter(out);
            outFile.write("<?php\n");
            outFile.write("?>\n");
            outFile.close();
        }
        return final_file;
    }   
   
    
    /*
     * Replace reserved words in variable names to keyword_00
     */
    public String keywordTo00(String ori, String html_clear) throws FileNotFoundException, IOException{
        String final_file = ori;

        // KeyWords
        String ReservedWords[] = {"case", "if", "array", "list", "else", "elseif", "for", "foreach", "while", "do",
                                  "switch", "default", "function", "global", "and", "or", "xor", "instanceof", "return", //};
                                  "print", "public"};
        List<String> KeyWords = Arrays.asList(ReservedWords);

        InputStream in = new FileInputStream(html_clear);
        Scanner fscanner = new Scanner(in);

        ArrayList<String> al = new ArrayList<String>();
        while( fscanner.hasNext() ) {
            String all = fscanner.nextLine();
            al.add(all);
        }
        fscanner.close();

        File out = new File(final_file);
        FileWriter outFile = new FileWriter(out);

        Pattern p = Pattern.compile("[a-zA-Z_0-9]");
        Matcher mat;
        boolean b;
        String linef;
        int nline;

        for (String aux : KeyWords){
            nline = 0;
            for( String line : al ) {
                linef = "";
                if (line.contains(aux) == true){
                    int indOf=0;
                    while (indOf != -1){
                        indOf = line.indexOf(aux);
                        if (indOf != -1){
                            if (indOf != 0){
                                String[] a = line.split(aux);
                                if (line.charAt(indOf-1) == '$'){
                                    try{
                                    char c = line.charAt(indOf + aux.length());
                                    mat = p.matcher(Character.toString(c));
                                    if (mat.matches() == false){
                                        linef = linef + a[0] + aux + "_00";
                                    }
                                    else
                                        linef = linef + a[0] + aux;
                                    } catch (Exception e){}
                                    line = line.substring(indOf + aux.length());
                                }
                                else{
                                    line = line.substring(indOf + aux.length());
                                    linef = linef + a[0] + aux;
                                }
                            }
                            else{
                                linef += aux;
                                line = line.substring(aux.length());
                            }

                        }
                        else
                            linef += line;
                    }
                    al.set(nline, linef);
                }
                nline++;
            }
        }

        for( String line : al ) {
            outFile.write(line+"\n");
        }
        outFile.close();

        return final_file;
    }

    /*
     * Process inverse of keywordTo00, ie, Replace keyword_00 to keyword
     */
    public void keywordFrom00(String html_clear) throws FileNotFoundException, IOException{
        // KeyWords_00
        String ReservedWords[] = {"case_00", "if_00", "array_00", "list_00", "else_00", "elseif_00", "for_00", "foreach_00",
                                  "while_00", "do_00", "switch_00", "default_00", "function_00", "global_00", "and_00",
                                  "or_00", "xor_00", "instanceof_00", "return_00", "print_00", "public_00"};
        List<String> KeyWords = Arrays.asList(ReservedWords);

        InputStream in = new FileInputStream(html_clear);
        Scanner fscanner = new Scanner(in);

        ArrayList<String> al = new ArrayList<String>();
        while( fscanner.hasNext() ) {
            String all = fscanner.nextLine();
            al.add(all);
        }
        fscanner.close();

        File out = new File(html_clear + "_tmp");
        FileWriter outFile = new FileWriter(out);

        Pattern p = Pattern.compile("[a-zA-Z_0-9]");
        Matcher mat;
        boolean b;
        String linef;
        int nline;

        for (String aux : KeyWords){
            nline = 0;
            for( String line : al ) {
                linef = "";
                if (line.contains(aux) == true){
                    int indOf=0;
                    while (indOf != -1){
                        indOf = line.indexOf(aux);
                        if (indOf != -1){
                            if (indOf != 0){
                                String[] a = line.split(aux);
                                if (line.charAt(indOf-1) == '$'){
                                    char c = line.charAt(indOf + aux.length());
                                    mat = p.matcher(Character.toString(c));
                                    if (mat.matches() == false){
                                        linef = linef + a[0] + aux.substring(0, aux.length()-4);
                                    }
                                    else
                                        linef = linef + a[0] + aux;
                                    line = line.substring(indOf + aux.length());
                                }
                                else{
                                    line = line.substring(indOf + aux.length());
                                    linef = linef + a[0] + aux;
                                }
                            }
                        }
                        else
                            linef += line;
                    }
                    al.set(nline, linef);
                }
                nline++;
            }
        }

        for( String line : al ) {
            outFile.write(line+"\n");
        }
        outFile.close();

        //Renomear file html_clear_tmp to html_clear
        File bb = new File(html_clear);
        out.renameTo(bb);
    }

    /*
     * replace the html code removed on begin of the process
     */
    public void putHtml(String ori, String html_clear) throws FileNotFoundException, IOException{
        InputStream in_ori = new FileInputStream(ori);
        Scanner fscanner_ori = new Scanner(in_ori);
        InputStream in_html = new FileInputStream(html_clear);
        Scanner fscanner_html = new Scanner(in_html);
        File out = new File(html_clear + "_tmp");
        FileWriter outFile = new FileWriter(out);

        int nline_html = 1;
        int nline_ori = 1;
        String line;
        while( fscanner_html.hasNext() ) {
            line = fscanner_html.nextLine();
            if (line.isEmpty() == false){
                outFile.write(line+"\n");
            }
            else{
                for(int i = nline_ori; i<nline_html; i++)
                    fscanner_ori.nextLine();
                line = fscanner_ori.nextLine();
                outFile.write(line+"\n");
                nline_ori = nline_html+1;
            }
            nline_html++;
        }

        while( fscanner_ori.hasNext() ) {
            line = fscanner_ori.nextLine();
            outFile.write(line+"\n");
        }
        fscanner_ori.close();
        fscanner_html.close();
        outFile.close();

        //Renomear file html_clear_tmp to html_clear
        File bb = new File(html_clear);
        out.renameTo(bb);

    }
    
    // copia file php em analise para Newfiles para podermos introduzir as correcoes no codigo
    public void copyFileToNewfiles(String targetDir, String targetName) throws FileNotFoundException, IOException{ 
        InputStream source = new FileInputStream(this.getAllFile().toString());
        Scanner fscanner_source = new Scanner(source);
        File out = null;
        if (targetName == null){
            try{
                int ind = this.getAllFile().toString().lastIndexOf(File.separator);
                String s = this.getAllFile().toString().substring(0, ind);
                File dir = new File(targetDir + s);
                dir.mkdirs();   
                out = new File(targetDir + this.getAllFile().toString());
            } catch (Exception e) {}
        }
        else{
            try{
                int ind = targetName.lastIndexOf(File.separator);
                String s = targetName.substring(0, ind);
                File dir = new File(targetDir + s);
                dir.mkdirs();   
                out = new File(targetDir + targetName);
            } catch (Exception e) {}
        }
            
        FileWriter outFile = new FileWriter(out);
        String line;
        while( fscanner_source.hasNext() ) {
            line = fscanner_source.nextLine();
            outFile.write(line+"\n");
        }
        fscanner_source.close();
        outFile.close();
    }
    
    // copia file php de improvements para Newfiles. Sao os files de codigo php para sanitizar inputs
    public void copyFileImprovement(String targetDir) throws FileNotFoundException, IOException{ 
        File dest = new File(targetDir);
        dest.mkdirs();
        File src = new File(this.getAllFile().toString());

        // Copy files
        String[] l = src.list();
        for(int i=0; i < l.length; i++){
            InputStream source = new FileInputStream(src + File.separator + l[i]);
            Scanner fscanner_source = new Scanner(source);

            //File out = new File(src + File.separator + l[i] + "_temp");
            File out = new File(dest + File.separator + l[i]);
            FileWriter outFile = new FileWriter(out);
            String line;
            while( fscanner_source.hasNext() ) {
                line = fscanner_source.nextLine();
                outFile.write(line+"\n");
            }
            fscanner_source.close();
            outFile.close();
        }
    }
    
    // Delete a no empty directory
    public Boolean deleteDir(File directory) {
        if (directory.isDirectory()) {
            String[] subDirs = directory.list();
            for (int i=0; i<subDirs.length; i++) {
                boolean success = deleteDir(new File(directory, subDirs[i]));
                if (!success) {
                    return false;
                }
            }
        }

        // The directory is now empty so delete it
        return directory.delete();
    } 
} public class buildAST {
    private CommonTreeNodeStream nodes = null;
    private Boolean validFile = false;
    private String finalFile;
    
    
    // *** CONSTRUCTORS
//    public buildAST(String filename, SymbolTable st, List files, int fileVerified) throws IOException{
    public buildAST(String filename, int fileVerified) throws IOException {
        String final_file;
        Boolean encontrei = false;
        Boolean valid_file = false;

        if (fileVerified == 0){ // somente para ficheiros de include/require
            ManageFiles ff = new ManageFiles(filename);
            final_file = ff.composePathFile(filename, ff.getBaseDir());
            ManageFiles fff = new ManageFiles(final_file);
            if (fff.existFile(final_file)){
                encontrei = true;
                valid_file = true;
            }           
        }
        else {// if (verified == 1)
            final_file = filename;
            valid_file = true;
            this.validFile = true;
            this.finalFile = final_file;
        }

        if (valid_file == true){
        try {
            InputStream is = new FileInputStream(final_file);
       
            // Create input stream from standard input
            ANTLRInputStream input = new ANTLRInputStream(is);
            // Create a lexer attached to that input stream
            PhpLexer lexer = new PhpLexer(input);
            // Create a stream of tokens pulled from the lexer
            CommonTokenStream tokens = new CommonTokenStream(lexer);

            // Create a parser attached to the token stream
            PhpParser parser = new PhpParser(tokens);
            RuleReturnScope r = parser.compilationUnit();   // launch parser

            // Get AST from result of parser
            CommonTree t = (CommonTree)r.getTree();
            //CommonTreeNodeStream nodes = new CommonTreeNodeStream(t);
            this.nodes = new CommonTreeNodeStream(t);
            nodes.setTokenStream(tokens);
        } catch (FileNotFoundException e) {
            System.err.println("File not found: " + final_file);
        } catch (Exception e) {
            System.err.println("Error parsing " + final_file);
            System.err.println(e.getMessage());
        }
        }

    }
    
    public CommonTreeNodeStream getNodes(){
        return this.nodes;
    }
    
    public Boolean getValidFile(){
        return this.validFile;
    }
    
    public String getFinalFile(){
        return this.finalFile;
    }

} public class SymbolTable implements Scope{
    String name;
    //Map<String, Symbol> symbols;
    List<Symbol> symbols;
    Boolean haveFunctions;
    Boolean haveClasses;
    List<String> includeFiles;
    Map <String, Symbol> aliases;
    Map <String, Symbol> globalVars;
    MethodTableCalls methodCallInstance;    // para somente os StaticMemberAccees diferentes de self e parent
    MethodTaintedTable methTaintedInstance; // para somente os StaticMemberAccees diferentes de self e parent


    // *** CONSTRUCTORS
    public SymbolTable(String name) {
        this.name = name;
        //symbols = new LinkedHashMap<String, Symbol>();
        symbols = new ArrayList<Symbol>();
        haveFunctions = false;
        haveClasses = false;
        includeFiles = new ArrayList<String>();
        this.aliases = new LinkedHashMap<String, Symbol>();
        this.globalVars = new LinkedHashMap<String, Symbol>();

        // cria a tabela para as st dos StaticMemberAccees que serao chamados diferentes de self e parent
        methodCallInstance = new MethodTableCalls(name);

        // cria a tainted table para as chamadas dos StaticMemberAccees diferentes de self e parent
        methTaintedInstance = new MethodTaintedTable(name);
   }

    // *** METHODS

    // Satisfy Scope interface
    public String getScopeName() {
    	//return "global";
        return name;
    }

    // am I nested in another?
    public Scope getEnclosingScope() {
    	return null;
    }

    /*
     * Give the Map that contain the Symbols of main Map
     * This symbols are root symbol the scopes CallSymbol (for Callfunction
     * or assign instrutions) or MethodSymbol (for user function definition)
     */
    public List getMembers() {
        return symbols;
    }

    /*
     * Give the root Symbol of the scope. In another words, give the symbol
     * that create a new scope.
     * Here, in main table of symbols, don't exist root symbol.
     */
    public Symbol getScopeSymbol() {
    	return null;
    }

    /*
     * Tell if file have functions definied by the programmer
     */
    public Boolean getHaveFunctions() {
    	return haveFunctions;
    }

    /*
     * Tell if file have classes definied by the programmer
     */
    public Boolean getHaveClasses() {
    	return haveClasses;
    }

    /*
     * Give the list of the include files that the analysed file have
     */
    public List<String> getIncludeFiles() {
    	return includeFiles;
    }

    /*
     * Give the Map of the alises defined inthe symbolTable
     */
    public Map getAliases(){
        return this.aliases;
    }

    public Map getGlobalVarsOfSymbolTable() {
        return globalVars;
    }

    public MethodTableCalls getMethodCallInstance() {
        return this.methodCallInstance;
    }

    public MethodTaintedTable getMethodTaintedInstance() {
        return this.methTaintedInstance;
    }
    
    public String getInstanceNameFromAliases(String s, InstanceTable instTab){
        String instName = "";
        boolean found = false;
        while (found == false){
            if (instTab.containsInstance(s) == true){
                instName = s;
                found = true;
            }
            else{
                if (this.getAliases().containsKey(s)){
                    Symbol sym = (Symbol) this.getAliases().get(s);
                    s = sym.getName();
                }
            }
        }
        return instName;
    }

    /*
     * Return a specific symbol
     */
    public Symbol getSymbolOfListSymbols(String symName){
        Symbol sym_final = null;
        Iterator <Symbol> it = this.getMembers().iterator();
        Symbol sym;
        for (;it.hasNext();){
                sym = it.next();
                if (sym.getName().equals(symName) == true){
                    sym_final = sym;
                    break;
                }
        }
        return sym_final;
    }

    /*
     * Tells if the symbols list contains a gived symbol
     */
    public Boolean containsSymbol(String symName){
        Iterator <Symbol> it = this.getMembers().iterator();
        Symbol sym;
        Boolean haveSymbol = false;
        for (;it.hasNext();){
                sym = it.next();
                if (sym.getName().equals(symName) == true){
                    haveSymbol = true;
                    break;
                }
        }
        return haveSymbol;
    }

    /*
     * Insert a root symbol (new scope) in main Map.
     */
    public void define(Symbol sym, Scope scp, Boolean IsVariableSymbol) {
        symbols.add(sym);
        sym.setRootScope(scp);
        sym.setScope(this);
        sym.setIsVariableSymbol(IsVariableSymbol);
    }

    /*
     * Set true if the analysed file have functions defined by user
     */
    public void setHaveFunctions(){
        haveFunctions = true;
    }

    /*
     * Set true if the analysed file have classes defined by user
     */
    public void setHaveClasses(){
        haveClasses = true;
    }
    
    public void setGlobalVarSymbolTable(String varName, Symbol gvar) {
        globalVars.put(varName, gvar);
    }

    /*
     * Set true if the analysed file have functions defined by user
     */
    public void setAllSymbols(List<Symbol> syms){
        symbols.addAll(syms);
    }
    
    /*
     * Set true if the analysed file have functions defined by user
     */
    public void setAllIncludeFiles(List<String> incs){
        includeFiles.addAll(incs);
    }    

    /*
     * Not relevant here!
     */
    //public Boolean resolve(String name, TaintedTable mts, UntaintedTable mus) {
    public void resolveSymbol(Scope scp, Symbol sy, TaintedTable mts, UntaintedTable mus, String file){
    	//return symbols.get(name);
    //    return true;
    }


    public Boolean resolve(Symbol symb, TaintedTable mts, UntaintedTable mus) {
        return true;
    }
     
    /*
     * Move include file symbolTable from mst to mift
     */
    public void mvIncludeFiles(List fileList) throws IOException{
        for(Iterator <String> it1 = this.getIncludeFiles().iterator(); it1.hasNext();){
            String s = it1.next();
            if(GlobalDataApp.args_flags[3] == 1){
                if (GlobalDataSqli.MainSymbolTable.containsKey(s) == true){
                    GlobalDataSqli.MainIncludeFilesTable.put(s, (SymbolTable)GlobalDataSqli.MainSymbolTable.get(s));
                    GlobalDataSqli.MainSymbolTable.remove(s);
                }
                else{
                    if (GlobalDataSqli.MainIncludeFilesTable.containsKey(s) == false){
                        try {
                            // file include do not exists in mst and mift
                            // Create AST
                            buildAST ast = new buildAST(s, 0);
                            CommonTreeNodeStream nodes = ast.getNodes();
                            
                            // build walker tree to SQLI
                            buildWalkerTree_sqli sqli = new buildWalkerTree_sqli(nodes, s, GlobalDataSqli.MainSymbolTable, GlobalDataSqli.MainIncludeFilesTable,
                                    GlobalDataSqli.MainFunctionsTable, GlobalDataSqli.MainFunctionsTaintedTable,
                                    GlobalDataSqli.MainTaintedTable, GlobalDataSqli.mus, GlobalDataSqli.MainLinesToCorrect,
                                    GlobalDataSqli.MainClassesTable, GlobalDataSqli.MainInstancesTable, fileList);
                            
                            GlobalDataSqli.MainIncludeFilesTable.put(s, (SymbolTable)GlobalDataSqli.MainSymbolTable.get(s));
                            GlobalDataSqli.MainSymbolTable.remove(s);
                        } catch (RecognitionException ex) {
                            Logger.getLogger(SymbolTable.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }

                SymbolTable st_aux = GlobalDataSqli.MainIncludeFilesTable.get(s);
                if (st_aux.getIncludeFiles().isEmpty() == false){
                    st_aux.mvIncludeFiles(fileList);
                }
            }

            if(GlobalDataApp.args_flags[6] == 1){
                if (GlobalDataCodeInj.MainSymbolTable.containsKey(s) == true){
                    GlobalDataCodeInj.MainIncludeFilesTable.put(s, (SymbolTable)GlobalDataCodeInj.MainSymbolTable.get(s));
                    GlobalDataCodeInj.MainSymbolTable.remove(s);
                }
                else{
                    if (GlobalDataCodeInj.MainIncludeFilesTable.containsKey(s) == false){
                        // file include do not exists in mst and mift
                        // Create AST
                        buildAST ast = new buildAST(s, 0);
                        CommonTreeNodeStream nodes = ast.getNodes();

                        // build walker tree to SQLI
                        buildWalkerTree_CodeInj ci = new buildWalkerTree_CodeInj(nodes, s, GlobalDataCodeInj.MainSymbolTable, GlobalDataCodeInj.MainIncludeFilesTable,
                                                                            GlobalDataCodeInj.MainFunctionsTable, GlobalDataCodeInj.MainFunctionsTaintedTable,
                                                                            GlobalDataCodeInj.MainTaintedTable, GlobalDataCodeInj.mus, GlobalDataCodeInj.MainLinesToCorrect,
                                                                            GlobalDataCodeInj.MainClassesTable, GlobalDataCodeInj.MainInstancesTable, fileList); 

                        GlobalDataCodeInj.MainIncludeFilesTable.put(s, (SymbolTable)GlobalDataCodeInj.MainSymbolTable.get(s));
                        GlobalDataCodeInj.MainSymbolTable.remove(s);
                    }
                }

                SymbolTable st_aux = GlobalDataCodeInj.MainIncludeFilesTable.get(s);
                if (st_aux.getIncludeFiles().isEmpty() == false){
                    st_aux.mvIncludeFiles(fileList);
                }
            }

            if(GlobalDataApp.args_flags[7] == 1){
                if (GlobalDataXSS.MainSymbolTable.containsKey(s) == true){
                    GlobalDataXSS.MainIncludeFilesTable.put(s, (SymbolTable)GlobalDataXSS.MainSymbolTable.get(s));
                    GlobalDataXSS.MainSymbolTable.remove(s);
                }
                else{
                    if (GlobalDataXSS.MainIncludeFilesTable.containsKey(s) == false){
                        // file include do not exists in mst and mift
                        // Create AST
                        buildAST ast = new buildAST(s, 0);
                        CommonTreeNodeStream nodes = ast.getNodes();

                        // build walker tree to SQLI
                        buildWalkerTree_XSS xss = new buildWalkerTree_XSS(nodes, s, GlobalDataXSS.MainSymbolTable, GlobalDataXSS.MainIncludeFilesTable,
                                                                            GlobalDataXSS.MainFunctionsTable, GlobalDataXSS.MainFunctionsTaintedTable,
                                                                            GlobalDataXSS.MainTaintedTable, GlobalDataXSS.mus, GlobalDataXSS.MainLinesToCorrect,
                                                                            GlobalDataXSS.MainClassesTable, GlobalDataXSS.MainInstancesTable, fileList);

                        GlobalDataXSS.MainIncludeFilesTable.put(s, (SymbolTable)GlobalDataXSS.MainSymbolTable.get(s));
                        GlobalDataXSS.MainSymbolTable.remove(s);
                    }
                }

                SymbolTable st_aux = GlobalDataXSS.MainIncludeFilesTable.get(s);
                if (st_aux.getIncludeFiles().isEmpty() == false){
                    st_aux.mvIncludeFiles(fileList);
                }
            }
        }        
    }

    
    
    /*
     * Move include file symbolTable from mst to mift
     */
    public void mvIncludeFiles(List fileList, String file) throws IOException{
    if(GlobalDataApp.args_flags[3] == 1){
        if (GlobalDataSqli.MainIncludeFilesTable.containsKey(file) == false){
            if (GlobalDataSqli.MainSymbolTable.containsKey(file) == true){                               
                GlobalDataSqli.MainIncludeFilesTable.put(file, (SymbolTable)GlobalDataSqli.MainSymbolTable.get(file));
                GlobalDataSqli.MainSymbolTable.remove(file);
            }
            else{
                try {
                    // file include do not exists in mst and mift
                    // Create AST
                    buildAST ast = new buildAST(file, 0);
                    CommonTreeNodeStream nodes = ast.getNodes();
                    
                    // build walker tree to SQLI
                    buildWalkerTree_sqli sqli = new buildWalkerTree_sqli(nodes, file, GlobalDataSqli.MainSymbolTable, GlobalDataSqli.MainIncludeFilesTable,
                            GlobalDataSqli.MainFunctionsTable, GlobalDataSqli.MainFunctionsTaintedTable,
                            GlobalDataSqli.MainTaintedTable, GlobalDataSqli.mus, GlobalDataSqli.MainLinesToCorrect,
                            GlobalDataSqli.MainClassesTable, GlobalDataSqli.MainInstancesTable, fileList);
                    
                    GlobalDataSqli.MainIncludeFilesTable.put(file, (SymbolTable)GlobalDataSqli.MainSymbolTable.get(file));
                    GlobalDataSqli.MainSymbolTable.remove(file);
                } catch (RecognitionException ex) {
                    Logger.getLogger(SymbolTable.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        } 
    }
        
    if(GlobalDataApp.args_flags[6] == 1){
        if (GlobalDataCodeInj.MainIncludeFilesTable.containsKey(file) == false){
            if (GlobalDataCodeInj.MainSymbolTable.containsKey(file) == true){
                GlobalDataCodeInj.MainIncludeFilesTable.put(file, (SymbolTable)GlobalDataCodeInj.MainSymbolTable.get(file));
                GlobalDataCodeInj.MainSymbolTable.remove(file);
            }
            else{
                try{
                    // file include do not exists in mst and mift
                    // Create AST
                    buildAST ast = new buildAST(file, 0);
                    CommonTreeNodeStream nodes = ast.getNodes();

                    // build walker tree to Code Injection
                    buildWalkerTree_CodeInj ci = new buildWalkerTree_CodeInj(nodes, file, GlobalDataCodeInj.MainSymbolTable, GlobalDataCodeInj.MainIncludeFilesTable,
                                                                        GlobalDataCodeInj.MainFunctionsTable, GlobalDataCodeInj.MainFunctionsTaintedTable,
                                                                        GlobalDataCodeInj.MainTaintedTable, GlobalDataCodeInj.mus, GlobalDataCodeInj.MainLinesToCorrect,
                                                                        GlobalDataCodeInj.MainClassesTable, GlobalDataCodeInj.MainInstancesTable, fileList);                                

                    GlobalDataCodeInj.MainIncludeFilesTable.put(file, (SymbolTable)GlobalDataCodeInj.MainSymbolTable.get(file));
                    GlobalDataCodeInj.MainSymbolTable.remove(file);
                } catch (Exception ex) {
                    Logger.getLogger(SymbolTable.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        } 
    }        
 
    if(GlobalDataApp.args_flags[7] == 1){
        if (GlobalDataXSS.MainIncludeFilesTable.containsKey(file) == false){
            if (GlobalDataXSS.MainSymbolTable.containsKey(file) == true){
                GlobalDataXSS.MainIncludeFilesTable.put(file, (SymbolTable)GlobalDataXSS.MainSymbolTable.get(file));
                GlobalDataXSS.MainSymbolTable.remove(file);
            }
            else{
                try{
                    // file include do not exists in mst and mift
                    // Create AST
                    buildAST ast = new buildAST(file, 0);
                    CommonTreeNodeStream nodes = ast.getNodes();

                    // build walker tree to XSS
                    buildWalkerTree_XSS xss = new buildWalkerTree_XSS(nodes, file, GlobalDataXSS.MainSymbolTable, GlobalDataXSS.MainIncludeFilesTable,
                                                                        GlobalDataXSS.MainFunctionsTable, GlobalDataXSS.MainFunctionsTaintedTable,
                                                                        GlobalDataXSS.MainTaintedTable, GlobalDataXSS.mus, GlobalDataXSS.MainLinesToCorrect,
                                                                        GlobalDataXSS.MainClassesTable, GlobalDataXSS.MainInstancesTable, fileList);                                

                    GlobalDataXSS.MainIncludeFilesTable.put(file, (SymbolTable)GlobalDataXSS.MainSymbolTable.get(file));
                    GlobalDataXSS.MainSymbolTable.remove(file);
                } catch (Exception ex) {
                    Logger.getLogger(SymbolTable.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        } 
    }           
}    
      

    /*
     * 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");
         }
    }


    @Override
    public String toString() {
    	return getScopeName()+":"+symbols;
    }

    public void resolveSymbolIncludeSQLI(Scope scp, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map varsDB, Map mftt, Map MainLinesToCorrect) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String resolveVarInclude(Scope scp, SymbolTable st) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void resolveSymbolFunctionSQLI(MethodSymbol mt, Scope rootScope, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map varsDB, Map mftt, Map MainLinesToCorrect) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Boolean verifyNumberVarList(int num_var){
        throw new UnsupportedOperationException("Not supported yet.");    
    }
    
    public void populateList(Scope scp_left, Scope scp_right, int num_var, TaintedTable mts, UntaintedTable mus, String filename){
        throw new UnsupportedOperationException("Not supported yet.");    
    }

    public String buildCorrectSQL(String connDB, String nameDB, int lineMysqliBindParam, List UserInput, TaintedTable mts_princ, SymbolTable st, Map MainLinesToCorrect) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Boolean buildCorrectCodeInj(String fileInc, List UserInput, TaintedTable mts_princ, SymbolTable st, Map MainLinesToCorrect){
            throw new UnsupportedOperationException("Not supported yet.");
    }

    public void resolveSymbolClass(TaintedTable mts, UntaintedTable mus, String filename) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void printtt(String string, Scope cp){
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void resolveSymbolParam(TaintedTable mts, UntaintedTable mus, String filename) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    public void resolveParam(Symbol symb, TaintedTable mts, UntaintedTable mus) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

} public class Symbol implements Cloneable{
    private String name;                // All symbols at least have a name
    private int tainted = 0;                // All symbols are untainted (0), when are initialized
    private int line;                   // Code Line of the symbol
    private Scope scope;                // Symbol have a scope
    private Scope rootScope;            // Symbol can be a new scope
    private Boolean alfanumeric = false; // parameters, arguments or values are alfanumerics
    private String fileSymbol; // Symbol pertence a file - string is the completed path of the file
    private Boolean isVariableSymbol=false;   // if the symbol is a object of VariableSymbol class
    private Boolean isSecureFunction = false; // if the symbol represents a mysql secure function
    private Boolean isFunction = false;  // if the symbol is call function
    private Boolean isUserFunction = false;  // if the symbol is call user function
    private Boolean isParameterUserFunction = false;  // if the symbol is a parameter of a user funcrion or a method class
    private Boolean isTaintedFunction = false; // if the symbol represents a tainted function (ex. mysql sqli)
    private Boolean isVulDetected = false; // if the symbol is a tainted function and it was detected as vulnerable (ex. mysql sqli)
    private Boolean isInstance = false;  // if the symbol is a new instance of a class
    private Boolean isClone = false;  // if the symbol is a clone of a instance class
    private Boolean isStaticMember = false;  // if the symbol is a call the one method in static way
    private Boolean isClassInstruction = false;  // if the symbol represents a class instruction
    private Boolean isClassMethod = false;  // if the symbol is call method of the class
    // public Type type;   // Symbols have types

    // *** CONSTRUCTORS
    public Symbol(String name, int line, String file) {
	this.name = name;
        this.line = line;
        this.fileSymbol = file;
    }
    public Symbol(String name, int tainted, int line, String file) {
	this.name = name;
	this.tainted = tainted;
        this.line = line;
        this.fileSymbol = file;
    }
    public Symbol(String name, int line, Boolean alfanumeric, String file) {
	this.name = name;
        this.line = line;
        this.alfanumeric = alfanumeric;
        this.fileSymbol = file;
    }

    public Symbol(String name, int tainted, int line, Boolean alfanumeric, String file) {
	this.name = name;
	this.tainted = tainted;
        this.line = line;
        this.alfanumeric = alfanumeric;
        this.fileSymbol = file;
    }


    // *** METHODS

    // Get the name of the symbol
    public String getName() {
	return name;
    }

    // Get the tainted value of the symbol
    public int getTainted() {
	return tainted;
    }

    // Get the number code line of the symbol
    public int getCodeLine() {
	return line;
    }

    // Get the alfanumeric value of the symbol
    public Boolean getAlfanumeric() {
	return alfanumeric;
    }

    // Get the Scope of the Symbol
    public Scope getScope() {
	return scope;
    }

    // Get rootScope of Symbol
    public Scope getRootScope() {
	return rootScope;
    }

    // Get Symbol
    public Symbol getSymbol() {
	return this;
    }

    // give the file that the symbol pertence
    public String getFileSymbol() {
        return fileSymbol;
    }

    // Tell if the symcol is a vaiable or not (callSymbol ou other)
    public Boolean getIsVariableSymbol() {
        return isVariableSymbol;
    }
    
    // Tell if the symbol is represents a mysql secure function
    public Boolean getIsSecureFunction() {
        return isSecureFunction;
    }
    
    // Tell if the symbol is a call function
    public Boolean getIsFunction() {
        return isFunction;
    }

    // Tell if the symbol is a User function
    public Boolean getIsUserFunction() {
        return isUserFunction;
    }
    
    // Tell if the symbol is a parameter of a User function or method class
    public Boolean getIsParamUserFunction() {
        return isParameterUserFunction;
    }
    
    // Tell if the symbol represents a mysql sqli function
    public Boolean getIsTaintedFunction() {
        return isTaintedFunction;
    }

    // Tell if the symbol is detected as vulnerable
    public Boolean getIsVulDetected() {
        return isVulDetected;
    }    
    
    // Tell if the symbol represents a instance of a class
    public Boolean getIsInstance() {
        return isInstance;
    }   

    // Tell if the symbol is a clone of a instance class
    public Boolean getIsClone() {
        return isClone;
    }

    // Tell if the symbol is a call of method class in static way
    public Boolean getIsStaticMember() {
        return isStaticMember;
    }

    // Tell if the symbol represents a class instruction
    public Boolean getIsClassInstruction() {
        return isClassInstruction;
    }

    // Tell if the symbol is a call class method
    public Boolean getIsClassMethod() {
        return isClassMethod;
    }

    // Set the tainted or untainted value
    public void setTainted(int t) {
	tainted = t;
    }

    // Set the name of the symbol
    public void setName(String nome) {
	name = nome;
    }

    // Set the code line of the symbol
    public void setCodeLine(int l) {
	line = l;
    }

    // Set the scope of the symbol
    public void setScope(Scope scp) {
	scope = scp;
    }

    // Set the rootScope of the symbol
    public void setRootScope(Scope scp) {
	rootScope = scp;
    }

    // set the file of the symbol pertence
    public void setFileSymbol(String file) {
        this.fileSymbol = file;
    }

    // set true if the symbol is a variableSymbol
    public void setIsVariableSymbol(Boolean a) {
        isVariableSymbol = a;
    }

    // set true if the symbol is a alfanumeric
    public void setAlfanumeric(Boolean a) {
        alfanumeric = a;
        this.setNameMultiline();
    }
    
    // set true if the symbol represents a mysql secure function
    public void setIsSecureFunction(Boolean a) {
        isSecureFunction = a;
    }

    // set true if the symbol is a call function
    public void setIsFunction(Boolean a) {
        isFunction = a;
    }
 
    // set true if the symbol is a user function
    public void setIsUserFunction(Boolean a) {
        isUserFunction = a;
    }

    // set true if the symbol is a parameter of a User function or method class
    public void setIsParamUserFunction(Boolean a) {
        isParameterUserFunction = a;
    }
    
    // set true if the symbol represents a mysql sqli function
    public void setIsTaintedFunction(Boolean a) {
        isTaintedFunction = a;
    }

    // set true when a vul is detected. Just sqli functions have this attribute true
    public void setIsVulDetected(Boolean a) {
        isVulDetected = a;
    }    
    
    // set true if the symbol represents a instance class
    public void setIsInstance(Boolean a) {
        isInstance = a;
    }

    // set true if the symbol is a clone of a instance class
    public void setIsClone(Boolean a) {
        isClone = a;
    }

    // set true if the symbol is a call of method class in static way
    public void setIsStaticMember(Boolean a) {
        isStaticMember = a;
    }

    // set true if the symbol represents a class instruction
    public void setIsClassInstruction(Boolean a) {
        isClassInstruction = a;
    }

    // set true if the symbol is a call class method
    public void setIsClassMethod(Boolean a) {
        isClassMethod = a;
    }

    // set Symbol name if it is composed by n lines
    public void setNameMultiline() {
        if (this.name.contains("\n")){
            String s[] = this.name.split("\n");
            String ss = s[0].trim();
            
            for (int i = 1; i < s.length; i++) {
                ss += " " + s[i].trim();
            }
            this.setName(ss);
        }
    }    
    

    // Print the name and tainted of the symbol
    @Override
    public String toString() {
	return '<'+ line + ":" + getName()+":" +tainted+'>' ;
    }

     @Override
     public Object clone() throws CloneNotSupportedException {
    	return super.clone();
    }
} public class MethodTable implements Scope{
    String name;
    List<MethodSymbol> methods;
    

    // *** CONSTRUCTORS
    public MethodTable(String name) {
        this.name = name;
        //symbols = new LinkedHashMap<String, Symbol>();
        methods = new ArrayList<MethodSymbol>();
    }


    // *** METHODS

    // Satisfy Scope interface
    public String getScopeName() {
        return name;
    }

    // am I nested in another?
    public Scope getEnclosingScope() {
    	return null;
    }

    /*
     * Give the List that contain the methods (functions defined by user) of the file
     */
    public List getMembers() {       
        return methods;
    }
    
    public List getMembersList() {
        return null;
    }

    /*
     * Give the root Symbol of the scope. In another words, give the symbol
     * that create a new scope.
     * Here, in main table of symbols, don't exist root symbol.
     */
    public Symbol getScopeSymbol() {
    	return null;
    }

    /*
     * Insert a root symbol (new scope) in main Map.
     */
    public void define(MethodSymbol meth) {
        methods.add(meth);
    }
    
        /*
     * Insert a root symbol (new scope) in main Map.
     */
    //public void define(Symbol sym, Scope scp, Boolean IsVariableSymbol) {
    public void define(MethodSymbol meth, Scope scp, Boolean IsVariableSymbol) {        
        methods.add(meth);
        meth.setRootScope(scp);
        meth.setScope(this);
        meth.setIsVariableSymbol(IsVariableSymbol);
    }


    /*
     * Not relevant here!
     */
    //public Boolean resolve(String name, TaintedTable mts, UntaintedTable mus) {
    public void resolveSymbol(Scope scp, Symbol sy, TaintedTable mts, UntaintedTable mus, String file){
    	//return symbols.get(name);
    //    return true;
    }


    public Boolean resolve(Symbol symb, TaintedTable mts, UntaintedTable mus) {
    	//return symbols.get(name);
        return true;
    }



    /*
     * Print the elements of the main Map scope.
     */
    public void print(Scope scp){
        Symbol aux1 = null;
        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();
                //System.out.println("Name: "+aux1.getName()+"\t\tline: "+aux1.getCodeLine()+"\t\ttainted: "
                //                +aux1.getTainted()+"\t\tScope: "+aux1.getScope().getScopeName()+"\n");
                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");
         }
    }

    @Override
    public String toString() {
    	return getScopeName()+":"+methods;
    }

    public void resolveSymbolIncludeSQLI(Scope scp, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map varsDB, Map mftt, Map MainLinesToCorrect) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String resolveVarInclude(Scope scp, SymbolTable st) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void define(Symbol sym, Scope scp, Boolean IsVariableSymbol) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void resolveSymbolFunctionSQLI(MethodSymbol mt, Scope rootScope, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map varsDB, Map mftt, Map MainLinesToCorrect) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Boolean verifyNumberVarList(int num_var){
        throw new UnsupportedOperationException("Not supported yet.");    
    }
    
    public void populateList(Scope scp_left, Scope scp_right, int num_var, TaintedTable mts, UntaintedTable mus, String filename){
        throw new UnsupportedOperationException("Not supported yet.");    
    }    
    
    public String buildCorrectSQL(String connDB, String nameDB, int lineMysqliBindParam, List UserInput, TaintedTable mts_princ, SymbolTable st, Map MainLinesToCorrect) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Boolean buildCorrectCodeInj(String fileInc, List UserInput, TaintedTable mts_princ, SymbolTable st, Map MainLinesToCorrect){
            throw new UnsupportedOperationException("Not supported yet.");
    }

    public void resolveSymbolClass(TaintedTable mts, UntaintedTable mus, String filename) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void printtt(String string, Scope cp){
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void resolveSymbolParam(TaintedTable mts, UntaintedTable mus, String filename) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    public void resolveParam(Symbol symb, TaintedTable mts, UntaintedTable mus) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

} public class MethodSymbol extends ScopedSymbol implements Cloneable{
    Boolean haveSubFunctions;
    String Progenitorfunction = "";
    Map <String, ArgFunctionSymbol> argsFunction;
    Map<String, Symbol> globalVars;
    List<Symbol> symbols;
    
    
    // ****** CONSTRUCTORS ***********
     public MethodSymbol(String function_name, int line, int tainted, Scope parent, String filename) {
        //this.functionName = fname;
        super (function_name, line, tainted, parent, filename);
	haveSubFunctions = false;
        argsFunction = new HashMap <String, ArgFunctionSymbol>();
        globalVars = new HashMap<String, Symbol>();
        //staticVars = new HashMap<String, Object>();
        symbols = new ArrayList<Symbol>(); //instructions of the function, except global instruction
    }
    
    
    // *** METHODS ********
    public String getFunctionName() {
        return this.getName();
    }

    public Boolean getHaveSubFunctions() {
        return haveSubFunctions;
    }
    
    public String getProgenitorFunction() {
        return this.Progenitorfunction;
    }
    
    public Map getArgsFunction() {
        return argsFunction;
    }
    
   
    public Map getGlobalVarsOfFunction() {
        return globalVars;
    }
    
    
    public void setFunctionName(String name) {
        this.setName(name);
    }    
    
    public void setHaveSubFunctions() {
        this.haveSubFunctions = true;
    }
    
    public void setProgenitorFunction(String p) {
        this.Progenitorfunction = p;
    }
    
    public void setArgFunction(String argName, ArgFunctionSymbol arg) {
        argsFunction.put(argName, arg);
    }
    
    public void setGlobalVarFunction(String varName, Symbol gvar) {
        globalVars.put(varName, gvar);

    }

    public MethodSymbol copyMethodSymbol(MethodSymbol meth_sym, String function_name, int line, Scope parent, String filename) {
        MethodSymbol mt = new MethodSymbol(function_name, line, 0, parent, filename);
        Symbol sym;

        //copia o map de argumentos da funcao
        ArgFunctionSymbol arg;
        for(Iterator <ArgFunctionSymbol> it = meth_sym.getArgsFunction().values().iterator(); it.hasNext();){
            arg = it.next();
            try {
                mt.argsFunction.put(arg.getParamName(), (ArgFunctionSymbol) arg.clone());
            } catch (CloneNotSupportedException ex) {
                Logger.getLogger(MethodSymbol.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
          
        //copia o map das vars globais da funcao
        for(Iterator <Symbol> it = meth_sym.getGlobalVarsOfFunction().values().iterator(); it.hasNext();){
            sym = it.next();
                try {
                    mt.getGlobalVarsOfFunction().put(sym.getName(), (Symbol) sym.clone());
                } catch (CloneNotSupportedException ex) {
                    Logger.getLogger(MethodSymbol.class.getName()).log(Level.SEVERE, null, ex);
                }
	 }
 
                
        //copia a lista de instrucoes da funcao
        Scope scp, scpRoot=null;
        CallSymbol curScope;
        Symbol sy;
        for(Iterator <Symbol> it = meth_sym.getMembers().iterator(); it.hasNext();){
            sy = it.next();
            if (sy.getIsVariableSymbol() == false){
                scp = (Scope) sy; 
                sym = scp.getScopeSymbol();
                curScope = new CallSymbol (sym.getName(), sym.getCodeLine(), null, sym.getTainted(), sym.getFileSymbol());
                curScope.setRootScope(curScope);
                curScope.setScope(curScope);
                curScope.setIsVariableSymbol(false);
                curScope.getScopeSymbol().setIsInstance(sym.getIsInstance());
                curScope.getScopeSymbol().setIsClone(sym.getIsClone());
                curScope.getScopeSymbol().setIsStaticMember(sym.getIsStaticMember());
                curScope.getScopeSymbol().setIsClassInstruction(sym.getIsClassInstruction());
                
                curScope.getScopeSymbol().setIsFunction(sym.getIsFunction());
                curScope.getScopeSymbol().setIsSecureFunction(sym.getIsSecureFunction());
                curScope.getScopeSymbol().setIsTaintedFunction(sym.getIsTaintedFunction());
                curScope.getScopeSymbol().setAlfanumeric(sym.getAlfanumeric());
                curScope.getScopeSymbol().setIsUserFunction(sym.getIsUserFunction());
                curScope.getScopeSymbol().setIsClassMethod(sym.getIsClassMethod());                
                
                copyScope(scp, curScope);
                mt.getMembers().add(curScope);
            }
         }
        
        return mt;
    }

    public void copyScope(Scope cs, Scope csClone){
        Symbol aux1, aux2;
        Scope s, s1 = null;
        CallSymbol curScope1;
        if (!cs.getMembers().isEmpty()){
            for(Iterator <Symbol> it = cs.getMembers().iterator(); it.hasNext();){
                aux1 = it.next();
                if ( aux1.getRootScope() != null ) { // is a root of a new scope?
                        s = aux1.getRootScope();
                        //aux2 = s.getScopeSymbol();
                        try {
                            s1 = (Scope) cs.getScopeSymbol().clone();
                        } catch (CloneNotSupportedException ex) {
                            Logger.getLogger(MethodSymbol.class.getName()).log(Level.SEVERE, null, ex);
                        }                        
                        curScope1 = new CallSymbol (aux1.getName(), aux1.getCodeLine(), s1, aux1.getTainted(), aux1.getFileSymbol());
                        curScope1.getScopeSymbol().setIsFunction(aux1.getIsFunction());
                        curScope1.getScopeSymbol().setIsSecureFunction(aux1.getIsSecureFunction());
                        curScope1.getScopeSymbol().setIsTaintedFunction(aux1.getIsTaintedFunction());
                        curScope1.getScopeSymbol().setAlfanumeric(aux1.getAlfanumeric());
                        curScope1.getScopeSymbol().setIsUserFunction(aux1.getIsUserFunction());
                        curScope1.getScopeSymbol().setIsInstance(aux1.getIsInstance());
                        curScope1.getScopeSymbol().setIsClone(aux1.getIsClone());
                        curScope1.getScopeSymbol().setIsStaticMember(aux1.getIsStaticMember());
                        curScope1.getScopeSymbol().setIsClassInstruction(aux1.getIsClassInstruction());
                        curScope1.getScopeSymbol().setIsClassMethod(aux1.getIsClassMethod());

                        csClone.define(curScope1, curScope1, false);
                        copyScope(s, curScope1);
                }
                else{
                    VariableSymbol vs = new VariableSymbol(aux1.getName(), aux1.getTainted(), aux1.getCodeLine(), aux1.getAlfanumeric(), aux1.getFileSymbol());
                    csClone.define(vs, null, true);

                }
                    
            }
        }       
    }


    public void cleanAll(){
            haveSubFunctions = false;
            Progenitorfunction = "";

            Collection <ArgFunctionSymbol> c = argsFunction.values();
            c.removeAll(c);
            argsFunction.clear();

            Collection <Symbol> c1 = globalVars.values();
            c1.removeAll(c1);
            globalVars.clear();

            Collection <Symbol> c2 = symbols;
            c2.removeAll(c2);
            symbols.clear();
    }
    
    // give the members (instructions) of the function
    public List<Symbol> getMembers() {
        return symbols;
    }

    public void printMethodSymbol() {
        System.out.println("FUNCTION: "+this.getFunctionName()+"\tTAINTED: "+this.getTainted());
        System.out.println("\tHave SubFunctions: "+ this.getHaveSubFunctions());
        System.out.println("\tFunction Progenitor: "+ this.getProgenitorFunction());
        
        System.out.println("\tPARAMETERS");
        Iterator <ArgFunctionSymbol> it;
        ArgFunctionSymbol afs;
        for(it = this.getArgsFunction().values().iterator(); it.hasNext();){
            afs = it.next();
            System.out.println("\t\tName: "+afs.getParamName()+"\tType: "+afs.getType()+"\tPosition: "+afs.getPositionParam()+
                                "\tTainted: "+afs.getTaintedValueCallFunctionArg()+"\tArgCallFunction: "+afs.getCallFunctionArg());
        }
        
        System.out.println("\tGLOBALS");
        Iterator <Symbol> it1;
        Symbol sym;
        for(it1 = this.getGlobalVarsOfFunction().values().iterator(); it1.hasNext();){
            sym = it1.next();
            System.out.println("\t\tName: "+sym.getName()+"\tTainted: "+sym.getTainted());
        }
        
        System.out.println("\tINSTRUCTIONS");
        Scope sc;
        for(it1 = this.getMembers().iterator(); it1.hasNext();){
            sc = (Scope) it1.next();
            System.out.println("ScopeName: "+sc.getScopeName()+"\tTainted: "+sc.getScopeSymbol().getTainted()
                                +"\tRootScope: "+sc.getScopeSymbol().getRootScope().getScopeName()
                                +"\tTaintedRootScope: "+sc.getScopeSymbol().getRootScope().getScopeSymbol().getTainted());
            sc.print(sc);
        }        
    }    
    
    public void print(Scope scp) {

    }

} public interface Scope {
    public String getScopeName();		// do I have a name?
    public Scope getEnclosingScope();		// am I nested in another?
    //public Map getMembers();                    // list of my symbols
    public List getMembers();                    // list of my symbols
    public Symbol getScopeSymbol();             // get the symbol that create the scope (the root symbol)
    public void define(Symbol sym, Scope scp, Boolean IsVariableSymbol);	// define sym in this scope
    //public Boolean resolve(String name, TaintedTable mts, UntaintedTable mus);	// look up name in scope
    public Boolean resolve(Symbol symb, TaintedTable mts, UntaintedTable mus);	// look up name in scope
    public void resolveSymbol(Scope scp, Symbol sy, TaintedTable mts, UntaintedTable mus, String file); // resolve symbol in scope
    //public void resolveSymbolInclude(Scope scp1, TaintedTable mts, UntaintedTable mus); // resolve symbols in include/function file
    public void resolveSymbolClass(TaintedTable mts, UntaintedTable mus, String filename);
    //public void resolveSymbolIncludeSQLI(Scope scp, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map varsDB, Map mftt, Map MainLinesToCorrect);
    public String resolveVarInclude(Scope scp, SymbolTable st); // resolve name of include/require file
    public void print(Scope scp);
    //public void resolveSymbolFunctionSQLI(MethodSymbol mt, Scope rootScope, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map varsDB, Map mftt, Map MainLinesToCorrect);

    public Boolean verifyNumberVarList(int num_var);
    public void populateList(Scope scp_left, Scope scp_right, int num_var, TaintedTable mts, UntaintedTable mus, String filename);
    
    public String buildCorrectSQL(String connDB, String nameDB, int lineMysqliBindParam, List UserInput, TaintedTable mts_princ, SymbolTable st, Map MainLinesToCorrect);

    public Boolean buildCorrectCodeInj(String fileInc, List UserInput, TaintedTable mts_princ, SymbolTable st, Map MainLinesToCorrect);

    public void printtt(String string, Scope cp);
    
} public class OutputAnalysisSqli {

    public static void outputAnalysisWithCorrection (String type_analyse, String filename, LinesToCorrect ltc, int num_file) throws IOException{
        FileWriter out_FileOfPaths;
        File dir = null;
        BufferedWriter bufferWritter = null;
        Date date = new Date(System.currentTimeMillis());
        int i = GlobalDataSqli.MainLinesToCorrect.size();

        if (type_analyse.equals("project") == true){
            dir = new File(System.getProperty("base.dir") + File.separator + "NewFiles");
            
            // Se ja houve analises anteriores apaga dir
            if (GlobalDataApp.numAnalysis == 0 && dir.exists() == true && num_file == i){
                ManageFiles r = new ManageFiles(dir.toString());
                r.deleteDir(dir);
                GlobalDataApp.numAnalysis++;
            }            
            
            //Criar directorio para colocar fichs corrigidos
            if (dir.exists() == false)
                dir.mkdir();
            // cria ficheiro que contem a path dos ficheiros que serao corrigidos
            File fileOfPaths = new File(dir+ File.separator +"PathNewFiles.txt");
            if (fileOfPaths.exists() == true)
                out_FileOfPaths = new FileWriter(fileOfPaths, true);
            else
                out_FileOfPaths = new FileWriter(fileOfPaths);
            bufferWritter = new BufferedWriter(out_FileOfPaths);
        }

        // Escrever Ficheiro corrigido       
            String file = ltc.getNameFile();
            ManageFiles relativeFile = new ManageFiles(file);

            if (type_analyse.equals("single_file") == true || type_analyse.equals("files") == true){
                File baseDir = relativeFile.getBaseDir();
                dir = new File(baseDir + File.separator + "NewFiles");
                
                // Se ja houve analises anteriores apaga dir
                if (GlobalDataApp.numAnalysis == 0 && dir.exists() == true && num_file == i){
                    ManageFiles r = new ManageFiles(dir.toString());
                    r.deleteDir(dir);
                    GlobalDataApp.numAnalysis++;
                }
                
                //Criar directorio para colocar fichs corrigidos
                File fileOfPaths = new File(dir+ File.separator +"PathNewFiles.txt");
                if (dir.exists() == false)
                    dir.mkdir();

                //if (fileOfPaths.exists() == true && i>=1 )
                if (fileOfPaths.exists() == true)
                    out_FileOfPaths = new FileWriter(fileOfPaths, true);
                else
                    out_FileOfPaths = new FileWriter(fileOfPaths);

    	        bufferWritter = new BufferedWriter(out_FileOfPaths);
            }


            if (ltc.getMapLinesToCorrect().isEmpty() == false){
                File ff = new File(dir+ File.separator + file);
                File in = null, out = null, temp = null, inn = null;                
                if (ff.exists() == false){          
                    bufferWritter.write(date + " " + file + "\n");
                    in = new File(file);
                    try{
                        int ind = file.lastIndexOf(File.separator);
                        String s = file.substring(0, ind);
                        File d = new File(dir + File.separator + s);
                        d.mkdirs();   
                        out = new File(ff.toString());
                    } catch (Exception e) {}
                }
                else{
                    inn = new File(ff.toString());
                    temp = new File(ff.toString() + "temp");
                    inn.renameTo(temp);
                    in = new File(temp.toString());
                    out = new File(dir+ File.separator + file);
                }

                Scanner fscanner = new Scanner(in);
                FileWriter outFinalFile = new FileWriter(out);

                Map sortedMap = new TreeMap(ltc.getMapLinesToCorrect());
                Set a = sortedMap.keySet();
                String codeLine;
                int line = 0;
                for (Object key : a) {
                    for (int j = line+1; j < (Integer)key; j++){
                        codeLine = fscanner.nextLine();
                        outFinalFile.write(codeLine+"\n");
                    }
                    codeLine = fscanner.nextLine();
                    outFinalFile.write(sortedMap.get(key).toString()+"\n");
                    line = (Integer)key;
                }

                while (fscanner.hasNextLine()){
                    codeLine = fscanner.nextLine();
                    outFinalFile.write(codeLine+"\n");
                }
                fscanner.close();
                outFinalFile.close();
                
                if (inn != null && inn.exists())
                    inn.delete();

                if (type_analyse.equals("single_file") == true || type_analyse.equals("files") == true)
                    bufferWritter.close();
            }
        //}
        if (type_analyse.equals("project") == true)
            bufferWritter.close();
    }


    public static void outputAnalysis(String type_analyse, FileWriter outFile, String diff_date_sqli, List files) throws IOException{
        int vuu = GlobalDataSqli.getNumVul(), fpp = GlobalDataSqli.getNumFP();
        /*
        Integer j;
        for(Iterator <Integer> it = GlobalDataSqli.MainNumVul.values().iterator(); it.hasNext(); ){
            j = it.next();
            vuu += j;
        }
        
        for(Iterator <Integer> it = GlobalDataSqli.MainNumFP.values().iterator(); it.hasNext(); ){
            j = it.next();
            fpp += j;
        } 
         */

        String setPlainText = "";
        String setBoldText = "";
        if (GlobalDataApp.isWindows.booleanValue() == false){
            setPlainText = "\033[0;0m";
            setBoldText = "\033[0;1m";
        }
        
        System.out.println(setBoldText +"\n\n  + Type of Analysis: SQLI");
        System.out.println("     > Summary:" + setPlainText);
        
        if(GlobalDataApp.args_flags[4] == 1){
            outFile.write("\n\n  + Type of Analysis: SQLI\n");
            outFile.write("     > Summary:\n");
        }
        
        if (vuu+fpp > 0){
            System.out.println("        - Time of analysis: " + diff_date_sqli);
            System.out.println("        - Number of vulnerabilities detected: " + setBoldText + (vuu+fpp) + setPlainText);
            System.out.println("           - Real vulnerabilities: " + setBoldText + vuu + setPlainText);
            System.out.println("           - False positives: " + setBoldText + fpp + setPlainText);
            System.out.println("        - Number of vulnerable files: " +
                    setBoldText + GlobalDataSqli.MainListVulners.size() + setPlainText);
            System.out.println("        - List of vulnerable files:");
            
            if(GlobalDataApp.args_flags[4] == 1){
                outFile.write("        - Time of analysis: " + diff_date_sqli+"\n");
                outFile.write("        - Number of vulnerabilities detected: " + (vuu+fpp)+"\n");
                outFile.write("           - Real vulnerabilities: " + vuu+"\n");
                outFile.write("           - False positives: " + fpp+"\n");
                outFile.write("        - Number of vulnerable files: " + GlobalDataSqli.MainListVulners.size()+"\n");
                outFile.write("        - List of vulnerable files:\n");
            }

            for(Iterator <ListVulners> it = GlobalDataSqli.MainListVulners.values().iterator(); it.hasNext(); ){
                ListVulners lv = it.next();
                System.out.println("\t    " + lv.getFilename());
                
                if(GlobalDataApp.args_flags[4] == 1){
                    outFile.write("\t    " + lv.getFilename()+"\n");
                }
            }

            if (GlobalDataApp.args_flags[5] == 0){
                // code needed for keyboard input
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                String temp;
                System.out.println("\n\nPress enter to view vulnerabilities...");
                temp = br.readLine();
            }
        }
        else{
            System.out.println("        - Time of analysis: " + diff_date_sqli);
            System.out.println("        - Number of vulnerabilities detected: "  + setBoldText +"none" + setPlainText);
            if(GlobalDataApp.args_flags[4] == 1){
                outFile.write("        - Time of analysis: " + diff_date_sqli +"\n");
                outFile.write("        - Number of vulnerabilities detected: none\n");
            }
          
            return;            
        }      
        
        
        ListVulners lv = null;
        for (Iterator <ListVulners> it = GlobalDataSqli.MainListVulners.values().iterator(); it.hasNext();){
            lv = it.next();
            if (GlobalDataApp.args_flags[5] == 0){
                String file = lv.getFilename();               
                ManageFiles ff = new ManageFiles (file);
                System.out.println(setBoldText + "\n> > > >  File: " + setPlainText + file + 
                        setBoldText + " < < < <" + setPlainText);
                System.out.println(setBoldText + "     > Information:" + setPlainText);
                System.out.println("        - Number of Lines of Code: " + ff.getNumberLinesFile());            

                if(GlobalDataApp.args_flags[4] == 1){
                    outFile.write("\n> > > >  File: " + file + " < < < <\n");
                    outFile.write("     > Information:\n");
                    outFile.write("        - Number of Lines of Code: " + ff.getNumberLinesFile()+"\n");
                }

                // is a include file?
                if (GlobalDataSqli.MainIncludeFilesTable.containsKey(file) == true){
                    System.out.println("        - It is a include file: yes");

                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - It is a include file: yes\n");
                    }
                }
                else{
                    System.out.println("        - It is a include file: no");

                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - It is a include file: no\n");
                    }
                }

                // list of included files from "regular" or include file
                SymbolTable st = null;
                if (GlobalDataSqli.MainSymbolTable.containsKey(file) == true)
                    st = GlobalDataSqli.MainSymbolTable.get(file);
                else
                    st = GlobalDataSqli.MainIncludeFilesTable.get(file);

                if(st.getIncludeFiles().isEmpty() == false){
                    System.out.println("        - Included files:");
                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Included files:\n");
                    }

                    for (int i = 0; i < st.getIncludeFiles().size(); i++){
                        System.out.println("\t    "+st.getIncludeFiles().get(i));

                        if(GlobalDataApp.args_flags[4] == 1){
                            outFile.write("\t    "+st.getIncludeFiles().get(i)+"\n");
                        }
                    }
                }
                else{
                    System.out.println("        - Included files: none");

                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Included files: none\n");
                    }
                }


                // list of defined user functioms
                if (GlobalDataSqli.MainFunctionsTable.containsKey(file) == true){
                    MethodTable mt = GlobalDataSqli.MainFunctionsTable.get(file);
                    System.out.println("        - Defined user functions:");
                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Defined user functions:\n");
                    }

                    for (Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext(); ){    
                        MethodSymbol ms = it1.next();
                        System.out.println("\t  "+ms.getFunctionName());
                        if(GlobalDataApp.args_flags[4] == 1){
                            outFile.write("\t  "+ms.getFunctionName()+"\n");
                        }
                    }
                }
                else{
                    System.out.println("        - Defined user function: none");
                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Defined user function: none\n");
                    }
                }

                // list of vulnerabilities of file
                VulnerSQLI v;
                int vuu_f = lv.getListOfVulners().size();
                int fpp_f = 0;
                for (Iterator <VulnerSQLI> it1 = lv.getListOfVulners().iterator(); it1.hasNext();){
                    v = it1.next();
                    if (v.IsFP() == 1)
                        fpp_f++;
                }
                vuu_f -= fpp_f;
                
                System.out.println("        - Number of Vulnerabilities detected: " +
                        setBoldText + lv.getListOfVulners().size() + setPlainText); 
                System.out.println("           - Real Vulnerabilities: " +
                        setBoldText + vuu_f + setPlainText);
                System.out.println("           - False positives: " +
                        setBoldText + fpp_f + setPlainText);
                if(GlobalDataApp.args_flags[4] == 1){
                    outFile.write("        - Number of Vulnerabilities detected: "+lv.getListOfVulners().size()+"\n");
                    outFile.write("           - Real Vulnerabilities: "+vuu_f+"\n");
                    outFile.write("           - False positives: "+fpp_f+"\n");
                }

                analysisOfFile(lv, outFile, file.toString());
                if (it.hasNext() && GlobalDataApp.args_flags[0] == 1){
                    // code needed for keyboard input
                    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                    String temp;
                    System.out.println("\n\nPress enter to view vulnerabilities of next file...");
                    temp = br.readLine();
                }
            }           
        }
        
        // CORRECAO no file
        if(GlobalDataApp.args_flags[0] == 0 && vuu > 0){
            // code needed for keyboard input
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String temp;

            System.out.println("\n\nPress enter to proceed automatic correction...");
            temp = br.readLine();
            
            try{
            LinesToCorrect ltc;
            int i = GlobalDataSqli.MainLinesToCorrect.size();
            for (Iterator <LinesToCorrect> it = GlobalDataSqli.MainLinesToCorrect.values().iterator(); it.hasNext();){
                ltc = it.next();
                OutputAnalysisSqli.outputAnalysisWithCorrection(type_analyse, ltc.getNameFile(), ltc, i);
                i--;
            }
            } catch (Exception e){}
            
            System.out.println("\n\nAutomatic correction complete !!!");
            if(GlobalDataApp.args_flags[4] == 1){
                outFile.write("\n\nAutomatic correction complete !!!\n");
            }
        }

    }

    private static void analysisOfFile(ListVulners lv, FileWriter outFile, String filename) throws IOException{
        VulnerSQLI v;
        String cl, correctedCode = "", aux = "";
        Iterator <VulnerSQLI> it;
        int i=0;
        LinesToCorrect ltc;
        Object key;
        
        String setPlainText = "";
        String setBoldText = "";
        if (GlobalDataApp.isWindows.booleanValue() == false){
            setPlainText = "\033[0;0m";
            setBoldText = "\033[0;1m";
        }

        for (it = lv.getListOfVulners().iterator(); it.hasNext();){
            v = it.next();
            if (v.IsFP() == 0)
                System.out.println(setBoldText + "\n\t= = = =  Vulnerability n.: " + (i+1) + "  = = = =");
            else
                System.out.println(setBoldText + "\n\t= = = =  Vulnerability n.: " + (i+1) + "   >>> is a possible False Positive <<<  = = = =");
            System.out.println("\tVulnerable code:" + setPlainText);
            if(GlobalDataApp.args_flags[4] == 1){
                if (v.IsFP() == 0)
                    outFile.write("\n\t= = = =  Vulnerability n.: " + (i+1) + "  = = = =\n");
                else
                    outFile.write("\n\t= = = =  Vulnerability n.: " + (i+1) + "   >>> is a possible False Positive <<<  = = = =\n");
                outFile.write("\tVulnerable code:\n");
            }
            i++;

          try{
           
            // escrever vulnerabilidade e sua correccao no ecra
            String f;
            correctedCode = "";
            for (int l = v.getLinesOfVulner().size() - 1; l >= 0; l--){
                f = "";
                if (v.getFilesOfVulner().get(l).equals(lv.getFilename()) == false)
                    f = (String) v.getFilesOfVulner().get(l);

                ManageFiles fff = new ManageFiles ((String) v.getFilesOfVulner().get(l));
                cl = fff.getLineOfCode((Integer) v.getLinesOfVulner().get(l));
                System.out.println("\t" + v.getLinesOfVulner().get(l) + ": "+ cl);
                if(GlobalDataApp.args_flags[4] == 1){
                    outFile.write("\t" + v.getLinesOfVulner().get(l) + ": "+ cl+"\n");
                }
                if (f.equals("") == false){
                    System.out.println("\t    (" + f + ")");
                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("\t    (" + f + ")\n");
                    }
                }

                if (v.IsFP() == 0){
                    // escrita do corrected code no ecra
                    ltc = GlobalDataSqli.MainLinesToCorrect.get(v.getFileOfLineToSanitize());
                    Map sortedMap = new TreeMap(ltc.getMapLinesToCorrect());                
                    if (ltc.getMapLinesToCorrect().containsKey(v.getLinesOfVulner().get(l)) == true){
                        key = v.getLinesOfVulner().get(l);
                        aux =  "\t" + (Integer)key + ": " + sortedMap.get(key).toString()+"\n";
                    }
                    else
                        aux =  "\t" + v.getLinesOfVulner().get(l) + ": "+ cl + "\n";
                    correctedCode = correctedCode + aux;
                }
            }
        }catch (Exception e){
            aux = "\tSome unexpected error in analysis happened. Sorry :-(";
            correctedCode = correctedCode + aux;
        }
        
        if (v.IsFP() == 0){
            System.out.println(setBoldText + "\n\tCorrected code:" + setPlainText);
            System.out.println(correctedCode);
            if(GlobalDataApp.args_flags[4] == 1)
                outFile.write("\n\tCorrected code:\n" + correctedCode);
        }
        else{
            String justifyFP = v.getJustificationOfFP();
            System.out.println(setBoldText + "\n\tFalse Positive justification:" + setPlainText);
            System.out.println(justifyFP);
            if(GlobalDataApp.args_flags[4] == 1)
                outFile.write("\n\tFalse Positive justification:\n" + justifyFP); 
        }
    }
    }
} public class FuncAndIncSQLI extends ScopedSymbol{

    // *** CONSTRUCTORS
    public FuncAndIncSQLI(Scope scp) {
        super(scp.getScopeSymbol().getName(), scp.getScopeSymbol().getCodeLine(), scp.getScopeSymbol().getTainted(), scp.getEnclosingScope(), scp.getScopeSymbol().getFileSymbol());
    }

    
    public void resolveSymbolClassSqli(MethodSymbol ms, Scope scp, TaintedTable mts, UntaintedTable mus, String filename, MethodSymbolCall mtsc, Instance inst, Map mct, Boolean ftime, Scope cs_att, Scope cs_acc, String typeMeth, Boolean isClassInstruction, Map varsDB) throws IOException{
    if (scp.getScopeSymbol().getIsSecureFunction() == false){ 
    Scope csAtt_acc = cs_att;
    Scope csAtt_att = cs_acc;
    String s = scp.getScopeName();
    Instance ret = null;
    Boolean exit_for = false;
    
    
    if (inst != null){   
    SymbolTable t = inst.getInstanceAttributes();
     
    //pegar no atributo do objecto numa atribuicao ou acesso
    if (t.containsSymbol(s) || (scp.getEnclosingScope() != null && scp.getEnclosingScope().getScopeName().equals("this") && t.containsSymbol(s))){
       //pegar no atributo do objecto numa atribuicao ou acesso
       if (ftime == true){
           csAtt_att = (Scope) t.getSymbolOfListSymbols(s);
           try{
               csAtt_att.getMembers().clear();
               for(int i=0; i< scp.getMembers().size(); i++)
                    csAtt_att.getMembers().add(scp.getMembers().get(i));
           } catch (Exception e) {}
           ftime = false;

           if (scp.getEnclosingScope() != null && scp.getEnclosingScope().getScopeName().equals("this")){
                Symbol sym_this = scp.getEnclosingScope().getScopeSymbol();
                scp.getScopeSymbol().setIsInstance(sym_this.getIsInstance());
                scp.getScopeSymbol().setIsClone(sym_this.getIsClone());
           }
       }
       else{
           csAtt_acc = (Scope) t.getSymbolOfListSymbols(s);
       }

    }
    }

    Iterator <Symbol> it;
    Symbol sym;
    for (it = scp.getMembers().iterator(); it.hasNext();){
        sym = it.next();
        if (isClassInstruction == true){
        int op = 0;

        // criacao de um objecto
        // do tipo $a = new A_class()
        if (scp.getScopeSymbol().getIsInstance() == true)
            op = 2;

        // atribuicao e' um clone
        // do tipo $a = clone $obj
        if (scp.getScopeSymbol().getIsClone() == true)
            op = 3;

        // staticMember
        // A::meth()
        if (scp.getScopeSymbol().getIsStaticMember() == true)
            op = 4;

        // chamada de um metodo
        if(scp.getScopeSymbol().getIsFunction() == true && scp.getScopeSymbol().getIsClassMethod() == true &&
           scp.getScopeSymbol().getIsSecureFunction()==false && scp.getScopeSymbol().getIsTaintedFunction()==false){
            if (ms != null)
                op = 5; // metodo dentro de um metodo
            else
                op = 1; //metodo normal
        }
            
        switch (op){           
            case 1:{ // chamada de um metodo normal
                ftime = false;
                
                // 1. obter instancia
                String instName = scp.getEnclosingScope().getScopeName();
                String fileInst = scp.getEnclosingScope().getScopeSymbol().getFileSymbol();
                InstanceTable instTable = GlobalDataSqli.MainInstancesTable.get(fileInst);
                SymbolTable st = GlobalDataSqli.MainSymbolTable.get(fileInst);
                String instName_aux = instName;
                Instance inst1 = null;
                if (st.getAliases().containsKey(instName_aux) == true)
                        instName_aux = st.getInstanceNameFromAliases(instName_aux, instTable);                
                
                if (instTable != null && instTable.containsInstance(instName_aux) == true)
                    inst1 = (Instance) instTable.getInstanceOfListInstances(instName_aux);

                // 2. obter classe
                String c_name = inst1.getInstanceClass();
                String cf_name = inst1.getFileOfClass();
                ClassTable ct = GlobalDataSqli.MainClassesTable.get(cf_name);
                ClassSymbol currentClass = ct.getClassOfListClasses(c_name);

                // * 3. procurar metodo
                MethodClass mc = currentClass.getMethodClass(scp.getScopeName(), "", mct);
                MethodSymbol mss_final = mc.getMeth();
                String mss_final_file = mc.getClassMeth().getFileClass();

                ret = null;
                ret = instanceMethod(mss_final, scp, filename, mss_final_file, mts, mus, inst1, null, mct, "", ret, varsDB, instTable, st);                

                if (ret != null && instTable.containsInstance(ret.getInstanceName()) == true){
                        Boolean a = true;
                        Scope enc_f = scp;
                        Scope enc_b;
                        while (a == true){
                                enc_b = enc_f.getEnclosingScope();
                                if (enc_b.getScopeName().equals(st.getScopeName()) == false)
                                        enc_f = enc_b;
                                else
                                        a = false;
                        }

                        Symbol sy = new Symbol(ret.getInstanceName(), ret.getTainted(), ret.getCreateLineInstance(), ret.getFileInstance());
                        sy.setIsClassInstruction(true);
                        st.getAliases().put(enc_f.getScopeName(), sy);
                        scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                        mts.removeDuplicates(sym);

                        if (cs_att != null){
                                cs_att.getScopeSymbol().setTainted(ret.getTainted());
                                inst1.updateTainted(cs_att, sym);
                        }
                }
                exit_for = true;
                return;
            }
            
            case 2:{ // criacao de um objecto
                ftime = false;
                // criacao de um objecto
                if (sym.getName().equals("mysqli") == true)
                    varsDB.put("connectionDB", s);
                else{
                    Instance inst1 = null;
                    InstanceTable instances_table = null;
                    if (ms == null){
                        String file_inst = sym.getFileSymbol();
                        instances_table = GlobalDataSqli.MainInstancesTable.get(file_inst);
                        Iterator <Instance> it1 = instances_table.getMembers().iterator();
                        for (; it1.hasNext();){
                            inst1 = it1.next();
                            if (inst1.getInstanceName().equals(s) && inst1.getCreateLineInstance() == sym.getCodeLine()){
                                break;
                            }
                        }
                    }
                    
                                        
                    /* 1. Procurar classe */
                    ClassTable class_table = null;
                    ClassSymbol currentClass = null;
                    //Symbol sy = null;
                    for (Iterator <ClassTable> it3 = GlobalDataSqli.MainClassesTable.values().iterator(); it3.hasNext();){
                        class_table = it3.next();

                        if (class_table.containsClass(sym.getName()) == true){
                            currentClass = (ClassSymbol) class_table.getClassOfListClasses(sym.getName());
                            break;
                        }
                    }

                    if (ms != null){
                        if (typeMeth.equals("constructor") == true)
                            instances_table = inst.getObjectsOfInstance();
                        else
                            instances_table = mtsc.getObjectsOfMethod();
                    }

                    if (currentClass.getExtendsClassName() != null && currentClass.getExtendsClassName().equals("mysqli") == true){
                        varsDB.put("connectionDB", s);
                        inst1 = new Instance(scp.getScopeName(), scp.getScopeSymbol().getCodeLine(), inst.getFileInstance(), sym.getName(), class_table.getScopeName(), currentClass, true);
                        instances_table.define(inst1);
                        return;
                    }
                    if (ms != null){
                        inst1 = new Instance(scp.getScopeName(), scp.getScopeSymbol().getCodeLine(), inst.getFileInstance(), sym.getName(), class_table.getScopeName(), currentClass, false);
                        instances_table.define(inst1);
                    }

                    /* 2. procurar metodo construtor*/
                    MethodClass mc = currentClass.getMethodClass(sym.getName(), "construct", mct);
                    MethodSymbol mss_final = mc.getMeth();
                    String mss_final_file = mc.getClassMeth().getFileClass();

                    /* Fazer a analise do construtor */
                    if (mss_final == null){ // a classe nao tem metodo construtor. logo fazer taint analise aos atributos
                        SymbolTable t1 = inst1.getInstanceAttributes();
                        TaintedTable tt1 = inst1.getMtsInstanceAttributes();
                        UntaintedTable ut1 = inst1.getMusInstanceAttributes();
                        Scope scp1;
                        for(Iterator <Symbol> it4 = t1.getMembers().iterator(); it4.hasNext();){
                             scp1 = (Scope) it4.next();
                             scp1.resolveSymbolClass(tt1, ut1, inst1.getFileOfClass());
                        }
                    }
                    else{
                        typeMeth = "constructor";
                        MethodSymbolSqli meth_sym = new MethodSymbolSqli(mss_final);
                        int valueFinal = meth_sym.analyseMethodSqli(mss_final,scp.getScopeSymbol().getCodeLine(), (Scope)sym, mts, mus, filename, mss_final_file, inst1, mct, typeMeth, null);
                        scp.getScopeSymbol().setTainted(valueFinal);
                        scp.resolveSymbol(scp, sym, mts, mus, scp.getScopeSymbol().getFileSymbol());

                        if (cs_att != null){
                            cs_att.getScopeSymbol().setTainted(valueFinal);
                            inst.updateTainted(cs_att, sym);
                        }
                    }
                    
                }
                return;
            }

            case 3:{ // atribuicao e' um clone
                ftime = false;

                // atribuicao e' um clone
                if (ms != null)
                    mtsc.getAliases().put(s, sym);
                
                scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                if (cs_att != null){
                    cs_att.getScopeSymbol().setTainted(scp.getScopeSymbol().getTainted());
                    inst.updateTainted(cs_att, sym);
                }
                return;
            }

            case 4:{ // staticMember
                ftime = false;

                // staticMember
                // obter classe
                String clas = "";
                String clas_file = "";
                if (s.equals("self") == true){
                    clas = inst.getInstanceClass();
                    clas_file = inst.getFileOfClass();
                }
                else{
                    if (s.equals("parent") == true){
                        clas = inst.getInstanceClass();
                        clas_file = inst.getFileOfClass();
                        ClassTable ct = GlobalDataSqli.MainClassesTable.get(clas_file);
                        ClassSymbol cls = (ClassSymbol) ct.getClassOfListClasses(clas);
                        clas = cls.getExtendsClassName();
                        clas_file = cls.getFileExtendsClass();
                    }
                    else{
                        // obter nome e file da class
                        for (Iterator <ClassTable> it1 = mct.values().iterator(); it1.hasNext();){
                            ClassTable class_table = it1.next();
                            if (class_table.containsClass(s) == true){
                                clas = s;
                                clas_file = class_table.getScopeName();
                                break;
                            }
                        }
                    }
                }
                if (clas.equals("") == false && sym.getIsClassMethod() == true){
                    ClassTable class_table = (ClassTable) mct.get(clas_file);
                    ClassSymbol currentClass  = (ClassSymbol) class_table.getClassOfListClasses(clas);

                    // obter metodo
                    //Symbol sy = (Symbol) scp.getMembers().get(0);
                    String ss = "";
                    if (sym.getName().equals("__construct"))
                        ss = "construct";
                    MethodClass mc = currentClass.getMethodClass(sym.getName(), ss, mct);
                    MethodSymbol mss_final = mc.getMeth();
                    String mss_final_file = mc.getClassMeth().getFileClass();

                    /* Fazer a analise do metodo */
                    if (mss_final != null){
                        Instance inst1 = null;
                        if (s.equals("self") == true || s.equals("parent") == true)
                            inst1 = inst;
                            
                        Scope scp1 = (Scope) sym;
                        MethodSymbolSqli meth_sym = new MethodSymbolSqli(mss_final);
                        int valueFinal = meth_sym.analyseMethodSqli(mss_final,scp.getScopeSymbol().getCodeLine(), scp1, mts, mus, filename, mss_final_file, inst1, mct, typeMeth, varsDB);
                        scp1.getScopeSymbol().setTainted(valueFinal);
                        scp.resolveSymbol(scp, scp1.getScopeSymbol(), mts, mus, scp1.getScopeSymbol().getFileSymbol());
                    }
                }
                return;
            }

            case 5:{ // chamada de um metodo dentro de outro metodo
                ftime = false;
                InstanceTable instTable = null;
                SymbolTable st = null;
                               
                ret = instanceMethod(ms, scp, filename, "", mts, mus, inst, mtsc, mct, typeMeth, ret, varsDB, null, null);

                InstanceTable instances_table = null;
                    if (typeMeth.equals("constructor") == true)
                        instances_table = inst.getObjectsOfInstance();
                    else
                        instances_table = mtsc.getObjectsOfMethod();

                if (ret != null && instances_table.containsInstance(ret.getInstanceName()) == true){
                    Boolean a = true;
                    Scope enc_f = scp;
                    Scope enc_b;
                    while (a == true){
                        enc_b = enc_f.getEnclosingScope();
                        if (enc_b.getScopeName().equals(ms.getFunctionName()) == false)
                            enc_f = enc_b;
                        else
                            a = false;
                    }
                    
                    Symbol sy = new Symbol(ret.getInstanceName(), ret.getTainted(), ret.getCreateLineInstance(), ret.getFileInstance());
                    sy.setIsClassInstruction(true);
                    mtsc.getAliases().put(enc_f.getScopeName(), sy);
                    scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                    mts.removeDuplicates(sym);

                    if (cs_att != null){
                        cs_att.getScopeSymbol().setTainted(ret.getTainted());
                        inst.updateTainted(cs_att, sym);
                    }
                }
                exit_for = true;
                return;
            }
            default:{
                if (scp.getEnclosingScope() != null && scp.getEnclosingScope().getScopeName().equals("this") == false)
                    ftime = false;

                if (sym.getRootScope() == null && (sym.getIsClassMethod() == false && sym.getIsUserFunction() == false)){
                    if (ms != null){
                        if (ms.getArgsFunction().containsKey(sym.getName()) == true){
                            ArgFunctionSymbol arg = (ArgFunctionSymbol) ms.getArgsFunction().get(sym.getName());
                            sym.setName(arg.getCallFunctionArg());
                        }
                    }

                    if (mts.getTaintedMembers().containsKey(sym.getName()) == true && mus.existSymbol(sym.getName()) == false)
                        sym.setTainted(1);
                    
                    if (inst != null){
                        SymbolTable t = inst.getInstanceAttributes();
                        if (t.containsSymbol(sym.getName()) || (scp.getEnclosingScope() != null && scp.getEnclosingScope().getScopeName().equals("this") && t.containsSymbol(sym.getName()))){
                            Scope scp_acc = (Scope) t.getSymbolOfListSymbols(sym.getName());
                            sym.setTainted(scp_acc.getScopeSymbol().getTainted());
                        }
                    }

                    scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                    mts.removeDuplicates(sym);


                    if (inst != null && csAtt_att != null){
                        inst.updateTainted(csAtt_att, sym);
                    }

                    if (csAtt_acc != null){
                        sym.setTainted(csAtt_acc.getScopeSymbol().getTainted());
                        scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                    }

                    // verificar se o scope e' uma das funcoes de DB
                    if (GlobalDataSqli.SQLConnectFunctions.contains(scp.getScopeSymbol().getName()) == true){
                        if (scp.getEnclosingScope() != null)
                            varsDB.put("connectionDB", scp.getEnclosingScope().getScopeName());
                        return;
                    }

                    if (GlobalDataSqli.SQLSelectDbFunctions.contains(scp.getScopeSymbol().getName()) == true){
                        if (scp.getEnclosingScope() != null)
                            varsDB.put("selectDB", scp.getEnclosingScope().getScopeName());
                        return;
                    }

                    if (scp.getScopeSymbol().getIsSecureFunction() == false){
                        // se o scope e' tainted e e' uma funcao SQLI entao fazer correcao SQL
                        if (scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false){
                            correctVulner(scp, filename, GlobalDataSqli.MainSymbolTable, null, ms, varsDB, mts, GlobalDataSqli.MainLinesToCorrect);
                        }
                    }
            }
            else{
                Scope scp1 = sym.getRootScope();
                if (scp1.getMembers().size() > 0){
                    FuncAndIncSQLI css2 = new FuncAndIncSQLI(scp1);
                    css2.resolveSymbolClassSqli(ms, scp1, mts, mus, filename, mtsc, inst, mct, ftime, csAtt_att, csAtt_acc, typeMeth, isClassInstruction, varsDB);
                scp.resolveSymbol(scp, sym, mts, mus, filename);
                mts.removeDuplicates(sym);
                return;
                }
                else{
                ftime = false;
                
                // 1. obter instancia
                String instName = scp1.getEnclosingScope().getScopeName();
                String fileInst = scp1.getEnclosingScope().getScopeSymbol().getFileSymbol();
                InstanceTable instTable = GlobalDataSqli.MainInstancesTable.get(fileInst);
                SymbolTable st = GlobalDataSqli.MainSymbolTable.get(fileInst);

                String instName_aux = instName;
                Instance inst1 = null;
                if (st.getAliases().containsKey(instName_aux) == true)
                        instName_aux = st.getInstanceNameFromAliases(instName_aux, instTable);                
                
                if (instTable != null && instTable.containsInstance(instName_aux) == true)
                    inst1 = (Instance) instTable.getInstanceOfListInstances(instName_aux);

                // 2. obter classe
                String c_name = inst1.getInstanceClass();
                String cf_name = inst1.getFileOfClass();
                ClassTable ct = GlobalDataSqli.MainClassesTable.get(cf_name);
                ClassSymbol currentClass = ct.getClassOfListClasses(c_name);

                // 3. procurar metodo
                MethodClass mc = currentClass.getMethodClass(scp1.getScopeName(), "", mct);
                MethodSymbol mss_final = mc.getMeth();
                String mss_final_file = mc.getClassMeth().getFileClass();

                ret = null;
                ret = instanceMethod(mss_final, scp1, filename, mss_final_file, mts, mus, inst1, null, mct, "", ret, varsDB, instTable, st);                

                if (ret != null && instTable.containsInstance(ret.getInstanceName()) == true){
                        Boolean a = true;
                        Scope enc_f = scp;
                        Scope enc_b;
                        while (a == true){
                                enc_b = enc_f.getEnclosingScope();
                                if (enc_b.getScopeName().equals(st.getScopeName()) == false)
                                        enc_f = enc_b;
                                else
                                        a = false;
                        }

                        Symbol sy = new Symbol(ret.getInstanceName(), ret.getTainted(), ret.getCreateLineInstance(), ret.getFileInstance());
                        sy.setIsClassInstruction(true);
                        st.getAliases().put(enc_f.getScopeName(), sy);
                        scp1.resolveSymbol(scp1, sym, mts, mus, sym.getFileSymbol());
                        mts.removeDuplicates(sym);

                        if (cs_att != null){
                                cs_att.getScopeSymbol().setTainted(ret.getTainted());
                                inst1.updateTainted(cs_att, sym);
                        }
                }
                }
                    
                scp.resolveSymbol(scp, sym, mts, mus, filename);
                mts.removeDuplicates(sym);
            }
         }
         
         if (exit_for == true)
             break;

        }
        }
      }
    }
    }    

    private static Instance instanceMethod(MethodSymbol ms, Scope scp, String filename, String file_methClass, TaintedTable mts, UntaintedTable mus, Instance inst, MethodSymbolCall mtsc, Map mct, String typeMeth, Instance objRet, Map varsDB, InstanceTable instTab, SymbolTable symTab) throws IOException{
        // ver quem e' o metodo
        String s = scp.getScopeName();
        String s1 = "", s2 = "";
        Instance ii = null, ret = null;
        
        InstanceTable instances_table = null;
        if (instTab == null){
            if (typeMeth.equals("constructor") == true)
                instances_table = inst.getObjectsOfInstance();
            else
                instances_table = mtsc.getObjectsOfMethod();
        }
        else
            instances_table = instTab;

        Scope enc = scp.getEnclosingScope();
        String enc_s = enc.getScopeSymbol().getName();
        String instanceName = enc_s;
        if (enc.getScopeSymbol().getIsClassMethod() == false && objRet == null){
            // obj -> func()
            // ver se a instancia e' um clone
            if (instTab == null){
                if (mtsc.getAliases().containsKey(instanceName) == true){
                    instanceName = mtsc.getInstanceNameFromAliases(instanceName, instances_table);
                }
            }
            else{
                if (symTab.getAliases().containsKey(instanceName) == true){
                    instanceName = symTab.getInstanceNameFromAliases(instanceName, instances_table);
                }
            }

            if (instances_table.containsInstance(instanceName) == true){
                ii = (Instance) instances_table.getInstanceOfListInstances(instanceName);
                s1 = ii.getInstanceClass();
                s2 = ii.getFileOfClass();
                inst = ii;
            }
            else{
                // func() e' um metodo da instancia actual
                try{
                    s1 = inst.getInstanceClass();
                    s2 = inst.getFileOfClass();
                } catch (Exception e) {}
            }

            if (s1 != null){
                // obter classe
                ClassTable class_table = (ClassTable) mct.get(s2);
                ClassSymbol currentClass  = (ClassSymbol) class_table.getClassOfListClasses(s1);

                // obter metodo
                MethodClass mc = currentClass.getMethodClass(s, "", mct);
                MethodSymbol mss_final = mc.getMeth();
                String mss_final_file = mc.getClassMeth().getFileClass();

                /* Fazer a analise do metodo */
                if (mss_final != null){
                    MethodSymbolSqli meth_sym = new MethodSymbolSqli(mss_final);
                    int valueFinal = meth_sym.analyseMethodSqli(mss_final,scp.getScopeSymbol().getCodeLine(), scp, mts, mus, filename, mss_final_file, inst, mct, typeMeth, varsDB);
                    scp.getScopeSymbol().setTainted(valueFinal);
                    ret = inst.getInstanceOfReturn(s, scp.getScopeSymbol().getCodeLine(), null, null, false);
                }
            }
        }
        else{
            // (obj -> func()) -> func()
            if (objRet != null){
                // obter classe
                s1 = objRet.getInstanceClass();
                s2 = objRet.getFileOfClass();
                ClassTable class_table = (ClassTable) mct.get(s2);
                ClassSymbol currentClass  = (ClassSymbol) class_table.getClassOfListClasses(s1);
                
                if (scp.getScopeSymbol().getIsClassMethod() == true){
                    // obter metodo
                    MethodClass mc = currentClass.getMethodClass(s, "", mct);
                    MethodSymbol mss_final = mc.getMeth();
                    String mss_final_file = mc.getClassMeth().getFileClass();
                  
                    /* Fazer a analise do metodo */
                    if (mss_final != null){
                        MethodSymbolSqli meth_sym = new MethodSymbolSqli(mss_final);
                        int valueFinal = meth_sym.analyseMethodSqli(mss_final,scp.getScopeSymbol().getCodeLine(), scp, mts, mus, filename, mss_final_file, inst, mct, typeMeth, varsDB);
                        scp.getScopeSymbol().setTainted(valueFinal);
                        ret = inst.getInstanceOfReturn(s, scp.getScopeSymbol().getCodeLine(), null, null, false);
                    }
                }
                else{
                    if (scp.getScopeSymbol().getRootScope() == null){                       
                        FuncAndIncSQLI css2 = new FuncAndIncSQLI(scp);
                        css2.resolveSymbolClassSqli(null, scp, mts, mus, scp.getScopeSymbol().getFileSymbol(), mtsc, inst, mct, true, null, null, typeMeth, true, varsDB);
                        scp.resolveSymbol(scp, (Symbol) scp.getMembers().get(0), mts, mus, scp.getScopeSymbol().getFileSymbol());
                        mts.removeDuplicates((Symbol) scp.getMembers().get(0));
                    }
                }
            }
        }

        
        
        // ver se o metodo e' o ultimo a ser chamado
        Boolean endChain = true;
        Symbol sy = null;
        for (int j = 0; j < scp.getMembers().size(); j++){
            sy = (Symbol) scp.getMembers().get(j);
            if (sy.getRootScope() != null && sy.getIsParamUserFunction() == false){
                endChain = false;
                break;
            }
        }
        if (endChain == true){
            if (ret != null){
                ClassTable ct = (ClassTable) mct.get(ret.getFileOfClass());
                ClassSymbol ret_cl = (ClassSymbol) ct.getClassOfListClasses(ret.getInstanceClass());
                Instance r = new Instance(ret, ret_cl);
                instances_table.getMembers().add(r);
                scp.getScopeSymbol().setTainted(ret.getTainted());
                scp.resolveSymbol(scp, scp.getScopeSymbol(), mts, mus, scp.getScopeSymbol().getFileSymbol());
            }
        }
        else{            
            ret = instanceMethod(ms, (Scope) sy, filename, file_methClass, mts, mus, inst, mtsc, mct, typeMeth, ret, varsDB, instTab, symTab);
            scp.resolveSymbol(scp, sy, mts, mus, scp.getScopeSymbol().getFileSymbol());
            mts.removeDuplicates(sy);
        }

        return ret;
    }

    // Resolve symbols of include files that have yet analysed one time.
    // In this way, the include is added just one time in Scope Symtab_include
    // and on next times just need make data flow analysis to scope     
    public void resolveSymbolIncludeSQLI(Scope scp, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map varsDB, Map mftt, Map MainLinesToCorrect) throws IOException{
        String filename_aux="";
        // Scope em analise e' um "include("...")"
        if (scp.getScopeName().equals("include") == true){
            Symbol s = (Symbol) scp.getMembers().get(0); 
            String nameIncFile = s.getName();
          
try{
            SymbolTable st = (SymbolTable) mift.get(nameIncFile);           
            Iterator <Symbol> it = st.getMembers().iterator();
            Scope cs;
            Symbol sy;
            for(; it.hasNext();){
		sy = it.next();
                if (sy.getIsVariableSymbol() == false){
                    cs = (Scope) sy;
                    FuncAndIncSQLI css = new FuncAndIncSQLI(cs);
                    css.resolveSymbolIncludeSQLI(cs, mts, mus, mift, nameIncFile, mft, mst, varsDB, mftt, MainLinesToCorrect);
                }
            }
} catch (Exception e){}
//} catch (Exception e){System.out.println("File: "+ nameIncFile+" not exist");}            
        }
        else{
            if (scp.getScopeSymbol().getIsSecureFunction() == false){
                // verifica se o scope name e' uma chamada de funcao de UserFunction
                // primeiro nas funcoes definidas no file em analise
                MethodSymbolSqli mss_final = null;
                MethodSymbol mss = null;
                String mss_final_file = "";
                if (scp.getScopeSymbol().getIsUserFunction() == true){
                    if (mft.containsKey(filename) == true){
                        MethodTable mt = (MethodTable) mft.get(filename);
                        for(Iterator <MethodSymbol> it = mt.getMembers().iterator(); it.hasNext();){
                            mss = it.next();
                            if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                mss_final = new MethodSymbolSqli(mss);
                                mss_final_file = filename;
                                break;
                            }
                        }
                    }
                    if (mss_final == null){
                        // segundo nas UserFunctions definidas nos include files do file em analise
                        SymbolTable st = (SymbolTable) mift.get(filename);
                        if (st.getIncludeFiles().isEmpty() == false){
                            String s;
                            SymbolTable st1;
                            for(Iterator <String> it = st.getIncludeFiles().iterator(); it.hasNext();){
                                s = it.next();
                                st1 = (SymbolTable) mift.get(s);
                                if(st1.getHaveFunctions() == true){
                                    MethodTable mt  = (MethodTable) mft.get(s);
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            mss_final = new MethodSymbolSqli(mss);
                                            mss_final_file = s;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                if (mss_final == null && scp.getScopeSymbol().getIsFunction() == true
                      && scp.getScopeSymbol().getIsTaintedFunction() == false
                      && scp.getScopeSymbol().getFileSymbol().equals(filename) == false){
                        // terceiro nas UserFunctions definidas nos include files do file que chamou a primeira
                        // funcao. Aqui estamos 'a procura de uma 2da funcao que esta' dentro de um include nao 
                        // pertencente ao file onde ela e' chamada, mas a um file que chama a 1 funcao
                        SymbolTable st = (SymbolTable) mst.get(filename);
                        if (st.getIncludeFiles().isEmpty() == false){
                            String s;
                            SymbolTable st1;
                            for(Iterator <String> it = st.getIncludeFiles().iterator(); it.hasNext();){
                                s = it.next();
                                st1 = (SymbolTable) mift.get(s);
                                if(st1.getHaveFunctions() == true){
                                    MethodTable mt  = (MethodTable) mft.get(s);
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            //mss_final = (MethodSymbolSqli) mss;
                                            mss_final = new MethodSymbolSqli(mss);
                                            mss_final_file = s;
                                            filename_aux = filename;
                                            filename= scp.getScopeSymbol().getFileSymbol();                                          
                                            break;
                                        }
                                    }
                                }
                                if (mss_final != null)
                                    break;
                            }
                        }
                        
                        // verifica nos outros includes. Para termos a certeza que se trata ou nao de uma userFunction
                        if (mss_final == null){
                            for(Iterator <SymbolTable> itt = mift.values().iterator(); itt.hasNext();){
                                SymbolTable st1 = itt.next();
                                if(st1.getHaveFunctions() == true && st.getIncludeFiles().contains(st1.getScopeName()) == false){
                                    MethodTable mt  = (MethodTable) mft.get(st1.getScopeName());
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            //mss_final = (MethodSymbolSqli) mss;
                                            mss_final = new MethodSymbolSqli(mss);
                                            mss_final_file = st1.getScopeName();
                                            filename_aux = filename;
                                            filename= scp.getScopeSymbol().getFileSymbol();                                          
                                            break;
                                        }
                                    }
                                }
                                if (mss_final != null)
                                    break;
                            }                        
                        }
                }
                
                
                // se mss_final != null entao o scope name e' uma Userfunction
                // Fazer entao a analise na UserFunction
                if (mss_final != null){
                    String valueFinal = mss_final.analyseUserFunctionSqli(mss, scp.getScopeSymbol().getCodeLine(), scp, mts, mus, filename, mss_final_file, mift, mft, mst, mftt, MainLinesToCorrect);
                    if (filename_aux.isEmpty() == false){
                        filename = filename_aux;
                        filename_aux = "";
                    }                     
                    if (scp.getEnclosingScope() != null){
                        if (valueFinal.equals("connectionDB") == true)
                            varsDB.put("connectionDB", scp.getEnclosingScope().getScopeName());
                        if (valueFinal.equals("selectDB") == true)
                            varsDB.put("selectDB", scp.getEnclosingScope().getScopeName());
                    }
                }
                else{
                Symbol sym1, sym;
                // verificar se o scope e' uma das funcoes de DB
                //if (scp.getScopeSymbol().getName().equals("mysql_connect") == true || scp.getScopeSymbol().getName().equals("mysqli_connect") == true){
                if (GlobalDataSqli.SQLConnectFunctions.contains(scp.getScopeSymbol().getName()) == true){
                    if (scp.getEnclosingScope() != null)
                        varsDB.put("connectionDB", scp.getEnclosingScope().getScopeName());
                    return;
                }

                //if (scp.getScopeSymbol().getName().equals("mysql_select_db") == true || scp.getScopeSymbol().getName().equals("mysqli_select_db") == true){
                if (GlobalDataSqli.SQLSelectDbFunctions.contains(scp.getScopeSymbol().getName()) == true){
                    if (scp.getEnclosingScope() != null)
                        varsDB.put("selectDB", scp.getEnclosingScope().getScopeName());
                    return;
                }

                if(scp.getScopeSymbol().getName().equals("mysqli_bind_param") == true){
                    Integer i = scp.getScopeSymbol().getCodeLine();
                    varsDB.put("lineMysqliBindParam", i.toString());
                    return;
                }

                Iterator <Symbol> it = scp.getMembers().iterator();
                for(;it.hasNext();){
                    sym = it.next();
                    if (sym.getRootScope() == null){
                            if (mts.getTaintedMembers().containsKey(sym.getName()) == true && mus.existSymbol(sym.getName()) == false)
                                sym.setTainted(1);

                            scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                            mts.removeDuplicates(sym);

                            // se o scope e' tainted e e' uma funcao SQLI entao fazer correcao SQL
                            if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)
                                || scp.getScopeSymbol().getName().equals("mysqli_execute")){
                                        correctVulner(scp, filename, mst, mift, null, varsDB, mts, MainLinesToCorrect);
                            }
                    }

                    else{
                        Scope scp1 = (Scope) sym.getRootScope();
                        FuncAndIncSQLI css1 = new FuncAndIncSQLI(scp1);
                        css1.resolveSymbolIncludeSQLI(sym.getRootScope(), mts, mus, mift, filename, mft, mst, varsDB, mftt, MainLinesToCorrect);
                        scp.resolveSymbol(scp, sym, mts, mus, filename);
                        mts.removeDuplicates(sym);
                        
                        // se o scope e' tainted e e' uma funcao SQLI entao fazer correcao SQL
                        if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)
                            || scp.getScopeSymbol().getName().equals("mysqli_execute")){
                                    correctVulner(scp, filename, mst, mift, null, varsDB, mts, MainLinesToCorrect);
                        }
                    }
               }
            }
        }
      }
    }

    // Resolve symbols of function defined by user that have yet analysed one time.
    // In this way, the function is added just one time in Scope Symtab_functions
    // and on next times just need make data flow analysis to scope
    public void resolveSymbolFunctionSQLI(MethodSymbol ms, Scope scp, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map varsDB, Map mftt, Map MainLinesToCorrect) throws IOException{
        String filename_aux="";
        if (scp.getScopeName().equals("include") == true){
            Symbol s = (Symbol) scp.getMembers().get(0);
            String nameIncFile = s.getName();
            String x = nameIncFile.substring(1,nameIncFile.length()-1);
            SymbolTable st = (SymbolTable) mift.get(x);
            Iterator <Symbol> it = st.getMembers().iterator();
            Scope cs;
            for(; it.hasNext();){
		cs = (Scope) it.next();
                FuncAndIncSQLI css = new FuncAndIncSQLI(cs);
                css.resolveSymbolIncludeSQLI(cs, mts, mus, mift, x, mft, mst, varsDB, mftt, MainLinesToCorrect);
            }
        }
        else{
            if (scp.getScopeSymbol().getIsSecureFunction() == false){
                // verifica se o scope name e' uma chamada de funcao de UserFunction
                // primeiro nas funcoes definidas no file em analise
                MethodSymbolSqli mss_final = null;
                MethodSymbol mss = null;
                String mss_final_file = "";
                if (scp.getScopeSymbol().getIsUserFunction() == true){
                    if (mft.containsKey(filename) == true){
                        MethodTable mt = (MethodTable) mft.get(filename);
                        for(Iterator <MethodSymbol> it = mt.getMembers().iterator(); it.hasNext();){
                            mss = it.next();
                            if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                mss_final = new MethodSymbolSqli(mss);
                                mss_final_file = filename;
                                break;
                            }
                        }
                    }
                    if (mss_final == null){
                        // segundo nas UserFunctions definidas nos include files do file em analise
                        SymbolTable st = (SymbolTable) mst.get(filename);
                        if (st.getIncludeFiles().isEmpty() == false){
                            String s;
                            SymbolTable st1;
                            for(Iterator <String> it = st.getIncludeFiles().iterator(); it.hasNext();){
                                s = it.next();
                                st1 = (SymbolTable) mift.get(s);
                                if(st1.getHaveFunctions() == true){
                                    MethodTable mt  = (MethodTable) mft.get(s);
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            mss_final = new MethodSymbolSqli(mss);
                                            mss_final_file = s;
                                            break;
                                        }
                                    }
                                }
                                if (mss_final != null)
                                    break;
                            }
                        }
                    }
                }
                
                if (mss_final == null && scp.getScopeSymbol().getIsFunction() == true
                      && scp.getScopeSymbol().getIsTaintedFunction() == false
                      && scp.getScopeSymbol().getFileSymbol().equals(filename) == false){
                        // terceiro nas UserFunctions definidas nos include files do file que chamou a primeira
                        // funcao. Aqui estamos 'a procura de uma 2da funcao que esta' dentro de um include nao 
                        // pertencente ao file onde ela e' chamada, mas a um file que chama a 1 funcao
                        SymbolTable st = (SymbolTable) mst.get(filename);
                        if (st.getIncludeFiles().isEmpty() == false){
                            String s;
                            SymbolTable st1;
                            for(Iterator <String> it = st.getIncludeFiles().iterator(); it.hasNext();){
                                s = it.next();
                                st1 = (SymbolTable) mift.get(s);
                                if(st1.getHaveFunctions() == true){
                                    MethodTable mt  = (MethodTable) mft.get(s);
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            //mss_final = (MethodSymbolSqli) mss;
                                            mss_final = new MethodSymbolSqli(mss);
                                            mss_final_file = s;
                                            filename_aux = filename;
                                            filename= scp.getScopeSymbol().getFileSymbol();                                          
                                            break;
                                        }
                                    }
                                }
                                if (mss_final != null)
                                    break;
                            }
                        }
                        
                        // verifica nos outros includes. Para termos a certeza que se trata ou nao de uma userFunction
                        if (mss_final == null){
                            for(Iterator <SymbolTable> itt = mift.values().iterator(); itt.hasNext();){
                                SymbolTable st1 = itt.next();
                                if(st1.getHaveFunctions() == true && st.getIncludeFiles().contains(st1.getScopeName()) == false){
                                    MethodTable mt  = (MethodTable) mft.get(st1.getScopeName());
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            mss_final = new MethodSymbolSqli(mss);
                                            mss_final_file = st1.getScopeName();
                                            filename_aux = filename;
                                            filename= scp.getScopeSymbol().getFileSymbol();                                          
                                            break;
                                        }
                                    }
                                }
                                if (mss_final != null)
                                    break;
                            }                        
                        }
                }


            // se mss_final != null entao o scope name e' uma Userfunction
            // Fazer entao a analise na UserFunction
            if (mss_final != null){                
                //try{
                String valueFinal = mss_final.analyseUserFunctionSqli(mss, scp.getScopeSymbol().getCodeLine(), scp, mts, mus, filename, mss_final_file, mift, mft, mst, mftt, MainLinesToCorrect);
                if (filename_aux.isEmpty() == false){
                    filename = filename_aux;
                    filename_aux = "";
                }
                    
                
                if (valueFinal.equals("connectionDB") == true)
                    varsDB.put("connectionDB", scp.getEnclosingScope().getScopeName());
                if (valueFinal.equals("selectDB") == true)
                    varsDB.put("selectDB", scp.getEnclosingScope().getScopeName());
                //} catch (Exception e){
                //    System.out.println("Error processing user function: "+mss_final.getName());
                //}
            }
            else{
            Symbol sym1, sym;

            // Se o nome do scope for o nome de argumento da chamada da funcao entao o nome do scope muda para ele
            if(ms.getArgsFunction().containsKey(scp.getScopeName()) == true){
                ArgFunctionSymbol arg = (ArgFunctionSymbol) ms.getArgsFunction().get(scp.getScopeName());
                scp.getScopeSymbol().setName(arg.getCallFunctionArg());             
                return;
            }

            // verificar se o scope e' uma das funcoes de DB
            //if (scp.getScopeSymbol().getName().equals("mysql_connect") == true || scp.getScopeSymbol().getName().equals("mysqli_connect") == true){
            if (GlobalDataSqli.SQLConnectFunctions.contains(scp.getScopeSymbol().getName()) == true){
                if (scp.getEnclosingScope() != null)
                    varsDB.put("connectionDB", scp.getEnclosingScope().getScopeName());
                return;
            }

            //if (scp.getScopeSymbol().getName().equals("mysql_select_db") == true || scp.getScopeSymbol().getName().equals("mysqli_select_db") == true){
            if (GlobalDataSqli.SQLSelectDbFunctions.contains(scp.getScopeSymbol().getName()) == true){
                if (scp.getEnclosingScope() != null)
                    varsDB.put("selectDB", scp.getEnclosingScope().getScopeName());
                return;
            }

            if(scp.getScopeSymbol().getName().equals("mysqli_bind_param") == true){
                Integer i = scp.getScopeSymbol().getCodeLine();
                varsDB.put("lineMysqliBindParam", i.toString());
                return;
            }

            Iterator <Symbol> it = scp.getMembers().iterator();
            for(;it.hasNext();){
                    sym = it.next();
                    if (sym.getRootScope() == null){
                            if (ms.getArgsFunction().containsKey(sym.getName()) == true){
                                ArgFunctionSymbol arg = (ArgFunctionSymbol) ms.getArgsFunction().get(sym.getName());
                                sym.setName(arg.getCallFunctionArg());
                            }

                            if (mts.getTaintedMembers().containsKey(sym.getName()) == true && mus.existSymbol(sym.getName()) == false)
                                sym.setTainted(1);

                            scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                            mts.removeDuplicates(sym);

                            // se o scope e' tainted e e' uma funcao SQLI entao fazer correcao SQL
                            if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)
                                || scp.getScopeSymbol().getName().equals("mysqli_execute")){
                                        correctVulner(scp, filename, mst, null, ms, varsDB, mts, MainLinesToCorrect);
                            }
                            
                    }
                    else{
                        Scope scp1 = (Scope) sym.getRootScope();
                        FuncAndIncSQLI css1 = new FuncAndIncSQLI(scp1);
                        css1.resolveSymbolFunctionSQLI(ms, sym.getRootScope(), mts, mus, mift, filename, mft, mst, varsDB, mftt, MainLinesToCorrect);
                        scp.resolveSymbol(scp, sym, mts, mus, filename);
                        mts.removeDuplicates(sym);
                        
                        // se o scope e' tainted e e' uma funcao SQLI entao fazer correcao SQL
                        if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)
                            || scp.getScopeSymbol().getName().equals("mysqli_execute")){
                                    correctVulner(scp, filename, mst, null, ms, varsDB, mts, MainLinesToCorrect);
                        }
                    }
            }

            Scope aux = scp.getScopeSymbol().getRootScope();
            if (aux.getScopeName().equals("return") == true && aux.getScopeSymbol().getTainted() == 1){
                ms.getScopeSymbol().setTainted(1);

                //inserir ms como dependente do return
                RootTaintedSymbol Rrt;
                Rrt = (RootTaintedSymbol) mts.getTaintedMembers().get("return");
                RelatedTaintedSymbol rtt;
                rtt =   (RelatedTaintedSymbol) Rrt.getListTaintedMembers().get(Rrt.getListTaintedMembers().size()-1);
                // Caso o ms nao pertenca 'a lista da funcao tainted
                if (rtt.getTaintedMembers().containsKey(ms.getScopeName()) == false){
                    VariableTaintedSymbol var = new VariableTaintedSymbol(ms.getScopeName(),
                                                ms.getScopeSymbol().getCodeLine(), ms.getScopeSymbol().getTainted(),
                                                ms.getScopeSymbol().getFileSymbol());
                    rtt.define(var);
                }
                else{
                    VariableTaintedSymbol var = (VariableTaintedSymbol) rtt.getTaintedMembers().get(ms.getScopeName());
                    var.InsertLine(ms.getScopeSymbol().getCodeLine());
                    var.InsertFile(ms.getScopeSymbol().getFileSymbol());
                }
            }
        }
    }
}
}

    // Resolve symbols of SymbolTable.
    public void resolveSymbolSQLI(Scope scp, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map varsDB, Map mftt, Map MainLinesToCorrect, Map mct, Map mobjt) throws IOException{               
        if (scp.getScopeName().equals("include")){            
            try{
            this.resolveSymbolIncludeSQLI(scp, mts, mus, mift, filename, mft, mst, varsDB, mftt, MainLinesToCorrect);
            } catch (Exception e){
                //System.out.println("Error processing include file: "+this.getName());
            }
            return;
        }
        
        if (scp.getScopeSymbol().getIsSecureFunction() == false){            
            if (scp.getScopeSymbol().getIsUserFunction() == true){               
                try{
                    this.resolveSymbolFunctionSQLI(null, scp, mts, mus, mift, filename, mft, mst, varsDB, mftt, MainLinesToCorrect);
                } catch (Exception e){
                //    System.out.println("Error processing user function: "+this.getName());
                }
                return;
            }

            if(scp.getScopeSymbol().getIsClassInstruction() == true){
                try{
                this.resolveSymbolClassSqli(null, scp, mts, mus, filename, null, null, mct, true, null, null, "", true, varsDB);
                } catch (Exception e){
                    //System.out.println("Error processing instruction: "+this.getName());
                }
                return;
            }

            // verificar se o scope e' uma das funcoes de DB
            if (GlobalDataSqli.SQLConnectFunctions.contains(scp.getScopeSymbol().getName()) == true){
                if (scp.getEnclosingScope() != null)
                    varsDB.put("connectionDB", scp.getEnclosingScope().getScopeName());
                return;
            }

            if (GlobalDataSqli.SQLSelectDbFunctions.contains(scp.getScopeSymbol().getName()) == true){
                if (scp.getEnclosingScope() != null)
                    varsDB.put("selectDB", scp.getEnclosingScope().getScopeName());
                return;
            }

            if(scp.getScopeSymbol().getName().equals("mysqli_bind_param") == true){
                Integer i = scp.getScopeSymbol().getCodeLine();
                varsDB.put("lineMysqliBindParam", i.toString());
                return;
            }            
            
            // Analise de scope normal
            Symbol sym1, sym;
            Iterator <Symbol> it = scp.getMembers().iterator();
            for(;it.hasNext();){
                sym = it.next();
                if (sym.getRootScope() == null){
                    if (mts.getTaintedMembers().containsKey(sym.getName()) == true && mus.existSymbol(sym.getName()) == false)
                        sym.setTainted(1);

                    scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                    mts.removeDuplicates(sym);

                    // se o scope e' tainted e e' uma funcao SQLI entao fazer correcao SQL
                    if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)
                        || scp.getScopeSymbol().getName().equals("mysqli_execute")){
                            correctVulner(scp, filename, mst, null, null, varsDB, mts, MainLinesToCorrect);
                    }                   
                }
                else{
                    Scope scp1 = (Scope) sym.getRootScope();
                    FuncAndIncSQLI css1 = new FuncAndIncSQLI(scp1);
                    css1.resolveSymbolSQLI(sym.getRootScope(), mts, mus, mift, filename, mft, mst, varsDB, mftt, MainLinesToCorrect, mct, mobjt);
                    scp.resolveSymbol(scp, sym, mts, mus, filename);
                    mts.removeDuplicates(sym);
                    
                    // se o scope e' tainted e e' uma funcao SQLI entao fazer correcao SQL
                    if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)
                        || scp.getScopeSymbol().getName().equals("mysqli_execute")){
                            correctVulner(scp, filename, mst, null, null, varsDB, mts, MainLinesToCorrect);
                    }
                }
           }            
        }
    }
   
    private void correctVulner(Scope scp, String filename, Map mst, Map mift, MethodSymbol ms, Map varsDB, TaintedTable mts, Map MainLinesToCorrect) throws IOException{        
            scp.getScopeSymbol().setIsVulDetected(true);
            SymbolTable currentSymbolTable = new SymbolTable(scp.getScopeSymbol().getFileSymbol());
            SymbolTable ct;          
            
            int m = 0;
            if (mift == null || mift.size() == 0)
                m = 0;
            else
                m = 1;
            
            if (ms == null){
                if (m == 0){
                    ct = (SymbolTable) mst.get(scp.getScopeSymbol().getFileSymbol());
                    currentSymbolTable.setAllSymbols(ct.getMembers());
                    currentSymbolTable.setAllIncludeFiles(ct.getIncludeFiles());
                }
                else{    
                    ct = (SymbolTable) mift.get(scp.getScopeSymbol().getFileSymbol());
                    currentSymbolTable.setAllSymbols(ct.getMembers());
                    currentSymbolTable.setAllIncludeFiles(ct.getIncludeFiles());
                }
            }
            else
                currentSymbolTable.setAllSymbols(ms.getMembers());
            
            VulnerabilityPathSqli vvp = new VulnerabilityPathSqli(scp);
            String conn, db, s;
            conn = (String) varsDB.get("connectionDB");
            db = (String) varsDB.get("selectDB");
            s = (String) varsDB.get("lineMysqliBindParam");
            int i = Integer.parseInt(s);
            
/* **************
 * CORRECAO e DM
 */                        
            VulnerSQLI vv = vvp.collectVulnPathSQL(conn, db, i, GlobalDataSqli.UserInput, mts, currentSymbolTable, false, MainLinesToCorrect);

            /*
                    DATA MINING
            */
            
            int fp = vv.getVectorAttributesOfVulner().predictFalsePositive(true);
            vv.setIsFP(fp);
            
            
            
            if (GlobalDataSqli.MainNumFP.containsKey(vv.getFileOf_SS()) == false)
                GlobalDataSqli.MainNumFP.put(vv.getFileOf_SS(), 0);
            
            if (GlobalDataSqli.MainNumVul.containsKey(vv.getFileOf_SS()) == false)
                GlobalDataSqli.MainNumVul.put(vv.getFileOf_SS(), 0);            
            
            //try{
            if (vv.IsFP() == 1){                          
                int nFP = GlobalDataSqli.MainNumFP.get(vv.getFileOf_SS()) + 1;
                GlobalDataSqli.MainNumFP.put(vv.getFileOf_SS(), nFP);                            
            }
            else{
                if (scp.getScopeSymbol().getTainted() == 1){                     
                    int nVul = GlobalDataSqli.MainNumVul.get(vv.getFileOf_SS()) + 1;
                    GlobalDataSqli.MainNumVul.put(vv.getFileOf_SS(), nVul);
                }

                /* Correccao */
                AutoCorrectSQL acs = new AutoCorrectSQL(vv);
                acs.buildCorrectSQL(MainLinesToCorrect);
            }
            //} catch (Exception e) {}

            if (scp.getScopeSymbol().getName().equals("mysqli_execute"))
                varsDB.put("lineMysqliBindParam", "-1");
           
            GlobalDataSqli.currentVulner = null;            
        //}
    }
    
    

    @Override
    public List<Symbol> getMembers() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void print(Scope scp) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

} public class GlobalDataSqli {

    // user input
    private final static String UserInputs[] = {"_GET", "_POST", "_COOKIE", "_REQUEST", "HTTP_GET_VARS", "HTTP_POST_VARS", "HTTP_COOKIE_VARS", "HTTP_REQUEST_VARS"};
    public static List<String> UserInput = Arrays.asList(UserInputs);

    // functions where can occur SQLI
    // functions deprecated: mysql_db_query, mysqli_execute, mysqli_master_query
    private final static String TaintFunctions[] = {"mysql_db_query", "mysql_query", "mysql_unbuffered_query", "mysqli_multi_query", "mysqli_stmt_execute",
                               "mysqli_execute", "mysqli_query", "mysqli_real_query", "mysqli_master_query", "query", "multi_query", "real_query", "execute",
                               "db2_exec", "pg_query", "pg_send_query"};
    /* "mysqli_stmt_execute", "execute" */
    public static List<String> SQLIFunctions = Arrays.asList(TaintFunctions);

    // functions that make secure the user input
    // functions deprecated: mysqli_bind_param, mysql_escape_string, mysqli_escape_string
    private final static String SecureFunctions[] = {"mysql_escape_string", "mysql_real_escape_string", "mysqli_escape_string", "mysqli_real_escape_string",
                                "mysqli_stmt_bind_param", "escape_string", "real_escape_string", "bind_param",
                                "db2_escape_string", "pg_escape_string", "pg_escape_bytea", "pg_escape_literal", "san_sqli"};
    //private final static String SecureFunctions[] = {};    
    public static List<String> SQLSecFunctions = Arrays.asList(SecureFunctions);

    // functions to connect to db
    private final static String ConnectFunctions[] = {"mysql_connect", "mysql_pconnect", "mysqli_connect", "mysqli_real_connect", "real_connect", "__construct",
                                "db2_connect", "db2_pconnect", "pg_connect", "pg_pconnect"};
    public static List<String> SQLConnectFunctions = Arrays.asList(ConnectFunctions);

    // functions to select db
    private final static String SelectDbFunctions[] = {"mysql_select_db", "mysqli_select_db", "select_db"};
    public static List<String> SQLSelectDbFunctions = Arrays.asList(SelectDbFunctions);
    
    // Mysql keywords
    private final static String clausules[] = {"SELECT", "INSERT INTO", "UPDATE", "ALTER TABLE", "DELETE FROM", "CREATE TABLE", "DROP TABLE",
                                "CREATE DATABASE", "DROP DATABASE", "FROM", "WHERE", "ORDER BY", "GROUP BY", "HAVING"};
    public static List<String> SQLKeywords = Arrays.asList(clausules);    

    // create main Tables
    public static Map <String, SymbolTable> MainSymbolTable = new LinkedHashMap<String, SymbolTable>();
    public static Map <String, SymbolTable> MainIncludeFilesTable = new LinkedHashMap<String, SymbolTable>();
    public static Map <String, MethodTable> MainFunctionsTable = new LinkedHashMap<String, MethodTable>();
    public static Map <String, MethodTableCalls> MainFunctionsCallsTable = new LinkedHashMap<String, MethodTableCalls>();
    public static Map <String, ClassTable> MainClassesTable = new LinkedHashMap<String, ClassTable>();
    public static Map <String, InstanceTable> MainInstancesTable = new LinkedHashMap<String, InstanceTable>();
    public static Map <String, TaintedTable> MainTaintedTable = new LinkedHashMap<String, TaintedTable>();
    public static Map <String, MethodTaintedTable> MainFunctionsTaintedTable = new LinkedHashMap<String, MethodTaintedTable>();
    public static UntaintedTable mus = new UntaintedTable();
    public static Map <String, LinesToCorrect> MainLinesToCorrect = new LinkedHashMap<String, LinesToCorrect>();
    public static Map <String, Integer> MainNumVul = new LinkedHashMap<String, Integer>();
    public static Map <String, ListVulners> MainListVulners = new LinkedHashMap<String, ListVulners>();
    public static VulnerSQLI currentVulner = null;
    public static Map <String, Integer> MainNumFP = new LinkedHashMap<String, Integer>();

    /*
     * Verify if symbol name contain tainted input
     */
    public static String containsInput(String f){
        //Verificar se f tem UserInput
        String found = "";
        for (String aux : GlobalDataSqli.UserInput){
                if (f.contains(aux) == true){
                    return aux;
                }
        }
        return found;
    }
  
    
    /*
     * Returns the number of real vulnerabilities detected
     */    
    public static int getNumVul(){
        int j, vuu=0;
        for(Iterator <Integer> it = GlobalDataSqli.MainNumVul.values().iterator(); it.hasNext(); ){
            j = it.next();
            vuu += j;
        }
        return vuu;
    }    

    /*
     * Returns the number of false positives detected
     */    
    public static int getNumFP(){
        int j, fpp=0;
        for(Iterator <Integer> it = GlobalDataSqli.MainNumFP.values().iterator(); it.hasNext(); ){
            j = it.next();
            fpp += j;
        }
        return fpp;
    }     
    
    
    
} public class FuncAndIncXSS extends ScopedSymbol{    

    // *** CONSTRUCTORS
    public FuncAndIncXSS(Scope scp) {
        super(scp.getScopeSymbol().getName(), scp.getScopeSymbol().getCodeLine(), scp.getScopeSymbol().getTainted(), scp.getEnclosingScope(), scp.getScopeSymbol().getFileSymbol());   
    }
   

    // *** METHODS
    public void resolveSymbolClassXSS(MethodSymbol ms, Scope scp, TaintedTable mts, UntaintedTable mus, String filename, MethodSymbolCall mtsc, Instance inst, Map mct, Boolean ftime, Scope cs_att, Scope cs_acc, String typeMeth, Boolean isClassInstruction) throws IOException{
    if (scp.getScopeSymbol().getIsSecureFunction() == false){ 
    Scope csAtt_acc = cs_att;
    Scope csAtt_att = cs_acc;
    String s = scp.getScopeName();
    Instance ret = null;
    Boolean exit_for = false;
    
    if (inst != null){   
    SymbolTable t = inst.getInstanceAttributes();
  
    //pegar no atributo do objecto numa atribuicao ou acesso
    if (t.containsSymbol(s) || (scp.getEnclosingScope() != null && scp.getEnclosingScope().getScopeName().equals("this") && t.containsSymbol(s))){
       //pegar no atributo do objecto numa atribuicao ou acesso
       if (ftime == true){
           csAtt_att = (Scope) t.getSymbolOfListSymbols(s);
           try{
               csAtt_att.getMembers().clear();
               for(int i=0; i< scp.getMembers().size(); i++)
                    csAtt_att.getMembers().add(scp.getMembers().get(i));
           } catch (Exception e) {}
           ftime = false;

           if (scp.getEnclosingScope() != null && scp.getEnclosingScope().getScopeName().equals("this")){
                Symbol sym_this = scp.getEnclosingScope().getScopeSymbol();
                scp.getScopeSymbol().setIsInstance(sym_this.getIsInstance());
                scp.getScopeSymbol().setIsClone(sym_this.getIsClone());
           }
       }
       else{
           //csAtt_acc = (Scope) t.getMembers().get(i);
           csAtt_acc = (Scope) t.getSymbolOfListSymbols(s);
       }
        }

    }

    Iterator <Symbol> it;
    Symbol sym;
    for (it = scp.getMembers().iterator(); it.hasNext();){
        sym = it.next();
        if (isClassInstruction == true){
        int op = 0;

        // criacao de um objecto
        // do tipo $a = new A_class()
        if (scp.getScopeSymbol().getIsInstance() == true)
            op = 2;

        // atribuicao e' um clone
        // do tipo $a = clone $obj
        if (scp.getScopeSymbol().getIsClone() == true)
            op = 3;

        // staticMember
        // A::meth()
        if (scp.getScopeSymbol().getIsStaticMember() == true)
            op = 4;

        // chamada de um metodo
        if(scp.getScopeSymbol().getIsFunction() == true && scp.getScopeSymbol().getIsClassMethod() == true &&
           scp.getScopeSymbol().getIsSecureFunction()==false && scp.getScopeSymbol().getIsTaintedFunction()==false){
            if (ms != null)
                op = 5; // metodo dentro de um metodo
            else
                op = 1; //metodo normal
        }

        switch (op){
            case 1:{ // chamada de um metodo normal
                ftime = false;
                
                // 1. obter instancia
                String instName = scp.getEnclosingScope().getScopeName();
                String fileInst = scp.getEnclosingScope().getScopeSymbol().getFileSymbol();
                InstanceTable instTable = GlobalDataXSS.MainInstancesTable.get(fileInst);
                SymbolTable st = GlobalDataXSS.MainSymbolTable.get(fileInst);
                String instName_aux = instName;
                Instance inst1 = null;
                if (st.getAliases().containsKey(instName_aux) == true)
                        instName_aux = st.getInstanceNameFromAliases(instName_aux, instTable);                
                
                if (instTable != null && instTable.containsInstance(instName_aux) == true)
                    inst1 = (Instance) instTable.getInstanceOfListInstances(instName_aux);

                // 2. obter classe
                String c_name = inst1.getInstanceClass();
                String cf_name = inst1.getFileOfClass();
                ClassTable ct = GlobalDataXSS.MainClassesTable.get(cf_name);
                ClassSymbol currentClass = ct.getClassOfListClasses(c_name);

                // * 3. procurar metodo
                MethodClass mc = currentClass.getMethodClass(scp.getScopeName(), "", mct);
                MethodSymbol mss_final = mc.getMeth();
                String mss_final_file = mc.getClassMeth().getFileClass();

                ret = null;
                ret = instanceMethod(mss_final, scp, filename, mss_final_file, mts, mus, inst1, null, mct, "", ret, instTable, st);                

                if (ret != null && instTable.containsInstance(ret.getInstanceName()) == true){
                        Boolean a = true;
                        Scope enc_f = scp;
                        Scope enc_b;
                        while (a == true){
                                enc_b = enc_f.getEnclosingScope();
                                if (enc_b.getScopeName().equals(st.getScopeName()) == false)
                                        enc_f = enc_b;
                                else
                                        a = false;
                        }

                        Symbol sy = new Symbol(ret.getInstanceName(), ret.getTainted(), ret.getCreateLineInstance(), ret.getFileInstance());
                        sy.setIsClassInstruction(true);
                        st.getAliases().put(enc_f.getScopeName(), sy);
                        scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                        mts.removeDuplicates(sym);

                        if (cs_att != null){
                                cs_att.getScopeSymbol().setTainted(ret.getTainted());
                                inst1.updateTainted(cs_att, sym);
                        }
                }
                exit_for = true;
                //break;
                return;
            }
            case 2:{
                ftime = false;
                // criacao de um objecto

                Instance inst1 = null;
                InstanceTable instances_table = null;
                if (ms == null){
                    String file_inst = sym.getFileSymbol();
                    instances_table = GlobalDataXSS.MainInstancesTable.get(file_inst);
                    Iterator <Instance> it1 = instances_table.getMembers().iterator();
                    for (; it1.hasNext();){
                        inst1 = it1.next();
                        if (inst1.getInstanceName().equals(s) && inst1.getCreateLineInstance() == sym.getCodeLine()){
                            break;
                        }
                    }
                }

                /* 1. Procurar classe */
                ClassTable class_table = null;
                ClassSymbol currentClass = null;

                for (Iterator <ClassTable> it3 = GlobalDataXSS.MainClassesTable.values().iterator(); it3.hasNext();){
                    class_table = it3.next();

                    if (class_table.containsClass(sym.getName()) == true){
                        currentClass = (ClassSymbol) class_table.getClassOfListClasses(sym.getName());
                        break;
                    }
                }
                
                    if (ms != null){
                        if (typeMeth.equals("constructor") == true)
                            instances_table = inst.getObjectsOfInstance();
                        else
                            instances_table = mtsc.getObjectsOfMethod();
                    }

                    if (currentClass.getExtendsClassName() != null){
                        inst1 = new Instance(scp.getScopeName(), scp.getScopeSymbol().getCodeLine(), inst.getFileInstance(), sym.getName(), class_table.getScopeName(), currentClass, true);
                        instances_table.define(inst1);
                        return;
                    }
                    if (ms != null){
                        inst1 = new Instance(scp.getScopeName(), scp.getScopeSymbol().getCodeLine(), inst.getFileInstance(), sym.getName(), class_table.getScopeName(), currentClass, false);
                        instances_table.define(inst1);
                    }

                /* 2. procurar metodo construtor*/
                MethodClass mc = currentClass.getMethodClass(sym.getName(), "construct", mct);
                MethodSymbol mss_final = mc.getMeth();
                String mss_final_file = mc.getClassMeth().getFileClass();

                /* Fazer a analise do construtor */
                if (mss_final == null){ // a classe nao tem metodo construtor. logo fazer taint analise aos atributos
                    SymbolTable t1 = inst1.getInstanceAttributes();
                    TaintedTable tt1 = inst1.getMtsInstanceAttributes();
                    UntaintedTable ut1 = inst1.getMusInstanceAttributes();
                    Scope scp1;
                    for(Iterator <Symbol> it4 = t1.getMembers().iterator(); it4.hasNext();){
                         scp1 = (Scope) it4.next();
                         scp1.resolveSymbolClass(tt1, ut1, inst1.getFileOfClass());
                    }
                }
                else{
                    typeMeth = "constructor";
                    MethodSymbolXSS meth_sym = new MethodSymbolXSS(mss_final);
                    int valueFinal = meth_sym.analyseMethodXSS(mss_final,scp.getScopeSymbol().getCodeLine(), (Scope)sym, mts, mus, filename, mss_final_file, inst1, mct, typeMeth);
                    scp.getScopeSymbol().setTainted(valueFinal);
                    scp.resolveSymbol(scp, sym, mts, mus, scp.getScopeSymbol().getFileSymbol());

                    if (cs_att != null){
                        cs_att.getScopeSymbol().setTainted(valueFinal);
                        inst.updateTainted(cs_att, sym);
                    }
                }
                return;
            }

            case 3:{
                ftime = false;

                // atribuicao e' um clone
                if (ms != null)
                    mtsc.getAliases().put(s, sym);
                
                scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                if (cs_att != null){
                    cs_att.getScopeSymbol().setTainted(scp.getScopeSymbol().getTainted());
                    inst.updateTainted(cs_att, sym);
                }
                return;
            }

            case 4:{
                ftime = false;

                // staticMember
                // obter classe
                String clas = "";
                String clas_file = "";
                if (s.equals("self") == true){
                    clas = inst.getInstanceClass();
                    clas_file = inst.getFileOfClass();
                }
                else{
                    if (s.equals("parent") == true){
                        clas = inst.getInstanceClass();
                        clas_file = inst.getFileOfClass();
                        ClassTable ct = GlobalDataXSS.MainClassesTable.get(clas_file);
                        ClassSymbol cls = (ClassSymbol) ct.getClassOfListClasses(clas);
                        clas = cls.getExtendsClassName();
                        clas_file = cls.getFileExtendsClass();

                    }
                    else{
                        // obter nome e file da class
                        for (Iterator <ClassTable> it1 = mct.values().iterator(); it1.hasNext();){
                            ClassTable class_table = it1.next();
                            if (class_table.containsClass(s) == true){
                                clas = s;
                                clas_file = class_table.getScopeName();
                                break;
                            }
                        }
                    }
                }
                if (clas.equals("") == false && sym.getIsClassMethod() == true){
                    ClassTable class_table = (ClassTable) mct.get(clas_file);
                    ClassSymbol currentClass  = (ClassSymbol) class_table.getClassOfListClasses(clas);

                    // obter metodo
                    //Symbol sy = (Symbol) scp.getMembers().get(0);
                    String ss = "";
                    if (sym.getName().equals("__construct"))
                        ss = "construct";
                    MethodClass mc = currentClass.getMethodClass(sym.getName(), ss, mct);
                    MethodSymbol mss_final = mc.getMeth();
                    String mss_final_file = mc.getClassMeth().getFileClass();
                    /* Fazer a analise do metodo */
                    if (mss_final != null){
                        Instance inst1 = null;
                        if (s.equals("self") == true || s.equals("parent") == true)
                            inst1 = inst;
                        
                        Scope scp1 = (Scope) sym;
                        MethodSymbolXSS meth_sym = new MethodSymbolXSS(mss_final);
                        int valueFinal = meth_sym.analyseMethodXSS(mss_final,scp.getScopeSymbol().getCodeLine(), scp1, mts, mus, filename, mss_final_file, inst, mct, typeMeth);
                        scp1.getScopeSymbol().setTainted(valueFinal);
                        scp.resolveSymbol(scp, scp1.getScopeSymbol(), mts, mus, scp1.getScopeSymbol().getFileSymbol());
                    }
                }
                return;
            }

            case 5:{
                ftime = false;
                InstanceTable instTable = null;
                SymbolTable st = null;
                
                ret = instanceMethod(ms, scp, filename, "", mts, mus, inst, mtsc, mct, typeMeth, ret, null, null);

                InstanceTable instances_table = null;
                if (typeMeth.equals("constructor") == true)
                    instances_table = inst.getObjectsOfInstance();
                else
                    instances_table = mtsc.getObjectsOfMethod();

                //if (ret != null && instances_table.getMembers().contains(ret) == true){
                if (ret != null && instances_table.containsInstance(ret.getInstanceName()) == true){
                    Boolean a = true;
                    Scope enc_f = scp;
                    Scope enc_b;
                    while (a == true){
                        enc_b = enc_f.getEnclosingScope();
                        if (enc_b.getScopeName().equals(ms.getFunctionName()) == false)
                            enc_f = enc_b;
                        else
                            a = false;
                    }

                    Symbol sy = new Symbol(ret.getInstanceName(), ret.getTainted(), ret.getCreateLineInstance(), ret.getFileInstance());
                    sy.setIsClassInstruction(true);
                    mtsc.getAliases().put(enc_f.getScopeName(), sy);
                    scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                    mts.removeDuplicates(sym);

                    if (cs_att != null){
                        cs_att.getScopeSymbol().setTainted(ret.getTainted());
                        inst.updateTainted(cs_att, sym);
                    }
                }
                exit_for = true;
                return;
            }
            default:{
                if (scp.getEnclosingScope() != null && scp.getEnclosingScope().getScopeName().equals("this") == false)
                    ftime = false;

                if (sym.getRootScope() == null && (sym.getIsClassMethod() == false && sym.getIsUserFunction() == false)){
                    if (ms != null){                  
                      if (ms.getArgsFunction().containsKey(sym.getName()) == true){
                          ArgFunctionSymbol arg = (ArgFunctionSymbol) ms.getArgsFunction().get(sym.getName());
                          sym.setName(arg.getCallFunctionArg());
                      }
                    }

                    if (mts.getTaintedMembers().containsKey(sym.getName()) == true && mus.existSymbol(sym.getName()) == false)
                        sym.setTainted(1);                  
                  
                    if (inst != null){
                        SymbolTable t = inst.getInstanceAttributes();
                        if (t.containsSymbol(sym.getName()) || (scp.getEnclosingScope() != null && scp.getEnclosingScope().getScopeName().equals("this") && t.containsSymbol(sym.getName()))){
                            Scope scp_acc = (Scope) t.getSymbolOfListSymbols(sym.getName());
                            sym.setTainted(scp_acc.getScopeSymbol().getTainted());
                        }
                    }

                    scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                    mts.removeDuplicates(sym);


                    if (csAtt_att != null){
                        inst.updateTainted(csAtt_att, sym);
                    }

                    if (csAtt_acc != null){
                        sym.setTainted(csAtt_acc.getScopeSymbol().getTainted());
                        scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                    }

                    if (scp.getScopeSymbol().getIsSecureFunction() == false){
                        // se o scope e' tainted e e' uma funcao SQLI entao fazer correcao SQL
                        if (scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false){
                            correctVulner(scp, filename, GlobalDataXSS.MainSymbolTable, null, ms, mts, GlobalDataXSS.MainLinesToCorrect);
                        }
                                                
                    }
            }
            else{
                Scope scp1 = sym.getRootScope();
                if (scp1.getMembers().size() > 0){
                    FuncAndIncXSS css2 = new FuncAndIncXSS(scp1);
                    css2.resolveSymbolClassXSS(ms, scp1, mts, mus, filename, mtsc, inst, mct, ftime, csAtt_att, csAtt_acc, typeMeth, isClassInstruction);
                    scp.resolveSymbol(scp, sym, mts, mus, filename);
                    mts.removeDuplicates(sym);
                    return;
                }
                else{                
                ftime = false;
                
                // 1. obter instancia
                String instName = scp1.getEnclosingScope().getScopeName();
                String fileInst = scp1.getEnclosingScope().getScopeSymbol().getFileSymbol();
                InstanceTable instTable = GlobalDataXSS.MainInstancesTable.get(fileInst);
                SymbolTable st = GlobalDataXSS.MainSymbolTable.get(fileInst);
                String instName_aux = instName;
                Instance inst1 = null;
                if (st.getAliases().containsKey(instName_aux) == true)
                        instName_aux = st.getInstanceNameFromAliases(instName_aux, instTable);                
                
                if (instTable != null && instTable.containsInstance(instName_aux) == true)
                    inst1 = (Instance) instTable.getInstanceOfListInstances(instName_aux);

                // 2. obter classe
                String c_name = inst1.getInstanceClass();
                String cf_name = inst1.getFileOfClass();
                ClassTable ct = GlobalDataXSS.MainClassesTable.get(cf_name);
                ClassSymbol currentClass = ct.getClassOfListClasses(c_name);
                // 3. procurar metodo
                MethodClass mc = currentClass.getMethodClass(scp1.getScopeName(), "", mct);
                MethodSymbol mss_final = mc.getMeth();
                String mss_final_file = mc.getClassMeth().getFileClass();

                ret = null;
                ret = instanceMethod(mss_final, scp1, filename, mss_final_file, mts, mus, inst1, null, mct, "", ret, instTable, st);                

                if (ret != null && instTable.containsInstance(ret.getInstanceName()) == true){
                        Boolean a = true;
                        Scope enc_f = scp;
                        Scope enc_b;
                        while (a == true){
                                enc_b = enc_f.getEnclosingScope();
                                if (enc_b.getScopeName().equals(st.getScopeName()) == false)
                                        enc_f = enc_b;
                                else
                                        a = false;
                        }

                        Symbol sy = new Symbol(ret.getInstanceName(), ret.getTainted(), ret.getCreateLineInstance(), ret.getFileInstance());
                        sy.setIsClassInstruction(true);
                        st.getAliases().put(enc_f.getScopeName(), sy);
                        scp1.resolveSymbol(scp1, sym, mts, mus, sym.getFileSymbol());
                        mts.removeDuplicates(sym);

                        if (cs_att != null){
                                cs_att.getScopeSymbol().setTainted(ret.getTainted());
                                inst1.updateTainted(cs_att, sym);
                        }
                }            
                }
                scp.resolveSymbol(scp, sym, mts, mus, filename);
                mts.removeDuplicates(sym);         
           }
         }
         if (exit_for == true)
             break;
        }
        }
      }
    }
    }
    

    private static Instance instanceMethod(MethodSymbol ms, Scope scp, String filename, String file_methClass, TaintedTable mts, UntaintedTable mus, Instance inst, MethodSymbolCall mtsc, Map mct, String typeMeth, Instance objRet, InstanceTable instTab, SymbolTable symTab) throws IOException{          
        // ver quem e' o metodo
        String s = scp.getScopeName();
        String s1 = "", s2 = "";
        Instance ii = null, ret = null;

        //int i = -1;

        InstanceTable instances_table = null;
        if (instTab == null){
            if (typeMeth.equals("constructor") == true)
                instances_table = inst.getObjectsOfInstance();
            else
                instances_table = mtsc.getObjectsOfMethod();
        }
        else
            instances_table = instTab;

        Scope enc = scp.getEnclosingScope();
        String enc_s = enc.getScopeSymbol().getName();
        String instanceName = enc_s;
        if (enc.getScopeSymbol().getIsClassMethod() == false && objRet == null){
            // obj -> func()
            // ver se a instancia e' um clone
            if (mtsc.getAliases().containsKey(instanceName) == true){
                    instanceName = mtsc.getInstanceNameFromAliases(instanceName, instances_table);
            }

            if (instances_table.containsInstance(instanceName) == true){
                ii = (Instance) instances_table.getInstanceOfListInstances(instanceName);
                s1 = ii.getInstanceClass();
                s2 = ii.getFileOfClass();
                inst = ii;
            }
            else{
                // func() e' um metodo da instancia actual
                try{
                    s1 = inst.getInstanceClass();
                    s2 = inst.getFileOfClass();
                } catch (Exception e) {}
            }

            if (s1 != null){
                // obter classe
                ClassTable class_table = (ClassTable) mct.get(s2);
                ClassSymbol currentClass  = (ClassSymbol) class_table.getClassOfListClasses(s1);

                // obter metodo
                MethodClass mc = currentClass.getMethodClass(s, "", mct);
                MethodSymbol mss_final = mc.getMeth();
                String mss_final_file = mc.getClassMeth().getFileClass();

                /* Fazer a analise do metodo */
                if (mss_final != null){
                    MethodSymbolXSS meth_sym = new MethodSymbolXSS(mss_final);
                    int valueFinal = meth_sym.analyseMethodXSS(mss_final,scp.getScopeSymbol().getCodeLine(), scp, mts, mus, filename, mss_final_file, inst, mct, typeMeth);
                    scp.getScopeSymbol().setTainted(valueFinal);
                    ret = inst.getInstanceOfReturn(s, scp.getScopeSymbol().getCodeLine(), null, null, false);

                }
            }
        }
        else{
            // (obj -> func()) -> func()
            if (objRet != null){
                // obter classe
                s1 = objRet.getInstanceClass();
                s2 = objRet.getFileOfClass();
                ClassTable class_table = (ClassTable) mct.get(s2);
                ClassSymbol currentClass  = (ClassSymbol) class_table.getClassOfListClasses(s1);

                if (scp.getScopeSymbol().getIsClassMethod() == true){                
                    // obter metodo
                    MethodClass mc = currentClass.getMethodClass(s, "", mct);
                    MethodSymbol mss_final = mc.getMeth();
                    String mss_final_file = mc.getClassMeth().getFileClass();

                    /* Fazer a analise do metodo */
                    if (mss_final != null){
                        MethodSymbolXSS meth_sym = new MethodSymbolXSS(mss_final);
                        int valueFinal = meth_sym.analyseMethodXSS(mss_final,scp.getScopeSymbol().getCodeLine(), scp, mts, mus, filename, mss_final_file, inst, mct, typeMeth);
                        scp.getScopeSymbol().setTainted(valueFinal);
                        ret = inst.getInstanceOfReturn(s, scp.getScopeSymbol().getCodeLine(), null, null, false);
                    }
                }
                else{
                    if (scp.getScopeSymbol().getRootScope() == null){                       
                        FuncAndIncXSS css2 = new FuncAndIncXSS(scp);
                        css2.resolveSymbolClassXSS(null, scp, mts, mus, scp.getScopeSymbol().getFileSymbol(), mtsc, inst, mct, true, null, null, typeMeth, true);
                        scp.resolveSymbol(scp, (Symbol) scp.getMembers().get(0), mts, mus, scp.getScopeSymbol().getFileSymbol());
                        mts.removeDuplicates((Symbol) scp.getMembers().get(0));
                    }                
                }
            }
        }

        
        // ver se o metodo e' o ultimo a ser chamado
        Boolean endChain = true;
        Symbol sy = null;
        for (int j = 0; j < scp.getMembers().size(); j++){
            sy = (Symbol) scp.getMembers().get(j);
            if (sy.getRootScope() != null && sy.getIsParamUserFunction() == false){
                endChain = false;
                break;
            }
        }
        if (endChain == true){
            if (ret != null){
                ClassTable ct = (ClassTable) mct.get(ret.getFileOfClass());
                ClassSymbol ret_cl = (ClassSymbol) ct.getClassOfListClasses(ret.getInstanceClass());
                Instance r = new Instance(ret, ret_cl);
                instances_table.getMembers().add(r);
                scp.getScopeSymbol().setTainted(ret.getTainted());
                scp.resolveSymbol(scp, scp.getScopeSymbol(), mts, mus, scp.getScopeSymbol().getFileSymbol());
            }
        }
        else{
            ret = instanceMethod(ms, (Scope) sy, filename, file_methClass, mts, mus, inst, mtsc, mct, typeMeth, ret, instTab, symTab);
            scp.resolveSymbol(scp, sy, mts, mus, scp.getScopeSymbol().getFileSymbol());
            mts.removeDuplicates(sy);
        }

        return ret;
    }



    // Resolve symbols of include files that have yet analysed one time.
    // In this way, the include is added just one time in Scope Symtab_include
    // and on next times just need make data flow analysis to scope
    public void resolveSymbolIncludeXSS(Scope scp, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map mftt, Map MainLinesToCorrect) throws IOException{
         String filename_aux="";
        // Scope em analise e' um "include("...")"
        if (scp.getScopeName().equals("include") == true){
            Symbol s = (Symbol) scp.getMembers().get(0);
            String nameIncFile = s.getName();
            
            try{
                SymbolTable st = (SymbolTable) mift.get(nameIncFile);
                Iterator <Symbol> it = st.getMembers().iterator();
                Scope cs;
                Symbol sy;
                for(; it.hasNext();){
                    sy = it.next();
                    if (sy.getIsVariableSymbol() == false){
                        cs = (Scope) sy;
                        FuncAndIncXSS css = new FuncAndIncXSS(cs);
                        css.resolveSymbolIncludeXSS(cs, mts, mus, mift, nameIncFile, mft, mst, mftt, MainLinesToCorrect);
                    }
                }
            } catch (Exception e){} 
            //} catch (Exception e){System.out.println("File: "+ nameIncFile+" not exist");} 
        }
        else{
            if (scp.getScopeSymbol().getIsSecureFunction() == false){
                // verifica se o scope name e' uma chamada de funcao de UserFunction
                // primeiro nas funcoes definidas no file em analise
                MethodSymbolXSS mss_final = null;
                MethodSymbol mss = null;
                String mss_final_file = "";                
                if (mft.containsKey(filename) == true){
                    MethodTable mt = (MethodTable) mft.get(filename);
                    for(Iterator <MethodSymbol> it = mt.getMembers().iterator(); it.hasNext();){
                        mss = it.next();
                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                            mss_final = new MethodSymbolXSS(mss);
                            mss_final_file = filename;
                            break;
                        }
                    }
                }
                if (mss_final == null){
                    // segundo nas UserFunctions definidas nos include files do file em analise
                    SymbolTable st = (SymbolTable) mift.get(filename);
                    if (st.getIncludeFiles().isEmpty() == false){
                        String s;
                        SymbolTable st1;
                        for(Iterator <String> it = st.getIncludeFiles().iterator(); it.hasNext();){
                            s = it.next();
                            st1 = (SymbolTable) mift.get(s);
                            if(st1.getHaveFunctions() == true){
                                MethodTable mt  = (MethodTable) mft.get(s);
                                for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                    mss = it1.next();
                                    if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                        mss_final = new MethodSymbolXSS(mss);
                                        mss_final_file = s;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                if (mss_final == null && scp.getScopeSymbol().getIsFunction() == true
                      && scp.getScopeSymbol().getIsTaintedFunction() == false
                      && scp.getScopeSymbol().getFileSymbol().equals(filename) == false){
                        // terceiro nas UserFunctions definidas nos include files do file que chamou a primeira
                        // funcao. Aqui estamos 'a procura de uma 2da funcao que esta' dentro de um include nao 
                        // pertencente ao file onde ela e' chamada, mas a um file que chama a 1 funcao
                        SymbolTable st = (SymbolTable) mst.get(filename);
                        if (st.getIncludeFiles().isEmpty() == false){
                            String s;
                            SymbolTable st1;
                            for(Iterator <String> it = st.getIncludeFiles().iterator(); it.hasNext();){
                                s = it.next();
                                st1 = (SymbolTable) mift.get(s);
                                if(st1.getHaveFunctions() == true){
                                    MethodTable mt  = (MethodTable) mft.get(s);
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            //mss_final = (MethodSymbolSqli) mss;
                                            mss_final = new MethodSymbolXSS(mss);
                                            mss_final_file = s;
                                            filename_aux = filename;
                                            filename= scp.getScopeSymbol().getFileSymbol();                                          
                                            break;
                                        }
                                    }
                                }
                                if (mss_final != null)
                                    break;
                            }
                        }
                        
                        // verifica nos outros includes. Para termos a certeza que se trata ou nao de uma userFunction
                        if (mss_final == null){
                            for(Iterator <SymbolTable> itt = mift.values().iterator(); itt.hasNext();){
                                SymbolTable st1 = itt.next();
                                if(st1.getHaveFunctions() == true && st.getIncludeFiles().contains(st1.getScopeName()) == false){
                                    MethodTable mt  = (MethodTable) mft.get(st1.getScopeName());
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            //mss_final = (MethodSymbolSqli) mss;
                                            mss_final = new MethodSymbolXSS(mss);
                                            mss_final_file = st1.getScopeName();
                                            filename_aux = filename;
                                            filename= scp.getScopeSymbol().getFileSymbol();                                          
                                            break;
                                        }
                                    }
                                }
                                if (mss_final != null)
                                    break;
                            }                        
                        }
                }                
                
                
                // se mss_final != null entao o scope name e' uma Userfunction
                // Fazer entao a analise na UserFunction
                if (mss_final != null){
                    String valueFinal = mss_final.analyseUserFunctionXSS((MethodSymbol) mss_final, scp.getScopeSymbol().getCodeLine(), scp, mts, mus, filename, mss_final_file, mift, mft, mst, mftt, MainLinesToCorrect);
                    if (filename_aux.isEmpty() == false){
                        filename = filename_aux;
                        filename_aux = "";
                    }                 
                }
                else{
                Symbol sym1, sym;
                Iterator <Symbol> it = scp.getMembers().iterator();
                for(;it.hasNext();){
                    sym = it.next();
                    if (sym.getRootScope() == null){
                            if (mts.getTaintedMembers().containsKey(sym.getName()) == true && mus.existSymbol(sym.getName()) == false)
                                sym.setTainted(1);

                            scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                            mts.removeDuplicates(sym);

                            // se o scope e' tainted e e' uma funcao XSS entao fazer correcao
                            if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)){
                                correctVulner(scp, filename, mst, mift, null, mts, MainLinesToCorrect);
                            }                            
                            
                    }
                    else{
                        Scope scp1 = (Scope) sym.getRootScope();
                        FuncAndIncXSS css1 = new FuncAndIncXSS(scp1);
                        css1.resolveSymbolIncludeXSS((Scope) scp1, mts, mus, mift, filename, mft, mst, mftt, MainLinesToCorrect);
                        scp.resolveSymbol(scp, sym, mts, mus, filename);
                        mts.removeDuplicates(sym);
                        
                        if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)){
                            correctVulner(scp, filename, mst, mift, null, mts, MainLinesToCorrect);
                        }
                    }  
               }
            }
        }
      }
    }




    // Resolve symbols of function defined by user that have yet analysed one time.
    // In this way, the function is added just one time in Scope Symtab_functions
    // and on next times just need make data flow analysis to scope
    public void resolveSymbolFunctionXSS(MethodSymbol ms, Scope scp, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map mftt, Map MainLinesToCorrect) throws IOException{       
        String filename_aux="";
        if (scp.getScopeName().equals("include") == true){
            Symbol s = (Symbol) scp.getMembers().get(0);
            String nameIncFile = s.getName();
            String x = nameIncFile.substring(1,nameIncFile.length()-1);
            SymbolTable st = (SymbolTable) mift.get(x);
            Iterator <Symbol> it = st.getMembers().iterator();
            Scope cs;
            for(; it.hasNext();){
		cs = (Scope) it.next();
                FuncAndIncXSS css = new FuncAndIncXSS(cs);
                css.resolveSymbolIncludeXSS((Scope) cs, mts, mus, mift, x, mft, mst, mftt, MainLinesToCorrect);
            }
            return;
        }
            if (scp.getScopeSymbol().getIsSecureFunction() == false){
            // verifica se o scope name e' uma chamada de funcao de UserFunction
            // primeiro nas funcoes definidas no file em analise
            MethodSymbolXSS mss_final = null;
            MethodSymbol mss = null;
            String mss_final_file = "";
            if (scp.getScopeSymbol().getIsUserFunction() == true){
            if (mft.containsKey(filename) == true){
                MethodTable mt = (MethodTable) mft.get(filename);
                for(Iterator <MethodSymbol> it = mt.getMembers().iterator(); it.hasNext();){
                    mss = it.next();
                    if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                        mss_final = new MethodSymbolXSS(mss);
                        mss_final_file = filename;
                        break;
                    }
                }
            }
            if (mss_final == null){
                // segundo nas UserFunctions definidas nos include files do file em analise
                SymbolTable st = (SymbolTable) mst.get(filename);
                if (st.getIncludeFiles().isEmpty() == false){
                    String s;
                    SymbolTable st1;
                    for(Iterator <String> it = st.getIncludeFiles().iterator(); it.hasNext();){
                        s = it.next();
			st1 = (SymbolTable) mift.get(s);
			if(st1.getHaveFunctions() == true){
                            MethodTable mt  = (MethodTable) mft.get(s);
			    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
				mss = it1.next();
				if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                    mss_final = new MethodSymbolXSS(mss);
                                    mss_final_file = s;
                                    break;
				}
                            }
			}
                        if (mss_final != null)
                            break;
                    }
                }
            }
            }

                if (mss_final == null && scp.getScopeSymbol().getIsFunction() == true
                      && scp.getScopeSymbol().getIsTaintedFunction() == false
                      && scp.getScopeSymbol().getFileSymbol().equals(filename) == false){
                        // terceiro nas UserFunctions definidas nos include files do file que chamou a primeira
                        // funcao. Aqui estamos 'a procura de uma 2da funcao que esta' dentro de um include nao 
                        // pertencente ao file onde ela e' chamada, mas a um file que chama a 1 funcao
                        SymbolTable st = (SymbolTable) mst.get(filename);
                        if (st.getIncludeFiles().isEmpty() == false){
                            String s;
                            SymbolTable st1;
                            for(Iterator <String> it = st.getIncludeFiles().iterator(); it.hasNext();){
                                s = it.next();
                                st1 = (SymbolTable) mift.get(s);
                                if(st1.getHaveFunctions() == true){
                                    MethodTable mt  = (MethodTable) mft.get(s);
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            mss_final = new MethodSymbolXSS(mss);
                                            mss_final_file = s;
                                            filename_aux = filename;
                                            filename= scp.getScopeSymbol().getFileSymbol();                                          
                                            break;
                                        }
                                    }
                                }
                                if (mss_final != null)
                                    break;
                            }
                        }
                        
                        // verifica nos outros includes. Para termos a certeza que se trata ou nao de uma userFunction
                        if (mss_final == null){
                            for(Iterator <SymbolTable> itt = mift.values().iterator(); itt.hasNext();){
                                SymbolTable st1 = itt.next();
                                if(st1.getHaveFunctions() == true && st.getIncludeFiles().contains(st1.getScopeName()) == false){
                                    MethodTable mt  = (MethodTable) mft.get(st1.getScopeName());
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            mss_final = new MethodSymbolXSS(mss);
                                            mss_final_file = st1.getScopeName();
                                            filename_aux = filename;
                                            filename= scp.getScopeSymbol().getFileSymbol();                                          
                                            break;
                                        }
                                    }
                                }
                                if (mss_final != null)
                                    break;
                            }                        
                        }
                }            
            

            // Fazer entao a analise na UserFunction
            if (mss_final != null){
                String valueFinal = mss_final.analyseUserFunctionXSS(mss, scp.getScopeSymbol().getCodeLine(), scp, mts, mus, filename, mss_final_file, mift, mft, mst, mftt, MainLinesToCorrect);
                if (filename_aux.isEmpty() == false){
                    filename = filename_aux;
                    filename_aux = "";
                }
            }
            else{
            Symbol sym1, sym;           
            
            // Se o nome do scope for o nome de argumento da chamada da funcao entao o nome do scope muda para ele
            if(ms.getArgsFunction().containsKey(scp.getScopeName()) == true){
                ArgFunctionSymbol arg = (ArgFunctionSymbol) ms.getArgsFunction().get(scp.getScopeName());
                scp.getScopeSymbol().setName(arg.getCallFunctionArg());
                return;
            }
                       
            Iterator <Symbol> it = scp.getMembers().iterator();
            for(;it.hasNext();){
                    sym = it.next();
                    if (sym.getRootScope() == null){
                            if (ms.getArgsFunction().containsKey(sym.getName()) == true){
                                ArgFunctionSymbol arg = (ArgFunctionSymbol) ms.getArgsFunction().get(sym.getName());
                                sym.setName(arg.getCallFunctionArg());
                            }
                            
                            if (mts.getTaintedMembers().containsKey(sym.getName()) == true && mus.existSymbol(sym.getName()) == false)
                                sym.setTainted(1);
                            
                            scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                            mts.removeDuplicates(sym);

                            // se o scope e' tainted e e' uma funcao XSS entao fazer correcao
                                if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)){
                                    correctVulner(scp, filename, mst, null, ms, mts, MainLinesToCorrect);
                                }
                            
                    }
                    else{
                        Scope scp1 = sym.getRootScope();
                        FuncAndIncXSS css1 = new FuncAndIncXSS(scp1);
                        css1.resolveSymbolFunctionXSS(ms, scp1, mts, mus, mift, filename, mft, mst, mftt, MainLinesToCorrect);
                        scp.resolveSymbol(scp, sym, mts, mus, filename);
                        mts.removeDuplicates(sym);
                        
                        if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)){
                            correctVulner(scp, filename, mst, null, ms, mts, MainLinesToCorrect);
                        }
                    }
            }              
            
            Scope aux = scp.getScopeSymbol().getRootScope();
            if (aux.getScopeName().equals("return") == true && aux.getScopeSymbol().getTainted() == 1){
                ms.getScopeSymbol().setTainted(1);
     
                //inserir ms como dependente do return
                RootTaintedSymbol Rrt;
                Rrt = (RootTaintedSymbol) mts.getTaintedMembers().get("return");
                RelatedTaintedSymbol rtt;
                rtt =   (RelatedTaintedSymbol) Rrt.getListTaintedMembers().get(Rrt.getListTaintedMembers().size()-1);
                // Caso o ms nao pertenca 'a lista da funcao tainted
                if (rtt.getTaintedMembers().containsKey(ms.getScopeName()) == false){
                    VariableTaintedSymbol var = new VariableTaintedSymbol(ms.getScopeName(),
                                                ms.getScopeSymbol().getCodeLine(), ms.getScopeSymbol().getTainted(),
                                                ms.getScopeSymbol().getFileSymbol());
                    rtt.define(var);
                }
                else{
                    VariableTaintedSymbol var = (VariableTaintedSymbol) rtt.getTaintedMembers().get(ms.getScopeName());
                    var.InsertLine(ms.getScopeSymbol().getCodeLine());
                    var.InsertFile(ms.getScopeSymbol().getFileSymbol());
                }
            }
        }
      }
}

    // Resolve symbols of SymbolTable.
    public void resolveSymbolXSS(Scope scp, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map mftt, Map MainLinesToCorrect, Map mct, Map mobjt) throws IOException{
        if (scp.getScopeName().equals("include")){
            try{
                this.resolveSymbolIncludeXSS(scp, mts, mus, mift, filename, mft, mst, mftt, MainLinesToCorrect);
            } catch (Exception e){
                //System.out.println("Error processing include file: "+this.getName());
            }
            return;
        }
        
        if (scp.getScopeSymbol().getIsSecureFunction() == false){
            if (scp.getScopeSymbol().getIsUserFunction() == true){
                try{
                    this.resolveSymbolFunctionXSS(null, scp, mts, mus, mift, filename, mft, mst, mftt, MainLinesToCorrect);
                } catch (Exception e){
                //System.out.println("Error processing include file: "+this.getName());
                }
                return;
            }

            if(scp.getScopeSymbol().getIsClassInstruction() == true){
                try{
                    this.resolveSymbolClassXSS(null, scp, mts, mus, filename, null, null, mct, true, null, null, filename, true);
                } catch (Exception e){
                //System.out.println("Error processing include file: "+this.getName());
                }
                return;
            }

                     
            // Analise de scope normal
            Symbol sym1, sym;
            Iterator <Symbol> it = scp.getMembers().iterator();
            for(;it.hasNext();){
                sym = it.next();
                if (sym.getRootScope() == null){
                    if (mts.getTaintedMembers().containsKey(sym.getName()) == true && mus.existSymbol(sym.getName()) == false)
                        sym.setTainted(1);

                    scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                    mts.removeDuplicates(sym);

                    // se o scope e' tainted e e' uma funcao SQLI entao fazer correcao XSS
                    if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)){
                            correctVulner(scp, filename, mst, null, null, mts, MainLinesToCorrect);
                    }                     
                }
                else{
                    Scope scp1 = (Scope) sym.getRootScope();
                    FuncAndIncXSS css1 = new FuncAndIncXSS(scp1);
                    css1.resolveSymbolXSS(sym.getRootScope(), mts, mus, mift, filename, mft, mst, mftt, MainLinesToCorrect, mct, mobjt);
                    scp.resolveSymbol(scp, sym, mts, mus, filename);
                    mts.removeDuplicates(sym);
                    
                    // se o scope e' tainted e e' uma funcao SQLI entao fazer correcao XSS
                    if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)){
                            correctVulner(scp, filename, mst, null, null, mts, MainLinesToCorrect);
                    }
                }
           }            
        }
    }
    
private void correctVulner(Scope scp, String filename, Map mst, Map mift, MethodSymbol ms, TaintedTable mts, Map MainLinesToCorrect) throws IOException{        
        scp.getScopeSymbol().setIsVulDetected(true);
        SymbolTable currentSymbolTable = new SymbolTable(scp.getScopeSymbol().getFileSymbol());
        SymbolTable ct;          
        
        int m = 0;
        if (mift == null || mift.size() == 0)
            m = 0;

        if (ms == null){
            if (m == 0){
                ct = (SymbolTable) mst.get(scp.getScopeSymbol().getFileSymbol());
                currentSymbolTable.setAllSymbols(ct.getMembers());
                currentSymbolTable.setAllIncludeFiles(ct.getIncludeFiles());
            }
            else{    
                ct = (SymbolTable) mift.get(scp.getScopeSymbol().getFileSymbol());
                currentSymbolTable.setAllSymbols(ct.getMembers());
                currentSymbolTable.setAllIncludeFiles(ct.getIncludeFiles());
            }
        }
        else
            currentSymbolTable.setAllSymbols(ms.getMembers());
        VulnerabilityPathXSS vvp = new VulnerabilityPathXSS(scp);


/* **************
* CORRECAO e DM
*/                        
        VulnerXSS vv = vvp.collectVulnPathXSS(GlobalDataXSS.UserInput, mts, currentSymbolTable, false, MainLinesToCorrect);

        /*
                DATA MINING
        */

        int fp = vv.getVectorAttributesOfVulner().predictFalsePositive(true);
        vv.setIsFP(fp);          

        if (GlobalDataXSS.MainNumFP.containsKey(vv.getFileOf_SS()) == false)
            GlobalDataXSS.MainNumFP.put(vv.getFileOf_SS(), 0);

        if (GlobalDataXSS.MainNumVul.containsKey(vv.getFileOf_SS()) == false)
            GlobalDataXSS.MainNumVul.put(vv.getFileOf_SS(), 0);            

        //try{
        if (vv.IsFP() == 1){                          
            int nFP = GlobalDataXSS.MainNumFP.get(vv.getFileOf_SS()) + 1;
            GlobalDataXSS.MainNumFP.put(vv.getFileOf_SS(), nFP);                            
        }
        else{
            if (scp.getScopeSymbol().getTainted() == 1){                     
                int nVul = GlobalDataXSS.MainNumVul.get(vv.getFileOf_SS()) + 1;
                GlobalDataXSS.MainNumVul.put(vv.getFileOf_SS(), nVul);
            }

            /* Correccao */
            AutoCorrectXSS acs = new AutoCorrectXSS(vv);
            acs.buildCorrect(MainLinesToCorrect);
        }
        //} catch (Exception e) {}



        GlobalDataXSS.currentVulner = null;            
    //}
    }        
    
    @Override
    public List<Symbol> getMembers() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void print(Scope scp) {
        throw new UnsupportedOperationException("Not supported yet.");
    }




} public class GlobalDataXSS {
    // user input
    private final static String UserInputs[] = {"_GET", "_POST", "_COOKIE", "_REQUEST", "HTTP_GET_VARS", "HTTP_POST_VARS",
                                                "HTTP_COOKIE_VARS", "HTTP_REQUEST_VARS", "_FILES", "_SERVER"};
    public static List<String> UserInput = Arrays.asList(UserInputs);

    // functions where can occur XSS Reflected and Stored
    private final static String XSSTaintFunctions[] = {"echo", "print", "printf", "file_get_contents", "file_put_contents",
                                                        "fprintf", "fgets", "fgetc", "fscanf", "die", "exit", "error"};
    public static List<String> XSSFunctions = Arrays.asList(XSSTaintFunctions);
   
    // functions that make secure the user input
    //private final static String SecureFunctions[] = {"htmlentities", "htmlspecialchars", "strip_tags", "urlencode",
    //                                                  "san_out", "san_rdata", "san_wdata"};
    private final static String SecureFunctions[] = {};    
    public static List<String> XSSSecFunctions = Arrays.asList(SecureFunctions);

    // create main Tables
    public static Map <String, SymbolTable> MainSymbolTable = new LinkedHashMap<String, SymbolTable>();
    public static Map <String, SymbolTable> MainIncludeFilesTable = new LinkedHashMap<String, SymbolTable>();
    public static Map <String, MethodTable> MainFunctionsTable = new LinkedHashMap<String, MethodTable>();
    public static Map <String, MethodTableCalls> MainFunctionsCallsTable = new LinkedHashMap<String, MethodTableCalls>();
    public static Map <String, ClassTable> MainClassesTable = new LinkedHashMap<String, ClassTable>();
    public static Map <String, InstanceTable> MainInstancesTable = new LinkedHashMap<String, InstanceTable>();
    public static Map <String, TaintedTable> MainTaintedTable = new LinkedHashMap<String, TaintedTable>();
    public static Map <String, MethodTaintedTable> MainFunctionsTaintedTable = new LinkedHashMap<String, MethodTaintedTable>();
    public static UntaintedTable mus = new UntaintedTable();
    public static Map <String, LinesToCorrect> MainLinesToCorrect = new LinkedHashMap<String, LinesToCorrect>();
    public static Map <String, Integer> MainNumVul = new LinkedHashMap<String, Integer>();
    public static Map <String, ListVulners> MainListVulners = new LinkedHashMap<String, ListVulners>();
    public static VulnerXSS currentVulner = null;
    public static Map <String, Integer> MainNumFP = new LinkedHashMap<String, Integer>();
    
    /*
     * Verify if symbol name contain tainted input
     */
    public static String containsInput(String f){
        //Verificar se f tem UserInput
        String found = "";
        for (String aux : GlobalDataXSS.UserInput){
                if (f.contains(aux) == true){
                    //found = aux;
                    return aux;
                }
        }
        return found;
    }
    
    /*
     * Returns the number of real vulnerabilities detected
     */    
    public static int getNumVul(){
        int j, vuu=0;
        for(Iterator <Integer> it = GlobalDataXSS.MainNumVul.values().iterator(); it.hasNext(); ){
            j = it.next();
            vuu += j;
        }
        return vuu;
    }    

    /*
     * Returns the number of false positives detected
     */    
    public static int getNumFP(){
        int j, fpp=0;
        for(Iterator <Integer> it = GlobalDataXSS.MainNumFP.values().iterator(); it.hasNext(); ){
            j = it.next();
            fpp += j;
        }
        return fpp;
    }     
} public class OutputAnalysisXSS {

    //public static void outputAnalysisWithCorrection (String type_analyse, String filename) throws IOException{
    public static void outputAnalysisWithCorrection (String type_analyse, String filename, LinesToCorrect ltc, int num_file) throws IOException{    
        FileWriter out_FileOfPaths;
        File dir = null;
        BufferedWriter bufferWritter = null;
        Date date = new Date(System.currentTimeMillis());
        int i = GlobalDataXSS.MainLinesToCorrect.size();

        if (type_analyse.equals("project") == true){
            dir = new File(System.getProperty("base.dir") + File.separator + "NewFiles");
            
            // Se ja houve analises anteriores apaga dir
            if (GlobalDataApp.numAnalysis == 0 && dir.exists() == true && num_file == i){
                ManageFiles r = new ManageFiles(dir.toString());
                r.deleteDir(dir);
                GlobalDataApp.numAnalysis++;
            }
            
            //Criar directorio para colocar fichs corrigidos
            if (dir.exists() == false)
                dir.mkdir();
            // cria ficheiro que contem a path dos ficheiros que serao corrigidos
            File fileOfPaths = new File(dir+ File.separator +"PathNewFiles.txt");
            if (fileOfPaths.exists() == true)
                out_FileOfPaths = new FileWriter(fileOfPaths, true);
            else
                out_FileOfPaths = new FileWriter(fileOfPaths);
            bufferWritter = new BufferedWriter(out_FileOfPaths);
        }

        // Escrever Ficheiro corrigido

           // LinesToCorrect ltc = GlobalDataXSS.MainLinesToCorrect.get(filename);            
            String file = ltc.getNameFile();
            ManageFiles relativeFile = new ManageFiles(file);

            if (type_analyse.equals("single_file") == true || type_analyse.equals("files") == true){
                File baseDir = relativeFile.getBaseDir();
                dir = new File(baseDir + File.separator + "NewFiles");
                
                // Se ja houve analises anteriores apaga dir
                if (GlobalDataApp.numAnalysis == 0 && dir.exists() == true && num_file == i){
                    ManageFiles r = new ManageFiles(dir.toString());
                    r.deleteDir(dir);
                    GlobalDataApp.numAnalysis++;
                }
                
                //Criar directorio para colocar fichs corrigidos
                File fileOfPaths = new File(dir+ File.separator +"PathNewFiles.txt");
                if (dir.exists() == false)
                    dir.mkdir();

                if (fileOfPaths.exists() == true)
                    out_FileOfPaths = new FileWriter(fileOfPaths, true);
                else
                    out_FileOfPaths = new FileWriter(fileOfPaths);

    	        bufferWritter = new BufferedWriter(out_FileOfPaths);
            }


            if (ltc.getMapLinesToCorrect().isEmpty() == false){
                File ff = new File(dir+ File.separator + file);
                File in = null, out = null, temp = null, inn = null;                
                if (ff.exists() == false){          
                    bufferWritter.write(date + " " + file + "\n");
                    in = new File(file);
                    try{
                        int ind = file.lastIndexOf(File.separator);
                        String s = file.substring(0, ind);
                        File d = new File(dir + File.separator + s);
                        d.mkdirs();   
                        out = new File(ff.toString());
                    } catch (Exception e) {}
                }
                else{
                    inn = new File(ff.toString());
                    temp = new File(ff.toString() + "temp");
                    inn.renameTo(temp);
                    in = new File(temp.toString());
                    out = new File(dir+ File.separator + file);
                }

                Scanner fscanner = new Scanner(in);
                FileWriter outFinalFile = new FileWriter(out);

                Map sortedMap = new TreeMap(ltc.getMapLinesToCorrect());
                Set a = sortedMap.keySet();
                String codeLine;
                int line = 0;
                Boolean foundFirst = false;
                for (Object key : a) {
                    for (int j = line+1; j < (Integer)key; j++){
                        codeLine = fscanner.nextLine();
                        outFinalFile.write(codeLine+"\n");
//                        if(codeLine.contains("<?php") && foundFirst == false){
//                            foundFirst = true;
//                            outFinalFile.write("include(\"includes_awap" + File.separator + "awap_XSS.php\");" + "\n");
//                        }
                    }
                    codeLine = fscanner.nextLine();
                    outFinalFile.write(sortedMap.get(key).toString()+"\n");
                    line = (Integer)key;
                }

                while (fscanner.hasNextLine()){
                    codeLine = fscanner.nextLine();
                    outFinalFile.write(codeLine+"\n");
                }
                fscanner.close();
                outFinalFile.close();
                
                if (inn != null && inn.exists())
                    inn.delete();

                if (type_analyse.equals("single_file") == true || type_analyse.equals("files") == true)
                    bufferWritter.close();
            }
        //}
        if (type_analyse.equals("project") == true)
            bufferWritter.close();
    }


    public static void outputAnalysis(String type_analyse, FileWriter outFile, String diff_date_xss, List files) throws IOException{
        int vuu = GlobalDataXSS.getNumVul(), fpp = GlobalDataXSS.getNumFP();
        /*
        for(Iterator <Integer> it = GlobalDataXSS.MainNumVul.values().iterator(); it.hasNext(); ){
            Integer j = it.next();
            vuu += j;
        }
        
        for(Iterator <Integer> it = GlobalDataXSS.MainNumFP.values().iterator(); it.hasNext(); ){
            Integer j = it.next();
            fpp += j;
        }        
        */
        
        String setPlainText = "";
        String setBoldText = "";
        if (GlobalDataApp.isWindows.booleanValue() == false){
            setPlainText = "\033[0;0m";
            setBoldText = "\033[0;1m";
        }
        
        System.out.println(setBoldText +"\n\n+ + + Type of Analysis: XSS");
        System.out.println("     > Summary:" + setPlainText);
        
        if(GlobalDataApp.args_flags[4] == 1){
            outFile.write("\n\n  + Type of Analysis: XSS\n");
            outFile.write("     > Summary:\n");
        }
        
        if (vuu+fpp > 0){
            System.out.println("        - Time of analysis: " + diff_date_xss);
            System.out.println("        - Number of vulnerabilities detected: " + setBoldText + (vuu+fpp) + setPlainText);
            System.out.println("           - Real vulnerabilities: " + setBoldText + vuu + setPlainText);
            System.out.println("           - False positives: " + setBoldText + fpp + setPlainText);
            System.out.println("        - Number of vulnerable files: " +
                    setBoldText + GlobalDataXSS.MainListVulners.size() + setPlainText);
            System.out.println("        - List of vulnerable files:");
            
            if(GlobalDataApp.args_flags[4] == 1){
                outFile.write("        - Time of analysis: " + diff_date_xss+"\n");
                outFile.write("        - Number of vulnerabilities detected: " + (vuu+fpp)+"\n");
                outFile.write("           - Real vulnerabilities: " + vuu+"\n");
                outFile.write("           - False positives: " + fpp+"\n");
                outFile.write("        - Number of vulnerable files: " + GlobalDataXSS.MainListVulners.size()+"\n");
                outFile.write("        - List of vulnerable files:\n");
            }

            for(Iterator <ListVulners> it = GlobalDataXSS.MainListVulners.values().iterator(); it.hasNext(); ){
                ListVulners lv = it.next();
                System.out.println("\t    " + lv.getFilename());
                
                if(GlobalDataApp.args_flags[4] == 1){
                    outFile.write("\t    " + lv.getFilename()+"\n");
                }
            }

            if (GlobalDataApp.args_flags[5] == 0){
                // code needed for keyboard input
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                String temp;
                System.out.println("\n\nPress enter to view vulnerabilities...");
                temp = br.readLine();
            }
        }
        else{
            System.out.println("        - Time of analysis: " + diff_date_xss);
            System.out.println("        - Number of vulnerabilities detected: "  + setBoldText +"none" + setPlainText);
            if(GlobalDataApp.args_flags[4] == 1){
                outFile.write("        - Time of analysis: " + diff_date_xss +"\n");
                outFile.write("        - Number of vulnerabilities detected: none\n");
            }
            
            return;            
        }      
        
        
        ListVulners lv = null;
        for (Iterator <ListVulners> it = GlobalDataXSS.MainListVulners.values().iterator(); it.hasNext();){
            lv = it.next();
            if (GlobalDataApp.args_flags[5] == 0){
                String file = lv.getFilename();               
                ManageFiles ff = new ManageFiles (file);
                System.out.println(setBoldText + "\n> > > >  File: " + setPlainText + file + 
                        setBoldText + " < < < <" + setPlainText);
                System.out.println(setBoldText + "     > Information:" + setPlainText);
                System.out.println("        - Number of Lines of Code: " + ff.getNumberLinesFile());            

                if(GlobalDataApp.args_flags[4] == 1){
                    outFile.write("\n> > > >  File: " + file + " < < < <\n");
                    outFile.write("     > Information:\n");
                    outFile.write("        - Number of Lines of Code: " + ff.getNumberLinesFile()+"\n");
                }

                // is a include file?
                if (GlobalDataXSS.MainIncludeFilesTable.containsKey(file) == true){
                    System.out.println("        - Is a include file: yes");

                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Is a include file: yes\n");
                    }
                }
                else{
                    System.out.println("        - Is a include file: no");

                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Is a include file: no\n");
                    }
                }

                // list of included files from "regular" or include file
                SymbolTable st = null;
                if (GlobalDataXSS.MainSymbolTable.containsKey(file) == true)
                    st = GlobalDataXSS.MainSymbolTable.get(file);
                else
                    st = GlobalDataXSS.MainIncludeFilesTable.get(file);

                if(st.getIncludeFiles().isEmpty() == false){
                    System.out.println("        - Included files:");
                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Included files:\n");
                    }

                    for (int i = 0; i < st.getIncludeFiles().size(); i++){
                        System.out.println("\t    "+st.getIncludeFiles().get(i));

                        if(GlobalDataApp.args_flags[4] == 1){
                            outFile.write("\t    "+st.getIncludeFiles().get(i)+"\n");
                        }
                    }
                }
                else{
                    System.out.println("        - Included files: none");

                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Included files: none\n");
                    }
                }


                // list of defined user functioms
                if (GlobalDataXSS.MainFunctionsTable.containsKey(file) == true){
                    MethodTable mt = GlobalDataXSS.MainFunctionsTable.get(file);
                    System.out.println("        - Defined user functions:");
                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Defined user functions:\n");
                    }

                    for (Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext(); ){    
                        MethodSymbol ms = it1.next();
                        System.out.println("\t  "+ms.getFunctionName());
                        if(GlobalDataApp.args_flags[4] == 1){
                            outFile.write("\t  "+ms.getFunctionName()+"\n");
                        }
                    }
                }
                else{
                    System.out.println("        - Defined user function: none");
                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Defined user function: none\n");
                    }
                }

                // list of vulnerabilities of file
                VulnerXSS v;
                int vuu_f = lv.getListOfVulners().size();
                int fpp_f = 0;
                for (Iterator <VulnerXSS> it1 = lv.getListOfVulners().iterator(); it1.hasNext();){
                    v = it1.next();
                    if (v.IsFP() == 1)
                        fpp_f++;
                }
                vuu_f -= fpp_f;                
                
                System.out.println("        - Number of Vulnerabilities detected: " +
                        setBoldText + lv.getListOfVulners().size() + setPlainText); 
                System.out.println("           - Real Vulnerabilities: " +
                        setBoldText + vuu_f + setPlainText);
                System.out.println("           - False positives: " +
                        setBoldText + fpp_f + setPlainText);
                if(GlobalDataApp.args_flags[4] == 1){
                    outFile.write("        - Number of Vulnerabilities detected: "+lv.getListOfVulners().size()+"\n");
                    outFile.write("           - Real Vulnerabilities: "+vuu_f+"\n");
                    outFile.write("           - False positives: "+fpp_f+"\n");
                }

                analysisOfFile(lv, outFile, file.toString());
                if (it.hasNext() && GlobalDataApp.args_flags[0] == 1){
                    // code needed for keyboard input
                    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                    String temp;
                    System.out.println("\n\nPress enterGlobalDataSqli to view vulnerabilities of next file...");
                    temp = br.readLine();
                }
            }
        }
            
            
            if(GlobalDataApp.args_flags[0] == 0 && vuu > 0){
                // code needed for keyboard input
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                String temp;

                System.out.println("\n\nPress enter to proceed automatic correction...");
                temp = br.readLine();

            try{    
            LinesToCorrect ltc;
            int i = GlobalDataXSS.MainLinesToCorrect.size();
            for (Iterator <LinesToCorrect> it1 = GlobalDataXSS.MainLinesToCorrect.values().iterator(); it1.hasNext();){
                ltc = it1.next();
                OutputAnalysisXSS.outputAnalysisWithCorrection(type_analyse, ltc.getNameFile(), ltc, i);
                i--;
            }
            } catch (Exception e){}
               
                //OutputAnalysisXSS.outputAnalysisWithCorrection(type_analyse, lv.getFilename());
                
                
                System.out.println("\n\nAutomatic correction complete !!!");
                if(GlobalDataApp.args_flags[4] == 1){
                    outFile.write("\n\nAutomatic correction complete !!!\n");
                }
            }

        //}

/*        
        // Renomear os files file.php_ori para os originais
        for(Iterator <String> it1 = files.iterator(); it1.hasNext(); ){
            String aux = it1.next();
            File ori = new File(aux + "_ori");
            File temp = new File(aux);
            ori.renameTo(temp);
        }
         * 
         */
    }

    private static void analysisOfFile(ListVulners lv, FileWriter outFile, String filename) throws IOException{
        VulnerXSS v;
        String cl, correctedCode = "", aux = "";
        Iterator <VulnerXSS> it;
        int i=0;
        LinesToCorrect ltc;
        Object key;
        
        String setPlainText = "";
        String setBoldText = "";
        if (GlobalDataApp.isWindows.booleanValue() == false){
            setPlainText = "\033[0;0m";
            setBoldText = "\033[0;1m";
        }
        
        //ltc = GlobalDataXSS.MainLinesToCorrect.get(filename);
        //Map sortedMap = new TreeMap(ltc.getMapLinesToCorrect());


        for (it = lv.getListOfVulners().iterator(); it.hasNext();){
            v = it.next();
            if (v.IsFP() == 0)
                System.out.println(setBoldText + "\n\t= = = =  Vulnerability n.: " + (i+1) + "  = = = =");
            else
                System.out.println(setBoldText + "\n\t= = = =  Vulnerability n.: " + (i+1) + "   >>> is a possible False Positive <<<  = = = =");
            System.out.println("\tVulnerable code:" + setPlainText);
            if(GlobalDataApp.args_flags[4] == 1){
                if (v.IsFP() == 0)
                    outFile.write("\n\t= = = =  Vulnerability n.: " + (i+1) + "  = = = =\n");
                else
                    outFile.write("\n\t= = = =  Vulnerability n.: " + (i+1) + "   >>> is a possible False Positive <<<  = = = =\n");
                outFile.write("\tVulnerable code:\n");
            }
            i++;

            try{
            // escrever vulnerabilidade no ecra
            String f;
            correctedCode = "";
            for (int l = v.getLinesOfVulner().size() -1; l >= 0; l--){
                f = "";
                if (v.getFilesOfVulner().get(l).equals(lv.getFilename()) == false)
                    f = (String) v.getFilesOfVulner().get(l);

                ManageFiles fff = new ManageFiles ((String) v.getFilesOfVulner().get(l));
                cl = fff.getLineOfCode((Integer) v.getLinesOfVulner().get(l));
                System.out.println("\t" + v.getLinesOfVulner().get(l) + ": "+ cl);
                if(GlobalDataApp.args_flags[4] == 1){
                    outFile.write("\t" + v.getLinesOfVulner().get(l) + ": "+ cl+"\n");
                }
                if (f.equals("") == false){
                    System.out.println("\t    (" + f + ")");
                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("\t    (" + f + ")\n");
                    }
                }
                

                if (v.IsFP() == 0){
                    // escrita do corrected code no ecra
                    ltc = GlobalDataXSS.MainLinesToCorrect.get(v.getFileOfLineToSanitize());
                    Map sortedMap = new TreeMap(ltc.getMapLinesToCorrect());                
                    if (ltc.getMapLinesToCorrect().containsKey(v.getLinesOfVulner().get(l)) == true){
                        key = v.getLinesOfVulner().get(l);
                        aux =  "\t" + (Integer)key + ": " + sortedMap.get(key).toString()+"\n";
                    }
                    else
                        aux =  "\t" + v.getLinesOfVulner().get(l) + ": "+ cl + "\n";
                    correctedCode = correctedCode + aux;
                }  
            }
        }catch (Exception e){
            aux = "\tSome unexpected error in analysis happened. Sorry :-(";
            correctedCode = correctedCode + aux;
        }            

        if (v.IsFP() == 0){
            System.out.println(setBoldText + "\n\tCorrected code:" + setPlainText);
            System.out.println(correctedCode);
            if(GlobalDataApp.args_flags[4] == 1)
                outFile.write("\n\tCorrected code:\n" + correctedCode);
        }
        else{
            String justifyFP = v.getJustificationOfFP();
            System.out.println(setBoldText + "\n\tFalse Positive justification:" + setPlainText);
            System.out.println(justifyFP);
            if(GlobalDataApp.args_flags[4] == 1)
                outFile.write("\n\tFalse Positive justification:\n" + justifyFP); 
        }            
        }
    }

} public class buildWalkerTree_XSS {
       
    // *** CONSTRUCTORS
    public buildWalkerTree_XSS(CommonTreeNodeStream nodes, String filename, Map mst, Map mift, Map mft, Map mftt, Map mtt, UntaintedTable mus, Map mlct, Map mct, Map mobjt, List files) throws IOException {
        try {
            // Navegate into AST by walker tree
            XSS def = new XSS(nodes, mst, mift, mft, mftt, mtt, mus, mlct, mct, mobjt, filename, files);
            XSS.prog_return prog = def.prog();
        } catch (RecognitionException ex) {
           Logger.getLogger(buildWalkerTree_sqli.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception e) {}

    }

} public class GlobalDataCodeInj {
    // user input
    private final static String UserInputs[] = {"_GET", "_POST", "_COOKIE", "_REQUEST", "HTTP_GET_VARS", "HTTP_POST_VARS", "HTTP_COOKIE_VARS", "HTTP_REQUEST_VARS", "_FILES"};
    public static List<String> UserInput = Arrays.asList(UserInputs);

    // functions where can occur RFI/LFI/DT
    // readfile can occur Source-code disclosure, too
    private final static String RFITaintFunctions[] = {"readfile", "highlight_file", "fopen", "file_get_contents", "file", "copy", 
    "unlink", "move_uploaded_file", "imagecreatefromgd2", "imagecreatefromgd2part", "imagecreatefromgd",
    "imagecreatefromgif", "imagecreatefromjpeg", "imagecreatefrompng", "imagecreatefromstring", "imagecreatefromwbmp",
    "imagecreatefromxbm", "imagecreatefromxpm", "require", "require_once", "include", "include_once"};
    public static List<String> RFIFunctions = Arrays.asList(RFITaintFunctions);
     
    // functions where can occur OS command injection
    private final static String OSTaintFunctions[] = {"passthru", "system", "shell_exec", "exec", "pcntl_exec", 
    "popen", "proc_open"};
    public static List<String> OSFunctions = Arrays.asList(OSTaintFunctions);

    // functions where can occur Eval-injection
    private final static String EvalTaintFunctions[] = {"eval", "preg_replace"};
    public static List<String> EvalFunctions = Arrays.asList(EvalTaintFunctions);

    // WAP sanitizations functions - fixes
    private final static String FixesFunctions[] = {"san_mix", "san_osci", "san_eval"};
    public static List<String> CInjSecFunctions = Arrays.asList(FixesFunctions);    
    
    

    // create main Tables
    public static Map <String, SymbolTable> MainSymbolTable = new LinkedHashMap<String, SymbolTable>();
    public static Map <String, SymbolTable> MainIncludeFilesTable = new LinkedHashMap<String, SymbolTable>();
    public static Map <String, MethodTable> MainFunctionsTable = new LinkedHashMap<String, MethodTable>();
    public static Map <String, MethodTableCalls> MainFunctionsCallsTable = new LinkedHashMap<String, MethodTableCalls>();
    public static Map <String, ClassTable> MainClassesTable = new LinkedHashMap<String, ClassTable>();
    public static Map <String, InstanceTable> MainInstancesTable = new LinkedHashMap<String, InstanceTable>();
    public static Map <String, TaintedTable> MainTaintedTable = new LinkedHashMap<String, TaintedTable>();
    public static Map <String, MethodTaintedTable> MainFunctionsTaintedTable = new LinkedHashMap<String, MethodTaintedTable>();
    public static UntaintedTable mus = new UntaintedTable();
    public static Map <String, LinesToCorrect> MainLinesToCorrect = new LinkedHashMap<String, LinesToCorrect>();
    public static Map <String, Integer> MainNumVul = new LinkedHashMap<String, Integer>();
    public static Map <String, ListVulners> MainListVulners = new LinkedHashMap<String, ListVulners>();
    public static Vulner currentVulner = null;
    public static Map <String, Integer> MainNumFP = new LinkedHashMap<String, Integer>();
    
    /*
     * Verify if symbol name contain tainted input
     */
    public static String containsInput(String f){
        //Verificar se f tem UserInput
        String found = "";
        for (String aux : GlobalDataCodeInj.UserInput){
                if (f.contains(aux) == true){
                    return aux;
                }
        }
        return found;
    }
    
    public static String getTypeVulInjection(String function){
        if (function.equals("readfile") == true || function.equals("highlight_file") == true)
            return "Source Code Discloser";
        else
            if (function.equals("eval") == true || function.equals("preg_replace") == true)
                return "PHP Code Injection";
            else
                if (GlobalDataCodeInj.OSFunctions.contains(function))
                    return "OS Command Injection";
                else
                    return "RFI, LFI, DT";
    }
    
    /*
     * Returns the number of real vulnerabilities detected
     */    
    public static int getNumVul(){
        int j, vuu=0;
        for(Iterator <Integer> it = GlobalDataCodeInj.MainNumVul.values().iterator(); it.hasNext(); ){
            j = it.next();
            vuu += j;
        }
        return vuu;
    }    

    /*
     * Returns the number of false positives detected
     */    
    public static int getNumFP(){
        int j, fpp=0;
        for(Iterator <Integer> it = GlobalDataCodeInj.MainNumFP.values().iterator(); it.hasNext(); ){
            j = it.next();
            fpp += j;
        }
        return fpp;
    }    
} public class buildWalkerTree_CodeInj {
       
    // *** CONSTRUCTORS
    public buildWalkerTree_CodeInj(CommonTreeNodeStream nodes, String filename, Map mst, Map mift, Map mft, Map mftt, Map mtt, UntaintedTable mus, Map mlct, Map mct, Map mobjt, List files) throws IOException {
        try {
            // Navegate into AST by walker tree
            CodeInjection def = new CodeInjection(nodes, mst, mift, mft, mftt, mtt, mus, mlct, mct, mobjt, filename, files);
            CodeInjection.prog_return prog = def.prog();
        } catch (RecognitionException ex) {
            Logger.getLogger(buildWalkerTree_sqli.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception e) {}

    }

} public class FuncAndIncCodeInj extends ScopedSymbol{    

    // *** CONSTRUCTORS
    public FuncAndIncCodeInj(Scope scp) {
        super(scp.getScopeSymbol().getName(), scp.getScopeSymbol().getCodeLine(), scp.getScopeSymbol().getTainted(), scp.getEnclosingScope(), scp.getScopeSymbol().getFileSymbol());   
    }
   

    // *** METHODS
    public void resolveSymbolClassCodeInj(MethodSymbol ms, Scope scp, TaintedTable mts, UntaintedTable mus, String filename, MethodSymbolCall mtsc, Instance inst, Map mct, Boolean ftime, Scope cs_att, Scope cs_acc, String typeMeth, Boolean isClassInstruction) throws IOException{
    if (scp.getScopeSymbol().getIsSecureFunction() == false){
    Scope csAtt_acc = cs_att;
    Scope csAtt_att = cs_acc;
    String s = scp.getScopeName();
    Instance ret = null;
    Boolean exit_for = false;
    
    if (inst != null){
    SymbolTable t = inst.getInstanceAttributes();

    //pegar no atributo do objecto numa atribuicao ou acesso
    //if (t.getMembers().contains(s) || (scp.getEnclosingScope().getScopeName().equals("this") && t.getMembers().contains(s))){
    if (t.containsSymbol(s) || (scp.getEnclosingScope() != null && scp.getEnclosingScope().getScopeName().equals("this") && t.containsSymbol(s))){
       //pegar no atributo do objecto numa atribuicao ou acesso
       if (ftime == true){
           //csAtt_att = (Scope) t.getMembers().get(i);
           csAtt_att = (Scope) t.getSymbolOfListSymbols(s);
           try{
               csAtt_att.getMembers().clear();
               for(int i=0; i< scp.getMembers().size(); i++)
                    csAtt_att.getMembers().add(scp.getMembers().get(i));
           } catch (Exception e) {}
           ftime = false;

           if (scp.getEnclosingScope() != null && scp.getEnclosingScope().getScopeName().equals("this")){
                Symbol sym_this = scp.getEnclosingScope().getScopeSymbol();
                scp.getScopeSymbol().setIsInstance(sym_this.getIsInstance());
                scp.getScopeSymbol().setIsClone(sym_this.getIsClone());
           }
       }
       else{
           //csAtt_acc = (Scope) t.getMembers().get(i);
           csAtt_acc = (Scope) t.getSymbolOfListSymbols(s);
       }
    }
    }

    Iterator <Symbol> it;
    Symbol sym;
    for (it = scp.getMembers().iterator(); it.hasNext();){
        sym = it.next();
        if (isClassInstruction == true){
        int op = 0;

        // criacao de um objecto
        // do tipo $a = new A_class()
        if (scp.getScopeSymbol().getIsInstance() == true)
            op = 2;

        // atribuicao e' um clone
        // do tipo $a = clone $obj
        if (scp.getScopeSymbol().getIsClone() == true)
            op = 3;

        // staticMember
        // A::meth()
        if (scp.getScopeSymbol().getIsStaticMember() == true)
            op = 4;

        // chamada de um metodo
        if(scp.getScopeSymbol().getIsFunction() == true && scp.getScopeSymbol().getIsClassMethod() == true &&
           scp.getScopeSymbol().getIsSecureFunction()==false && scp.getScopeSymbol().getIsTaintedFunction()==false){
            if (ms != null)
                op = 5; // metodo dentro de um metodo
            else
                op = 1; //metodo normal
        }

        switch (op){
            case 1:{ // chamada de um metodo normal
                ftime = false;
                
                // 1. obter instancia
                String instName = scp.getEnclosingScope().getScopeName();
                String fileInst = scp.getEnclosingScope().getScopeSymbol().getFileSymbol();
                InstanceTable instTable = GlobalDataCodeInj.MainInstancesTable.get(fileInst);
                SymbolTable st = GlobalDataCodeInj.MainSymbolTable.get(fileInst);
                String instName_aux = instName;
                Instance inst1 = null;
                if (st.getAliases().containsKey(instName_aux) == true)
                        instName_aux = st.getInstanceNameFromAliases(instName_aux, instTable);                
                
                if (instTable != null && instTable.containsInstance(instName_aux) == true)
                    inst1 = (Instance) instTable.getInstanceOfListInstances(instName_aux);

                // 2. obter classe
                String c_name = inst1.getInstanceClass();
                String cf_name = inst1.getFileOfClass();
                ClassTable ct = GlobalDataCodeInj.MainClassesTable.get(cf_name);
                ClassSymbol currentClass = ct.getClassOfListClasses(c_name);

                // * 3. procurar metodo
                MethodClass mc = currentClass.getMethodClass(scp.getScopeName(), "", mct);
                MethodSymbol mss_final = mc.getMeth();
                String mss_final_file = mc.getClassMeth().getFileClass();

                ret = null;
                ret = instanceMethod(mss_final, scp, filename, mss_final_file, mts, mus, inst1, null, mct, "", ret, instTable, st);                

                if (ret != null && instTable.containsInstance(ret.getInstanceName()) == true){
                        Boolean a = true;
                        Scope enc_f = scp;
                        Scope enc_b;
                        while (a == true){
                                enc_b = enc_f.getEnclosingScope();
                                if (enc_b.getScopeName().equals(st.getScopeName()) == false)
                                        enc_f = enc_b;
                                else
                                        a = false;
                        }

                        Symbol sy = new Symbol(ret.getInstanceName(), ret.getTainted(), ret.getCreateLineInstance(), ret.getFileInstance());
                        sy.setIsClassInstruction(true);
                        st.getAliases().put(enc_f.getScopeName(), sy);
                        scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                        mts.removeDuplicates(sym);

                        if (cs_att != null){
                                cs_att.getScopeSymbol().setTainted(ret.getTainted());
                                inst1.updateTainted(cs_att, sym);
                        }
                }
                exit_for = true;
                return;
            }
            
            case 2:{
                ftime = false;
                // criacao de um objecto
                    Instance inst1 = null;
                    InstanceTable instances_table = null;
                    if (ms == null){
                        String file_inst = sym.getFileSymbol();
                        instances_table = GlobalDataCodeInj.MainInstancesTable.get(file_inst);
                        Iterator <Instance> it1 = instances_table.getMembers().iterator();
                        for (; it1.hasNext();){
                            inst1 = it1.next();
                            if (inst1.getInstanceName().equals(s) && inst1.getCreateLineInstance() == sym.getCodeLine()){
                                break;
                            }
                        }
                    }


                /* 1. Procurar classe */
                ClassTable class_table = null;
                ClassSymbol currentClass = null;
                //Symbol sy = null;
                for (Iterator <ClassTable> it3 = GlobalDataCodeInj.MainClassesTable.values().iterator(); it3.hasNext();){
                    class_table = it3.next();


                    if (class_table.containsClass(sym.getName()) == true){
                        currentClass = (ClassSymbol) class_table.getClassOfListClasses(sym.getName());
                        break;
                    }
                }

                    if (ms != null){
                        if (typeMeth.equals("constructor") == true)
                            instances_table = inst.getObjectsOfInstance();
                        else
                            instances_table = mtsc.getObjectsOfMethod();
                    }

                    if (ms != null){
                        inst1 = new Instance(scp.getScopeName(), scp.getScopeSymbol().getCodeLine(), inst.getFileInstance(), sym.getName(), class_table.getScopeName(), currentClass, false);
                        instances_table.define(inst1);
                    }

                /* 2. procurar metodo construtor*/
                MethodClass mc = currentClass.getMethodClass(sym.getName(), "construct", mct);
                MethodSymbol mss_final = mc.getMeth();
                String mss_final_file = mc.getClassMeth().getFileClass();

                /* Fazer a analise do construtor */
                if (mss_final == null){ // a classe nao tem metodo construtor. logo fazer taint analise aos atributos
                    SymbolTable t1 = inst1.getInstanceAttributes();
                    TaintedTable tt1 = inst1.getMtsInstanceAttributes();
                    UntaintedTable ut1 = inst1.getMusInstanceAttributes();
                    Scope scp1;
                    for(Iterator <Symbol> it4 = t1.getMembers().iterator(); it4.hasNext();){
                         scp1 = (Scope) it4.next();
                         scp1.resolveSymbolClass(tt1, ut1, inst1.getFileOfClass());
                    }
                }
                else{
                    typeMeth = "constructor";
                    MethodSymbolCodeInj meth_sym = new MethodSymbolCodeInj(mss_final);
                    int valueFinal = meth_sym.analyseMethodCodeInj(mss_final,scp.getScopeSymbol().getCodeLine(), (Scope)sym, mts, mus, filename, mss_final_file, inst1, mct, typeMeth);
                    scp.getScopeSymbol().setTainted(valueFinal);
                    scp.resolveSymbol(scp, sym, mts, mus, scp.getScopeSymbol().getFileSymbol());

                    if (cs_att != null){
                        cs_att.getScopeSymbol().setTainted(valueFinal);
                        inst.updateTainted(cs_att, sym);
                    }
                }
                return;
            }

            case 3:{
                ftime = false;

                // atribuicao e' um clone
                if (ms != null)
                    mtsc.getAliases().put(s, sym);
                
                scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                if (cs_att != null){
                    cs_att.getScopeSymbol().setTainted(scp.getScopeSymbol().getTainted());
                    inst.updateTainted(cs_att, sym);
                }
                return;
            }

            case 4:{
                ftime = false;

                // staticMember
                // obter classe
                String clas = "";
                String clas_file = "";
                if (s.equals("self") == true){
                    clas = inst.getInstanceClass();
                    clas_file = inst.getFileOfClass();
                }
                else{
                    if (s.equals("parent") == true){
                        clas = inst.getInstanceClass();
                        clas_file = inst.getFileOfClass();
                        ClassTable ct = GlobalDataCodeInj.MainClassesTable.get(clas_file);
                        ClassSymbol cls = (ClassSymbol) ct.getClassOfListClasses(clas);
                        clas = cls.getExtendsClassName();
                        clas_file = cls.getFileExtendsClass();

                    }
                    else{
                        // obter nome e file da class
                        for (Iterator <ClassTable> it1 = mct.values().iterator(); it1.hasNext();){
                            ClassTable class_table = it1.next();
                            //if (class_table.getMembers().contains(s) == true){
                            if (class_table.containsClass(s) == true){
                                clas = s;
                                clas_file = class_table.getScopeName();
                                break;
                            }
                        }
                    }
                }
                if (clas.equals("") == false && sym.getIsClassMethod() == true){
                    ClassTable class_table = (ClassTable) mct.get(clas_file);
                    ClassSymbol currentClass  = (ClassSymbol) class_table.getClassOfListClasses(clas);

                    // obter metodo
                    //Symbol sy = (Symbol) scp.getMembers().get(0);
                    String ss = "";
                    if (sym.getName().equals("__construct"))
                        ss = "construct";
                    MethodClass mc = currentClass.getMethodClass(sym.getName(), ss, mct);
                    MethodSymbol mss_final = mc.getMeth();
                    String mss_final_file = mc.getClassMeth().getFileClass();
                    /* Fazer a analise do metodo */
                    if (mss_final != null){
                        Instance inst1 = null;
                        if (s.equals("self") == true || s.equals("parent") == true)
                            inst1 = inst;
                        
                        Scope scp1 = (Scope) sym;
                        MethodSymbolCodeInj meth_sym = new MethodSymbolCodeInj(mss_final);
                        int valueFinal = meth_sym.analyseMethodCodeInj(mss_final,scp.getScopeSymbol().getCodeLine(), scp1, mts, mus, filename, mss_final_file, inst, mct, typeMeth);
                        scp1.getScopeSymbol().setTainted(valueFinal);
                        scp.resolveSymbol(scp, scp1.getScopeSymbol(), mts, mus, scp1.getScopeSymbol().getFileSymbol());
                    }
                }
                return;
            }

            case 5:{
                ftime = false;
                InstanceTable instTable = null;
                SymbolTable st = null;                

                ret = instanceMethod(ms, scp, filename, "", mts, mus, inst, mtsc, mct, typeMeth, ret, null, null);

                InstanceTable instances_table = null;
                if (typeMeth.equals("constructor") == true)
                    instances_table = inst.getObjectsOfInstance();
                else
                    instances_table = mtsc.getObjectsOfMethod();

                //if (ret != null && instances_table.getMembers().contains(ret) == true){
                if (ret != null && instances_table.containsInstance(ret.getInstanceName()) == true){
                    Boolean a = true;
                    Scope enc_f = scp;
                    Scope enc_b;
                    while (a == true){
                        enc_b = enc_f.getEnclosingScope();
                        if (enc_b.getScopeName().equals(ms.getFunctionName()) == false)
                            enc_f = enc_b;
                        else
                            a = false;
                    }

                    Symbol sy = new Symbol(ret.getInstanceName(), ret.getTainted(), ret.getCreateLineInstance(), ret.getFileInstance());
                    sy.setIsClassInstruction(true);
                    mtsc.getAliases().put(enc_f.getScopeName(), sy);
                    scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                    mts.removeDuplicates(sym);

                    if (cs_att != null){
                        cs_att.getScopeSymbol().setTainted(ret.getTainted());
                        inst.updateTainted(cs_att, sym);
                    }
                }
                exit_for = true;                
            }
            default:{
                if (scp.getEnclosingScope() != null && scp.getEnclosingScope().getScopeName().equals("this") == false)
                    ftime = false;

                if (sym.getRootScope() == null && (sym.getIsClassMethod() == false && sym.getIsUserFunction() == false)){
                    if (ms != null){
                        if (ms.getArgsFunction().containsKey(sym.getName()) == true){
                            ArgFunctionSymbol arg = (ArgFunctionSymbol) ms.getArgsFunction().get(sym.getName());
                            sym.setName(arg.getCallFunctionArg());
                        }
                    }

                    if (mts.getTaintedMembers().containsKey(sym.getName()) == true && mus.existSymbol(sym.getName()) == false)
                        sym.setTainted(1);

                    if (inst != null){
                        SymbolTable t = inst.getInstanceAttributes();
                        if (t.containsSymbol(sym.getName()) || (scp.getEnclosingScope() != null && scp.getEnclosingScope().getScopeName().equals("this") && t.containsSymbol(sym.getName()))){
                            Scope scp_acc = (Scope) t.getSymbolOfListSymbols(sym.getName());
                            sym.setTainted(scp_acc.getScopeSymbol().getTainted());
                        }
                    }

                    scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                    mts.removeDuplicates(sym);


                    if (inst != null && csAtt_att != null){
                        inst.updateTainted(csAtt_att, sym);
                    }

                    if (csAtt_acc != null){
                        sym.setTainted(csAtt_acc.getScopeSymbol().getTainted());
                        scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                    }
                    
                    if (scp.getScopeSymbol().getIsSecureFunction() == false){
                        // se o scope e' tainted e e' uma funcao CI entao fazer correcao
                        if (scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false){
                            correctVulner("taintedFunction", scp, filename, GlobalDataCodeInj.MainSymbolTable, null, ms, mts, GlobalDataCodeInj.MainLinesToCorrect);
                        }
                    }                    
            }
            else{
                Scope scp1 = sym.getRootScope();
                if (scp1.getMembers().size() > 0){
                    FuncAndIncCodeInj css2 = new FuncAndIncCodeInj(scp1);
                    css2.resolveSymbolClassCodeInj(ms, scp1, mts, mus, filename, mtsc, inst, mct, ftime, csAtt_att, csAtt_acc, typeMeth, isClassInstruction);
                    scp.resolveSymbol(scp, sym, mts, mus, filename);
                    mts.removeDuplicates(sym);
                    return;
                }
                else{
                ftime = false;
                
                // 1. obter instancia
                String instName = scp1.getEnclosingScope().getScopeName();
                String fileInst = scp1.getEnclosingScope().getScopeSymbol().getFileSymbol();
                InstanceTable instTable = GlobalDataCodeInj.MainInstancesTable.get(fileInst);
                SymbolTable st = GlobalDataCodeInj.MainSymbolTable.get(fileInst);
                String instName_aux = instName;
                Instance inst1 = null;
                if (st.getAliases().containsKey(instName_aux) == true)
                        instName_aux = st.getInstanceNameFromAliases(instName_aux, instTable);                
                
                if (instTable != null && instTable.containsInstance(instName_aux) == true)
                    inst1 = (Instance) instTable.getInstanceOfListInstances(instName_aux);

                // 2. obter classe
                String c_name = inst1.getInstanceClass();
                String cf_name = inst1.getFileOfClass();
                ClassTable ct = GlobalDataCodeInj.MainClassesTable.get(cf_name);
                ClassSymbol currentClass = ct.getClassOfListClasses(c_name);
                // 3. procurar metodo
                MethodClass mc = currentClass.getMethodClass(scp1.getScopeName(), "", mct);
                MethodSymbol mss_final = mc.getMeth();
                String mss_final_file = mc.getClassMeth().getFileClass();

                ret = null;
                ret = instanceMethod(mss_final, scp1, filename, mss_final_file, mts, mus, inst1, null, mct, "", ret, instTable, st);                

                if (ret != null && instTable.containsInstance(ret.getInstanceName()) == true){
                        Boolean a = true;
                        Scope enc_f = scp;
                        Scope enc_b;
                        while (a == true){
                                enc_b = enc_f.getEnclosingScope();
                                if (enc_b.getScopeName().equals(st.getScopeName()) == false)
                                        enc_f = enc_b;
                                else
                                        a = false;
                        }

                        Symbol sy = new Symbol(ret.getInstanceName(), ret.getTainted(), ret.getCreateLineInstance(), ret.getFileInstance());
                        sy.setIsClassInstruction(true);
                        st.getAliases().put(enc_f.getScopeName(), sy);
                        scp1.resolveSymbol(scp1, sym, mts, mus, sym.getFileSymbol());
                        mts.removeDuplicates(sym);

                        if (cs_att != null){
                                cs_att.getScopeSymbol().setTainted(ret.getTainted());
                                inst1.updateTainted(cs_att, sym);
                        }
                }
                }
                scp.resolveSymbol(scp, sym, mts, mus, filename);
                mts.removeDuplicates(sym);
            }
         }
         if (exit_for == true)
             break;

        }
        }
      }
    }
    }


    private static Instance instanceMethod(MethodSymbol ms, Scope scp, String filename, String file_methClass, TaintedTable mts, UntaintedTable mus, Instance inst, MethodSymbolCall mtsc, Map mct, String typeMeth, Instance objRet, InstanceTable instTab, SymbolTable symTab) throws IOException{      
        // ver quem e' o metodo
        String s = scp.getScopeName();
        String s1 = "", s2 = "";
        Instance ii = null, ret = null;

        //int i = -1;

        InstanceTable instances_table = null;
        if (instTab == null){
            if (typeMeth.equals("constructor") == true)
                instances_table = inst.getObjectsOfInstance();
            else
                instances_table = mtsc.getObjectsOfMethod();
        }
        else
            instances_table = instTab;

        Scope enc = scp.getEnclosingScope();
        String enc_s = enc.getScopeSymbol().getName();
        String instanceName = enc_s;
        if (enc.getScopeSymbol().getIsClassMethod() == false && objRet == null){
            // obj -> func()
            // ver se a instancia e' um clone
            if (instTab == null){
                if (mtsc.getAliases().containsKey(instanceName) == true){
                    instanceName = mtsc.getInstanceNameFromAliases(instanceName, instances_table);
                }
            }
            else{
                if (symTab.getAliases().containsKey(instanceName) == true){
                    instanceName = symTab.getInstanceNameFromAliases(instanceName, instances_table);
                }
            }

            if (instances_table.containsInstance(instanceName) == true){
                ii = (Instance) instances_table.getInstanceOfListInstances(instanceName);
                s1 = ii.getInstanceClass();
                s2 = ii.getFileOfClass();
                inst = ii;
            }
            else{
                // func() e' um metodo da instancia actual
                try{
                    s1 = inst.getInstanceClass();
                    s2 = inst.getFileOfClass();
                } catch (Exception e) {}
            }

            if (s1 != null){
                // obter classe
                ClassTable class_table = (ClassTable) mct.get(s2);
                ClassSymbol currentClass  = (ClassSymbol) class_table.getClassOfListClasses(s1);

                // obter metodo
                MethodClass mc = currentClass.getMethodClass(s, "", mct);
                MethodSymbol mss_final = mc.getMeth();
                String mss_final_file = mc.getClassMeth().getFileClass();

                /* Fazer a analise do metodo */
                if (mss_final != null){
                    MethodSymbolCodeInj meth_sym = new MethodSymbolCodeInj(mss_final);
                    int valueFinal = meth_sym.analyseMethodCodeInj(mss_final,scp.getScopeSymbol().getCodeLine(), scp, mts, mus, filename, mss_final_file, inst, mct, typeMeth);
                    scp.getScopeSymbol().setTainted(valueFinal);
                    ret = inst.getInstanceOfReturn(s, scp.getScopeSymbol().getCodeLine(), null, null, false);

                }
            }
        }
        else{
            // (obj -> func()) -> func()
            if (objRet != null){
                // obter classe
                s1 = objRet.getInstanceClass();
                s2 = objRet.getFileOfClass();
                ClassTable class_table = (ClassTable) mct.get(s2);
                ClassSymbol currentClass  = (ClassSymbol) class_table.getClassOfListClasses(s1);

                if (scp.getScopeSymbol().getIsClassMethod() == true){
                    // obter metodo
                    MethodClass mc = currentClass.getMethodClass(s, "", mct);
                    MethodSymbol mss_final = mc.getMeth();
                    String mss_final_file = mc.getClassMeth().getFileClass();

                    /* Fazer a analise do metodo */
                    if (mss_final != null){
                        MethodSymbolCodeInj meth_sym = new MethodSymbolCodeInj(mss_final);
                        int valueFinal = meth_sym.analyseMethodCodeInj(mss_final,scp.getScopeSymbol().getCodeLine(), scp, mts, mus, filename, mss_final_file, inst, mct, typeMeth);
                        scp.getScopeSymbol().setTainted(valueFinal);
                        ret = inst.getInstanceOfReturn(s, scp.getScopeSymbol().getCodeLine(), null, null, false);
                    }
                }
                else{
                    if (scp.getScopeSymbol().getRootScope() == null){                       
                        FuncAndIncCodeInj css2 = new FuncAndIncCodeInj(scp);
                        css2.resolveSymbolClassCodeInj(null, scp, mts, mus, scp.getScopeSymbol().getFileSymbol(), mtsc, inst, mct, true, null, null, typeMeth, true);
                        scp.resolveSymbol(scp, (Symbol) scp.getMembers().get(0), mts, mus, scp.getScopeSymbol().getFileSymbol());
                        mts.removeDuplicates((Symbol) scp.getMembers().get(0));
                    }
                }
            }
        }

        // ver se o metodo e' o ultimo a ser chamado
        Boolean endChain = true;
        Symbol sy = null;
        for (int j = 0; j < scp.getMembers().size(); j++){
            sy = (Symbol) scp.getMembers().get(j);
            if (sy.getRootScope() != null && sy.getIsParamUserFunction() == false){
                endChain = false;
                break;
            }
        }
        if (endChain == true){
            if (ret != null){
                ClassTable ct = (ClassTable) mct.get(ret.getFileOfClass());
                ClassSymbol ret_cl = (ClassSymbol) ct.getClassOfListClasses(ret.getInstanceClass());
                Instance r = new Instance(ret, ret_cl);
                instances_table.getMembers().add(r);
                scp.getScopeSymbol().setTainted(ret.getTainted());
                scp.resolveSymbol(scp, scp.getScopeSymbol(), mts, mus, scp.getScopeSymbol().getFileSymbol());
            }
        }
        else{
            ret = instanceMethod(ms, (Scope) sy, filename, file_methClass, mts, mus, inst, mtsc, mct, typeMeth, ret, instTab, symTab);
            scp.resolveSymbol(scp, sy, mts, mus, scp.getScopeSymbol().getFileSymbol());
            mts.removeDuplicates(sy);
        }

        return ret;
    }



    // Resolve symbols of include files that have yet analysed one time.
    // In this way, the include is added just one time in Scope Symtab_include
    // and on next times just need make data flow analysis to scope
    public void resolveSymbolIncludeCodeInj(Scope scp, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map mftt, Map MainLinesToCorrect) throws IOException{
        String filename_aux="";
        // Scope em analise e' um "include("...")"
        if (scp.getScopeName().equals("include") == true){       
            // Resolver a taintedness do include
            resolveSymbolTaintednessInclude(mts, mus, scp, scp);
           
            // se o scope e' tainted e e' uma funcao RFI/LFI/DT entao fazer correcao
            if (scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false){                
                correctVulner("taintedFunction", scp, filename, mst, mift, null, mts, MainLinesToCorrect);      
                //return;
            }
                  
            Symbol s = (Symbol) scp.getMembers().get(0);
            String nameIncFile = s.getName();
        try{
            SymbolTable st = (SymbolTable) mift.get(nameIncFile);           
            Iterator <Symbol> it = st.getMembers().iterator();
            Scope cs;
            Symbol sy;
            for(; it.hasNext();){
		sy = it.next();
                if (sy.getIsVariableSymbol() == false){
                    cs = (Scope) sy;
                    FuncAndIncCodeInj css = new FuncAndIncCodeInj(cs);
                    css.resolveSymbolIncludeCodeInj((Scope) cs, mts, mus, mift, nameIncFile, mft, mst, mftt, MainLinesToCorrect);
                }
            }
         } catch (Exception e){}
         //} catch (Exception e){System.out.println("File: "+ nameIncFile+" not exist");}
        }
        else{
            if (scp.getScopeSymbol().getIsSecureFunction() == false){
                // verifica se o scope name e' uma chamada de funcao de UserFunction
                // primeiro nas funcoes definidas no file em analise
                MethodSymbolCodeInj mss_final = null;
                MethodSymbol mss = null;
                String mss_final_file = "";
                if (scp.getScopeSymbol().getIsUserFunction() == true){
                    if (mft.containsKey(filename) == true){
                        MethodTable mt = (MethodTable) mft.get(filename);
                        for(Iterator <MethodSymbol> it = mt.getMembers().iterator(); it.hasNext();){
                            mss = it.next();
                            if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                mss_final = new MethodSymbolCodeInj(mss);
                                mss_final_file = filename;
                                break;
                            }
                        }
                    }
                    if (mss_final == null){
                        // segundo nas UserFunctions definidas nos include files do file em analise
                        SymbolTable st = (SymbolTable) mift.get(filename);
                        if (st.getIncludeFiles().isEmpty() == false){
                            String s;
                            SymbolTable st1;
                            for(Iterator <String> it = st.getIncludeFiles().iterator(); it.hasNext();){
                                s = it.next();
                                st1 = (SymbolTable) mift.get(s);
                                if(st1.getHaveFunctions() == true){
                                    MethodTable mt  = (MethodTable) mft.get(s);
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            mss_final = new MethodSymbolCodeInj(mss);
                                            mss_final_file = s;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                if (mss_final == null && scp.getScopeSymbol().getIsFunction() == true
                      && scp.getScopeSymbol().getIsTaintedFunction() == false
                      && scp.getScopeSymbol().getFileSymbol().equals(filename) == false){
                        // terceiro nas UserFunctions definidas nos include files do file que chamou a primeira
                        // funcao. Aqui estamos 'a procura de uma 2da funcao que esta' dentro de um include nao 
                        // pertencente ao file onde ela e' chamada, mas a um file que chama a 1 funcao
                        SymbolTable st = (SymbolTable) mst.get(filename);
                        if (st.getIncludeFiles().isEmpty() == false){
                            String s;
                            SymbolTable st1;
                            for(Iterator <String> it = st.getIncludeFiles().iterator(); it.hasNext();){
                                s = it.next();
                                st1 = (SymbolTable) mift.get(s);
                                if(st1.getHaveFunctions() == true){
                                    MethodTable mt  = (MethodTable) mft.get(s);
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            //mss_final = (MethodSymbolSqli) mss;
                                            mss_final = new MethodSymbolCodeInj(mss);
                                            mss_final_file = s;
                                            filename_aux = filename;
                                            filename= scp.getScopeSymbol().getFileSymbol();                                          
                                            break;
                                        }
                                    }
                                }
                                if (mss_final != null)
                                    break;
                            }
                        }
                        
                        // verifica nos outros includes. Para termos a certeza que se trata ou nao de uma userFunction
                        if (mss_final == null){
                            for(Iterator <SymbolTable> itt = mift.values().iterator(); itt.hasNext();){
                                SymbolTable st1 = itt.next();
                                if(st1.getHaveFunctions() == true && st.getIncludeFiles().contains(st1.getScopeName()) == false){
                                    MethodTable mt  = (MethodTable) mft.get(st1.getScopeName());
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            //mss_final = (MethodSymbolSqli) mss;
                                            mss_final = new MethodSymbolCodeInj(mss);
                                            mss_final_file = st1.getScopeName();
                                            filename_aux = filename;
                                            filename= scp.getScopeSymbol().getFileSymbol();                                          
                                            break;
                                        }
                                    }
                                }
                                if (mss_final != null)
                                    break;
                            }                        
                        }
                }
                               
                // se mss_final != null entao o scope name e' uma Userfunction
                // Fazer entao a analise na UserFunction
                if (mss_final != null){
                    String valueFinal = mss_final.analyseUserFunctionCodeInj(mss, scp.getScopeSymbol().getCodeLine(), scp, mts, mus, filename, mss_final_file, mift, mft, mst, mftt, MainLinesToCorrect);
                    if (filename_aux.isEmpty() == false){
                        filename = filename_aux;
                        filename_aux = "";
                    }                 
                }
                else{
                Symbol sym1, sym;
                Iterator <Symbol> it = scp.getMembers().iterator();
                for(;it.hasNext();){
                    sym = it.next();
                    if (sym.getRootScope() == null){
                            if (mts.getTaintedMembers().containsKey(sym.getName()) == true && mus.existSymbol(sym.getName()) == false)
                                sym.setTainted(1);

                            scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                            mts.removeDuplicates(sym);

                            // se o scope e' tainted e e' uma funcao RFI/LFI/DT entao fazer correcao
                            if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)){
                                correctVulner("taintedFunction", scp, filename, mst, mift, null, mts, MainLinesToCorrect);
                            }                            
                    }
                    else{
                        Scope scp1 = (Scope) sym.getRootScope();
                        FuncAndIncCodeInj css1 = new FuncAndIncCodeInj(scp1);
                        css1.resolveSymbolIncludeCodeInj(sym.getRootScope(), mts, mus, mift, filename, mft, mst, mftt, MainLinesToCorrect);
                        scp.resolveSymbol(scp, sym, mts, mus, filename);
                        mts.removeDuplicates(sym);
                        
                        if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)){
                            correctVulner("taintedFunction", scp, filename, mst, mift, null, mts, MainLinesToCorrect);
                        }
                    }  
               }
            }
         }
      }
    }




    // Resolve symbols of function defined by user that have yet analysed one time.
    // In this way, the function is added just one time in Scope Symtab_functions
    // and on next times just need make data flow analysis to scope
    public void resolveSymbolFunctionCodeInj(MethodSymbol ms, Scope scp, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map mftt, Map MainLinesToCorrect) throws IOException{       
        String filename_aux="";
        if (scp.getScopeName().equals("include") == true){
            
            // Resolver a taintedness do include
            resolveSymbolTaintednessInclude(mts, mus, scp, scp);
           
            // se o scope e' tainted e e' uma funcao RFI/LFI/DT entao fazer correcao
            if (scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false){
                correctVulner("taintedFunction", scp, filename, mst, mift, null, mts, MainLinesToCorrect);      
                //return;
            }            
            
            try{
            this.resolveSymbolIncludeCodeInj(scp, mts, mus, mift, filename, mft, mst, mftt, MainLinesToCorrect);
            } catch (Exception e){
                //System.out.println("Error processing include file: "+this.getName());
            }
            return;
        }        
        
           if (scp.getScopeSymbol().getIsSecureFunction() == false){
            // verifica se o scope name e' uma chamada de funcao de UserFunction
            // primeiro nas funcoes definidas no file em analise
            MethodSymbolCodeInj mss_final = null;
            MethodSymbol mss = null;
            String mss_final_file = "";
            if (scp.getScopeSymbol().getIsUserFunction() == true){
                if (mft.containsKey(filename) == true){
                    MethodTable mt = (MethodTable) mft.get(filename);
                    for(Iterator <MethodSymbol> it = mt.getMembers().iterator(); it.hasNext();){
                        mss = it.next();
                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                            mss_final = new MethodSymbolCodeInj(mss);
                            mss_final_file = filename;
                            break;
                        }
                    }
                }
                if (mss_final == null){
                    // segundo nas UserFunctions definidas nos include files do file em analise
                    SymbolTable st = (SymbolTable) mst.get(filename);
                    if (st.getIncludeFiles().isEmpty() == false){
                        String s;                       
                        SymbolTable st1;
                        for(Iterator <String> it = st.getIncludeFiles().iterator(); it.hasNext();){
                            s = it.next();
                            st1 = (SymbolTable) mift.get(s);
                            if(st1.getHaveFunctions() == true){
                                MethodTable mt  = (MethodTable) mft.get(s);
                                for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                    mss = it1.next();                                    
                                    if(mss.getFunctionName().equals(scp.getScopeName()) == true){                                       
                                        mss_final = new MethodSymbolCodeInj(mss);
                                        mss_final_file = s;                                       
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                
            }
             
                if (mss_final == null && scp.getScopeSymbol().getIsFunction() == true
                      && scp.getScopeSymbol().getIsTaintedFunction() == false
                      && scp.getScopeSymbol().getFileSymbol().equals(filename) == false){
                        // terceiro nas UserFunctions definidas nos include files do file que chamou a primeira
                        // funcao. Aqui estamos 'a procura de uma 2da funcao que esta' dentro de um include nao 
                        // pertencente ao file onde ela e' chamada, mas a um file que chama a 1 funcao
                        SymbolTable st = (SymbolTable) mst.get(filename);
                        if (st.getIncludeFiles().isEmpty() == false){
                            String s;
                            SymbolTable st1;
                            for(Iterator <String> it = st.getIncludeFiles().iterator(); it.hasNext();){
                                s = it.next();
                                st1 = (SymbolTable) mift.get(s);
                                if(st1.getHaveFunctions() == true){
                                    MethodTable mt  = (MethodTable) mft.get(s);
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            mss_final = new MethodSymbolCodeInj(mss);
                                            mss_final_file = s;
                                            filename_aux = filename;
                                            filename= scp.getScopeSymbol().getFileSymbol();                                          
                                            break;
                                        }
                                    }
                                }
                                if (mss_final != null)
                                    break;
                            }
                        }
                        
                        // verifica nos outros includes. Para termos a certeza que se trata ou nao de uma userFunction
                        if (mss_final == null){
                            for(Iterator <SymbolTable> itt = mift.values().iterator(); itt.hasNext();){
                                SymbolTable st1 = itt.next();
                                if(st1.getHaveFunctions() == true && st.getIncludeFiles().contains(st1.getScopeName()) == false){
                                    MethodTable mt  = (MethodTable) mft.get(st1.getScopeName());
                                    for(Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext();){
                                        mss = it1.next();
                                        if(mss.getFunctionName().equals(scp.getScopeName()) == true){
                                            //mss_final = (MethodSymbolSqli) mss;
                                            mss_final = new MethodSymbolCodeInj(mss);
                                            mss_final_file = st1.getScopeName();
                                            filename_aux = filename;
                                            filename= scp.getScopeSymbol().getFileSymbol();                                          
                                            break;
                                        }
                                    }
                                }
                                if (mss_final != null)
                                    break;
                            }                        
                        }
                }            
            
            // se mss_final != null entao o scope name e' uma Userfunction
            // Fazer entao a analise na UserFunction
            if (mss_final != null){
                String valueFinal = mss_final.analyseUserFunctionCodeInj(mss, scp.getScopeSymbol().getCodeLine(), scp, mts, mus, filename, mss_final_file, mift, mft, mst, mftt, MainLinesToCorrect);
                if (filename_aux.isEmpty() == false){
                    filename = filename_aux;
                    filename_aux = "";
                }
            }
            else{
            Symbol sym1, sym;           
            
            // Se o nome do scope for o nome de argumento da chamada da funcao entao o nome do scope muda para ele
            if(ms.getArgsFunction().containsKey(scp.getScopeName()) == true){
                ArgFunctionSymbol arg = (ArgFunctionSymbol) ms.getArgsFunction().get(scp.getScopeName());
                scp.getScopeSymbol().setName(arg.getCallFunctionArg());
                return;
            }                      
            Iterator <Symbol> it = scp.getMembers().iterator();
            for(;it.hasNext();){
                    sym = it.next();
                    if (sym.getRootScope() == null){
                            if (ms.getArgsFunction().containsKey(sym.getName()) == true){
                                ArgFunctionSymbol arg = (ArgFunctionSymbol) ms.getArgsFunction().get(sym.getName());
                                sym.setName(arg.getCallFunctionArg());
                            }                             
                            if (mts.getTaintedMembers().containsKey(sym.getName()) == true && mus.existSymbol(sym.getName()) == false)
                                sym.setTainted(1);
                            
                            scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                            mts.removeDuplicates(sym);           
                            // se o scope e' tainted e e' uma funcao RFI/LFI/DT entao fazer correcao
                                if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)){
                                            correctVulner("taintedFunction", scp, filename, mst, null, ms, mts, MainLinesToCorrect);
                                }
                                                       
                    }
                    else{
                        Scope scp1 = sym.getRootScope();
                        FuncAndIncCodeInj css1 = new FuncAndIncCodeInj(scp1);
                        css1.resolveSymbolFunctionCodeInj(ms, scp1, mts, mus, mift, filename, mft, mst, mftt, MainLinesToCorrect);
                        scp.resolveSymbol(scp, sym, mts, mus, filename);
                        mts.removeDuplicates(sym);
                        
                    if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)){
                            correctVulner("taintedFunction", scp, filename, mst, null, ms, mts, MainLinesToCorrect);
                    }                        
                    }
            }              
            
            Scope aux = scp.getScopeSymbol().getRootScope();
            if (aux.getScopeName().equals("return") == true && aux.getScopeSymbol().getTainted() == 1){
                ms.getScopeSymbol().setTainted(1);
     
                //inserir ms como dependente do return
                RootTaintedSymbol Rrt;
                Rrt = (RootTaintedSymbol) mts.getTaintedMembers().get("return");
                RelatedTaintedSymbol rtt;
                rtt =   (RelatedTaintedSymbol) Rrt.getListTaintedMembers().get(Rrt.getListTaintedMembers().size()-1);
                // Caso o ms nao pertenca 'a lista da funcao tainted
                if (rtt.getTaintedMembers().containsKey(ms.getScopeName()) == false){
                    VariableTaintedSymbol var = new VariableTaintedSymbol(ms.getScopeName(),
                                                ms.getScopeSymbol().getCodeLine(), ms.getScopeSymbol().getTainted(),
                                                ms.getScopeSymbol().getFileSymbol());
                    rtt.define(var);
                }
                else{
                    VariableTaintedSymbol var = (VariableTaintedSymbol) rtt.getTaintedMembers().get(ms.getScopeName());
                    var.InsertLine(ms.getScopeSymbol().getCodeLine());
                    var.InsertFile(ms.getScopeSymbol().getFileSymbol());
                }
            }
        }
      }
 //   }
}

    // Resolve symbols of SymbolTable.
    public void resolveSymbolCodeInj(Scope scp, TaintedTable mts, UntaintedTable mus, Map mift, String filename, Map mft, Map mst, Map mftt, Map MainLinesToCorrect, Map mct, Map mobjt) throws IOException{
        if (scp.getScopeName().equals("include")){
            try{
            this.resolveSymbolIncludeCodeInj(scp, mts, mus, mift, filename, mft, mst, mftt, MainLinesToCorrect);
            } catch (Exception e){
                //System.out.println("Error processing include file: "+this.getName());
            }
            return;
        }
        
        if (scp.getScopeSymbol().getIsSecureFunction() == false){             
            if (scp.getScopeSymbol().getIsUserFunction() == true){
                try{
                this.resolveSymbolFunctionCodeInj(null, scp, mts, mus, mift, filename, mft, mst, mftt, MainLinesToCorrect);
                } catch (Exception e){
                    //System.out.println("Error processing include file: "+this.getName());
                }
                return;
            }

            if(scp.getScopeSymbol().getIsClassInstruction() == true){
                try{
                this.resolveSymbolClassCodeInj(null, scp, mts, mus, filename, null, null, mct, true, null, null, "", true);
                } catch (Exception e){
                    //System.out.println("Error processing include file: "+this.getName());
                }
                return;
            }

                       
            // Analise de scope normal
            Symbol sym1, sym;
            Iterator <Symbol> it = scp.getMembers().iterator();
            for(;it.hasNext();){
                sym = it.next();
                if (sym.getRootScope() == null){
                    if (mts.getTaintedMembers().containsKey(sym.getName()) == true && mus.existSymbol(sym.getName()) == false)
                        sym.setTainted(1);

                    scp.resolveSymbol(scp, sym, mts, mus, sym.getFileSymbol());
                    mts.removeDuplicates(sym);

                    // se o scope e' tainted e e' uma funcao CodeInjection entao fazer correcao CI
                    if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)){
                            correctVulner("taintedFunction", scp, filename, mst, null, null, mts, MainLinesToCorrect);
                    }                    
                }
                else{
                    Scope scp1 = (Scope) sym.getRootScope();
                    FuncAndIncCodeInj css1 = new FuncAndIncCodeInj(scp1);
                    css1.resolveSymbolCodeInj(sym.getRootScope(), mts, mus, mift, filename, mft, mst, mftt, MainLinesToCorrect, mct, mobjt);
                    scp.resolveSymbol(scp, sym, mts, mus, filename);
                    mts.removeDuplicates(sym);
                    
                    // se o scope e' tainted e e' uma funcao SQLI entao fazer correcao SQL
                    if ((scp.getScopeSymbol().getIsTaintedFunction() == true && scp.getScopeSymbol().getTainted() == 1 && scp.getScopeSymbol().getIsVulDetected() == false)){
                            correctVulner("taintedFunction", scp, filename, mst, null, null, mts, MainLinesToCorrect);
                    }                    
                }
           }            
        }
    }
    

    private void correctVulner(String dataInc, Scope scp, String filename, Map mst, Map mift, MethodSymbol ms, TaintedTable mts, Map MainLinesToCorrect) throws IOException{        
            scp.getScopeSymbol().setIsVulDetected(true);
            SymbolTable currentSymbolTable = new SymbolTable(scp.getScopeSymbol().getFileSymbol());
            SymbolTable ct;          

            int m = 0;
            if (mift == null || mift.size() == 0)
                m = 0;
            
            if (ms == null){
                if (m == 0){
                    ct = (SymbolTable) mst.get(scp.getScopeSymbol().getFileSymbol());
                    currentSymbolTable.setAllSymbols(ct.getMembers());
                    currentSymbolTable.setAllIncludeFiles(ct.getIncludeFiles());
                }
                else{    
                    ct = (SymbolTable) mift.get(scp.getScopeSymbol().getFileSymbol());
                    currentSymbolTable.setAllSymbols(ct.getMembers());
                    currentSymbolTable.setAllIncludeFiles(ct.getIncludeFiles());
                }
            }
            else
                currentSymbolTable.setAllSymbols(ms.getMembers());
            VulnerabilityPathCodeInj vvp = new VulnerabilityPathCodeInj(scp);
            
            
/* **************
 * CORRECAO e DM
 */                        
            Vulner vv = vvp.collectVulnPathCodeInj(dataInc, GlobalDataCodeInj.UserInput, mts, currentSymbolTable, false, MainLinesToCorrect);

            /*
                    DATA MINING
            */
            
            int fp = vv.getVectorAttributesOfVulner().predictFalsePositive(true);
            vv.setIsFP(fp);          
            
            if (GlobalDataCodeInj.MainNumFP.containsKey(vv.getFileOf_SS()) == false)
                GlobalDataCodeInj.MainNumFP.put(vv.getFileOf_SS(), 0);
            
            if (GlobalDataCodeInj.MainNumVul.containsKey(vv.getFileOf_SS()) == false)
                GlobalDataCodeInj.MainNumVul.put(vv.getFileOf_SS(), 0);            
            
            //try{
            if (vv.IsFP() == 1){                          
                int nFP = GlobalDataCodeInj.MainNumFP.get(vv.getFileOf_SS()) + 1;
                GlobalDataCodeInj.MainNumFP.put(vv.getFileOf_SS(), nFP);                            
            }
            else{
                if (scp.getScopeSymbol().getTainted() == 1){                     
                    int nVul = GlobalDataCodeInj.MainNumVul.get(vv.getFileOf_SS()) + 1;
                    GlobalDataCodeInj.MainNumVul.put(vv.getFileOf_SS(), nVul);
                }

            }
            //} catch (Exception e) {}


            GlobalDataCodeInj.currentVulner = null;            
        //}
    }    
    
    
     /*
      * Resolve symbol of arguments include
      */
     private void resolveSymbolTaintednessInclude(TaintedTable mts, UntaintedTable mus, Scope sc, Scope sc_princ){
        if (sc.getScopeSymbol().getTainted() == 0){       
            if (!sc.getMembers().isEmpty()){
               Symbol sym;
               for(Iterator <Symbol> itt = sc.getMembers().iterator(); itt.hasNext();){
                   sym = itt.next();
                   if (sym.getRootScope() != null){
                       Scope scc = (Scope) sym;
                       resolveSymbolTaintednessInclude(mts, mus, scc, sc_princ);
                   }
                   else{
                       resolveTaintednessInclude(sym, mts, mus, sc);
                       if (sym.getTainted() == 1)
                           sc_princ.getScopeSymbol().setTainted(1);                       
                   }
               }
            }
            else{
                resolveTaintednessInclude(sc.getScopeSymbol(), mts, mus, sc);
                if (sc.getScopeSymbol().getTainted() == 1)
                    sc_princ.getScopeSymbol().setTainted(1);                
            }
        }
     }     
  
    
    /*
     * Resolve taintedness of include to see if they are reaches a include function
     */
    private void resolveTaintednessInclude(Symbol symb, TaintedTable mts, UntaintedTable mus, Scope sc){
        if (symb.getTainted() == 0){
            String nam = symb.getName();
            // Caso o symbol seja uma var ja tainted e pertenca a tabela das vars tainteds
            if (mts.getTaintedMembers().containsKey(nam) == true && mus.existSymbol(nam) == false) {
                symb.setTainted(1);
            }

        // Caso o symbol seja um alfanumeric e contenha uma var tainted da tabela das vars tainteds
        if (symb.getAlfanumeric() == true) {
            Boolean existe = false;
            Iterator <Symbol> itt = mts.getTaintedMembers().values().iterator();
            for(;itt.hasNext(); ){
                String s = itt.next().getName();
                if (nam.contains("$"+s) == true && mus.existSymbol(s) == false){
                    symb.setTainted(1);
                }
            }
        }

        // colocar scope parent tainted
        if (symb.getTainted() == 1)
            sc.getScopeSymbol().setTainted(1);
        }
        
        sc.resolveSymbol(sc, symb, mts, mus, symb.getFileSymbol());
        mts.removeDuplicates(symb);
    }    
    
    @Override
    public List<Symbol> getMembers() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void print(Scope scp) {
        throw new UnsupportedOperationException("Not supported yet.");
    }




} public class OutputAnalysisCodeInj {

    //public static void outputAnalysisWithCorrection (String type_analyse, String filename) throws IOException{
    public static void outputAnalysisWithCorrection (String type_analyse, String filename, LinesToCorrect ltc, int num_file) throws IOException{        
        FileWriter out_FileOfPaths = null;
        File dir = null;
        BufferedWriter bufferWritter = null;
        Date date = new Date(System.currentTimeMillis());
        int i = GlobalDataCodeInj.MainLinesToCorrect.size();

        if (type_analyse.equals("project") == true){
            dir = new File(System.getProperty("base.dir") + File.separator + "NewFiles");
            
            // Se ja houve analises anteriores apaga dir
            if (GlobalDataApp.numAnalysis == 0 && dir.exists() == true && num_file == i){
                ManageFiles r = new ManageFiles(dir.toString());
                r.deleteDir(dir);
                GlobalDataApp.numAnalysis++;
            }
            
            //Criar directorio para colocar fichs corrigidos
            if (dir.exists() == false)
                dir.mkdir();
            // cria ficheiro que contem a path dos ficheiros que serao corrigidos
            File fileOfPaths = new File(dir+ File.separator +"PathNewFiles.txt");
            if (fileOfPaths.exists() == true)
                out_FileOfPaths = new FileWriter(fileOfPaths, true);
            else
                out_FileOfPaths = new FileWriter(fileOfPaths);
            bufferWritter = new BufferedWriter(out_FileOfPaths);
        }

        // Escrever Ficheiro corrigido
        //for (Iterator <LinesToCorrect> it = GlobalDataCodeInj.MainLinesToCorrect.values().iterator(); it.hasNext();){
        //    ltc = it.next();

            //ltc = GlobalDataCodeInj.MainLinesToCorrect.get(filename);
            String file = ltc.getNameFile();
            ManageFiles relativeFile = new ManageFiles(file);
            //File filename = relativeFile.getFileName();

            if (type_analyse.equals("single_file") == true || type_analyse.equals("files") == true){
                File baseDir = relativeFile.getBaseDir();
                dir = new File(baseDir + File.separator + "NewFiles");
                
                // Se ja houve analises anteriores apaga dir
                if (GlobalDataApp.numAnalysis == 0 && dir.exists() == true && num_file == i){
                    ManageFiles r = new ManageFiles(dir.toString());
                    r.deleteDir(dir);
                    GlobalDataApp.numAnalysis++;
                }
                
                //Criar directorio para colocar fichs corrigidos
                File fileOfPaths = new File(dir+ File.separator +"PathNewFiles.txt");
                if (dir.exists() == false)
                    dir.mkdir();

                if (fileOfPaths.exists() == true)
                    out_FileOfPaths = new FileWriter(fileOfPaths, true);
                else
                    out_FileOfPaths = new FileWriter(fileOfPaths);

    	        bufferWritter = new BufferedWriter(out_FileOfPaths);
            }


            if (ltc.getMapLinesToCorrectArray().isEmpty() == false){
                File ff = new File(dir+ File.separator + file);
                File in = null, out = null, temp = null, inn = null;                
                if (ff.exists() == false){                   
                    bufferWritter.write(date + " " + file + "\n");
                    in = new File(file);
                    try{
                        int ind = file.lastIndexOf(File.separator);
                        String s = file.substring(0, ind);
                        File d = new File(dir + File.separator + s);
                        d.mkdirs();   
                        out = new File(ff.toString());
                    } catch (Exception e) {}                    
                }
                else{
                    in = new File(ff.toString());
                    temp = new File(ff.toString() + "temp");
                    in.renameTo(temp);
                    in = new File(temp.toString());
                    out = new File(dir+ File.separator + file);
                }
                
                Scanner fscanner = new Scanner(in);
                FileWriter outFinalFile = new FileWriter(out);

                Map sortedMap = new TreeMap(ltc.getMapLinesToCorrectArray());
                Set a = sortedMap.keySet();
                String codeLine;
                int line = 0;
                Boolean foundFirst = false;
                for (Object key : a) {
                    for (int j = line+1; j < (Integer)key; j++){
                        codeLine = fscanner.nextLine();
                        outFinalFile.write(codeLine+"\n");
 //                       if(codeLine.contains("<?php") && foundFirst == false){
 //                           foundFirst = true;
 //                           outFinalFile.write("include(\"includes_awap" + File.separator + "awap_CodeInjection.php\");" + "\n");
//                            if (GlobalDataApp.args_flags[7]==1 && GlobalDataXSS.MainListVulners.size()>0)
//                                outFile.write("include(\"includes_awap" + File.separator + "awap_XSS.php\");" + "\n");
                        //}
                    }
                    codeLine = fscanner.nextLine();
                    String[] b = (String[]) sortedMap.get(key);
                    if (codeLine.contains("{")){
                        int ind = codeLine.indexOf("{");
                        outFinalFile.write(codeLine.substring(0, ind+1) + "\n");
                        codeLine = codeLine.substring(ind+1);
                    }                       
                    outFinalFile.write(b[3] + "\n");
                    outFinalFile.write(b[4] + "\n");
                    //outFile.write(b[2] + "\n");
                    if (codeLine.contains("}")){                      
                        int ind = codeLine.indexOf("}");
                        codeLine = codeLine.substring(0, ind-1);
                        outFinalFile.write(codeLine + "\n");
                        outFinalFile.write("}" + "\n");
                    }
                    //else
                        //outFinalFile.write(codeLine + "\n");
                    line = (Integer)key;
                }

                while (fscanner.hasNextLine()){
                    codeLine = fscanner.nextLine();
                    outFinalFile.write(codeLine+"\n");
                }
                fscanner.close();
                outFinalFile.close();
                //in.delete();
                
                if (type_analyse.equals("single_file") == true || type_analyse.equals("files") == true)
                    bufferWritter.close();
            }
        //}
        if (type_analyse.equals("project") == true)
            bufferWritter.close();
    }


    public static void outputAnalysis(String type_analyse, FileWriter outFile, String diff_date_fidt, List files) throws IOException{
        int vuu = GlobalDataCodeInj.getNumVul(), fpp = GlobalDataCodeInj.getNumFP();
        /*
        Integer j;
        for(Iterator <Integer> it = GlobalDataCodeInj.MainNumVul.values().iterator(); it.hasNext(); ){
            j = it.next();
            vuu += j;
        }

        for(Iterator <Integer> it = GlobalDataCodeInj.MainNumFP.values().iterator(); it.hasNext(); ){
            j = it.next();
            fpp += j;
        }
        */
        
        String setPlainText = "";
        String setBoldText = "";
        if (GlobalDataApp.isWindows.booleanValue() == false){
            setPlainText = "\033[0;0m";
            setBoldText = "\033[0;1m";
        }       
        
        System.out.println(setBoldText +"\n\n  + Type of Analysis: RFI/LFI/DT/SCD/OS/Eval");
        System.out.println("\t     > Summary:" + setPlainText);
        
        if(GlobalDataApp.args_flags[4] == 1){
            outFile.write("\n\n  + Type of Analysis: RFI/LFI/DT/SCD/OS/Eval\n");
            outFile.write("\t     > Summary:\n");
        }
        
        if (vuu + fpp > 0){
            System.out.println("        - Time of analyse: " + diff_date_fidt);
            System.out.println("        - Number of vulnerabilities detected: " + setBoldText + (vuu+fpp) + setPlainText);
            System.out.println("           - Real vulnerabilities: " + setBoldText + vuu + setPlainText);
            System.out.println("           - False positives: " + setBoldText + fpp + setPlainText);
            System.out.println("        - Number of vulnerable files: " +
                    setBoldText + GlobalDataCodeInj.MainListVulners.size() + setPlainText);
            System.out.println("        - List of vulnerable files:");
            
            if(GlobalDataApp.args_flags[4] == 1){
                outFile.write("        - Time of analyse: " + diff_date_fidt+"\n");
                outFile.write("        - Number of vulnerabilities detected: " + (vuu+fpp)+"\n");
                outFile.write("           - Real vulnerabilities: " + vuu+"\n");
                outFile.write("           - False positives: " + fpp+"\n");
                outFile.write("        - Number of vulnerable files: " + GlobalDataCodeInj.MainListVulners.size()+"\n");
                outFile.write("        - List of vulnerable files:\n");
            }

            for(Iterator <ListVulners> it = GlobalDataCodeInj.MainListVulners.values().iterator(); it.hasNext(); ){
                ListVulners lv = it.next();
                System.out.println("\t    " + lv.getFilename());
                
                if(GlobalDataApp.args_flags[4] == 1){
                    outFile.write("\t    " + lv.getFilename()+"\n");
                }
            }

            if (GlobalDataApp.args_flags[5] == 0){
                // code needed for keyboard input
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                String temp;
                System.out.println("\n\nPress enter to view vulnerabilities...");
                temp = br.readLine();
            }
        }
        else{
            System.out.println("        - Time of analyse: " + diff_date_fidt);
            System.out.println("        - Number of vulnerabilities found: " + setBoldText +"none" + setPlainText);
            if(GlobalDataApp.args_flags[4] == 1){
                outFile.write("        - Time of analyse: " + diff_date_fidt +"\n");
                outFile.write("        - Number of vulnerabilities found: none\n");
            }

            return;            
        }      
        
        
        ListVulners lv = null;
        for (Iterator <ListVulners> it = GlobalDataCodeInj.MainListVulners.values().iterator(); it.hasNext();){
            lv = it.next();
            if (GlobalDataApp.args_flags[5] == 0){
                String file = lv.getFilename();
                ManageFiles ff = new ManageFiles (file);
                System.out.println(setBoldText + "\n> > > >  File: " + setPlainText + file + 
                        setBoldText + " < < < <" + setPlainText);
                System.out.println(setBoldText + "     > Information:" + setPlainText);
                System.out.println("        - Number of Lines of Code: " + ff.getNumberLinesFile());             

                if(GlobalDataApp.args_flags[4] == 1){
                    outFile.write("\n> > > >  File: " + file + " < < < <\n");
                    outFile.write("     > Information:\n");
                    outFile.write("        - Number of Lines of Code: " + ff.getNumberLinesFile()+"\n");
                }

                // is a include file?
                if (GlobalDataCodeInj.MainIncludeFilesTable.containsKey(file) == true){
                    System.out.println("        - Is a include file: yes");

                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Is a include file: yes\n");
                    }
                }
                else{
                    System.out.println("        - Is a include file: no");

                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Is a include file: no\n");
                    }
                }

                // list of included files from "regular" or include file
                SymbolTable st = null;
                if (GlobalDataCodeInj.MainSymbolTable.containsKey(file) == true)
                    st = GlobalDataCodeInj.MainSymbolTable.get(file);
                else
                    st = GlobalDataCodeInj.MainIncludeFilesTable.get(file);

                if(st.getIncludeFiles().isEmpty() == false){
                    System.out.println("        - Included files:");
                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Included files:\n");
                    }

                    for (int i = 0; i < st.getIncludeFiles().size(); i++){
                        System.out.println("\t    "+st.getIncludeFiles().get(i));

                        if(GlobalDataApp.args_flags[4] == 1){
                            outFile.write("\t    "+st.getIncludeFiles().get(i)+"\n");
                        }
                    }
                }
                else{
                    System.out.println("        - Included files: none");

                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Included files: none\n");
                    }
                }


                // list of defined user functioms
                if (GlobalDataCodeInj.MainFunctionsTable.containsKey(file) == true){
                    MethodTable mt = GlobalDataCodeInj.MainFunctionsTable.get(file);
                    System.out.println("        - Defined user functions:");
                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Defined user functions:\n");
                    }

                    for (Iterator <MethodSymbol> it1 = mt.getMembers().iterator(); it1.hasNext(); ){    
                        MethodSymbol ms = it1.next();
                        System.out.println("\t  "+ms.getFunctionName());
                        if(GlobalDataApp.args_flags[4] == 1){
                            outFile.write("\t  "+ms.getFunctionName()+"\n");
                        }
                    }
                }
                else{
                    System.out.println("        - Defined user function: none");
                    if(GlobalDataApp.args_flags[4] == 1){
                        outFile.write("        - Defined user function: none\n");
                    }
                }

                // list of vulnerabilities of file
                Vulner v;
                int vuu_f = lv.getListOfVulners().size();
                int fpp_f = 0;
                for (Iterator <Vulner> it1 = lv.getListOfVulners().iterator(); it1.hasNext();){
                    v = it1.next();
                    if (v.IsFP() == 1)
                        fpp_f++;
                }
                vuu_f -= fpp_f;
                
                System.out.println("        - Number of Vulnerabilities detected: " +
                        setBoldText + lv.getListOfVulners().size() + setPlainText); 
                System.out.println("           - Real Vulnerabilities: " +
                        setBoldText + vuu_f + setPlainText);
                System.out.println("           - False positives: " +
                        setBoldText + fpp_f + setPlainText);
                if(GlobalDataApp.args_flags[4] == 1){
                    outFile.write("        - Number of Vulnerabilities detected: "+lv.getListOfVulners().size()+"\n");
                    outFile.write("           - Real Vulnerabilities: "+vuu+"\n");
                    outFile.write("           - False positives: "+fpp_f+"\n");
                }

                analysisOfFile(lv, outFile, file.toString());
                if (it.hasNext() && GlobalDataApp.args_flags[0] == 1){
                    // code needed for keyboard input
                    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                    String temp;
                    System.out.println("\n\nPress enter to view vulnerabilities of next file...");
                    temp = br.readLine();
                }
            }
        }
            
            if(GlobalDataApp.args_flags[0] == 0 && vuu > 0){
                // code needed for keyboard input
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                String temp;

                System.out.println("\n\nPress enter to proceed automatic correction...");
                temp = br.readLine();

                try{
                LinesToCorrect ltc;
                int i = GlobalDataCodeInj.MainLinesToCorrect.size();
                for (Iterator <LinesToCorrect> it = GlobalDataCodeInj.MainLinesToCorrect.values().iterator(); it.hasNext();){
                    ltc = it.next();
                    OutputAnalysisCodeInj.outputAnalysisWithCorrection(type_analyse, ltc.getNameFile(), ltc, i);
                    i--;
                }
                } catch (Exception e){}                
                
                //OutputAnalysisCodeInj.outputAnalysisWithCorrection(type_analyse, lv.getFilename());
                System.out.println("\n\nAutomatic correction complete !!!");
                if(GlobalDataApp.args_flags[4] == 1){
                    outFile.write("\n\nAutomatic correction complete !!!\n");
                }
            }

        //}
    }

    private static void analysisOfFile(ListVulners lv, FileWriter outFile, String filename) throws IOException{
        Vulner v;
        String cl, correctedCode = "", aux = "", aux1 = "", vulnerableCode = "", f1="", f;
        String correctedCode_f = "", vulnerableCode_f = "";
        Iterator <Vulner> it;
        int i=0;
        LinesToCorrect ltc;
        Object key;
        String typeVul="";

        String setPlainText = "";
        String setBoldText = "";
        if (GlobalDataApp.isWindows.booleanValue() == false){
            setPlainText = "\033[0;0m";
            setBoldText = "\033[0;1m";
        }

        for (it = lv.getListOfVulners().iterator(); it.hasNext();){
            v = it.next();
            typeVul = v.getTypeVuln();
            
            try{
            // escrever vulnerabilidade no ecra
            correctedCode = setBoldText + "\tCorrected code:" + setPlainText + "\n";
            vulnerableCode = setBoldText + "\n\tVulnerable code:" + setPlainText + "\n";
            
            // escrever vuln para file
            if(GlobalDataApp.args_flags[4] == 1){
                correctedCode_f = "\tCorrected code: \n";
                vulnerableCode_f = "\n\tVulnerable code: \n";                
            }
            for (int l = v.getLinesOfVulner().size() -1; l >= 0; l--){
                f = "";
                if (v.getFilesOfVulner().get(l).equals(lv.getFilename()) == false)
                    f = (String) v.getFilesOfVulner().get(l);

                ManageFiles fff = new ManageFiles ((String) v.getFilesOfVulner().get(l));
                cl = fff.getLineOfCode((Integer) v.getLinesOfVulner().get(l));
                aux = "\t" + v.getLinesOfVulner().get(l) + ": "+ cl + "\n";
                vulnerableCode = vulnerableCode + aux;
                vulnerableCode_f = vulnerableCode_f + aux;

                if (f.equals("") == false){
                    aux = "\t    (" + f + ")" + "\n";
                    vulnerableCode = vulnerableCode + aux;
                    vulnerableCode_f = vulnerableCode_f + aux;
                }
                           
                if (v.IsFP() == 0){
                    // escrita do corrected code no ecra
                    ltc = GlobalDataCodeInj.MainLinesToCorrect.get(v.getFileOfLineToSanitize());
                    Map sortedMap = new TreeMap(ltc.getMapLinesToCorrectArray());
                    if (ltc.getMapLinesToCorrectArray().containsKey(v.getLinesOfVulner().get(l)) == true){
                        key = v.getLinesOfVulner().get(l);
                        String[] b = (String[]) sortedMap.get(key);
                        //f1 = b[2];
                        //typeVul = GlobalDataCodeInj.getTypeVulInjection(f1);
                        
                        if (typeVul.equals("PHP Code Injection") == true){
                            aux1 = "if ( $san_line = " + b[0] + " != 1)";
                            aux = "\t" + (Integer)key + ": " + aux1 +"\n";
                            correctedCode = correctedCode + aux;
                            correctedCode_f = correctedCode_f + aux;

                            aux = "\t" + ((Integer)key + 1) + ":\t $san_line;\n";                        
                        }
                        else{
                            aux1 = "if (" + b[0] + " == 0)";
                            aux = "\t" + (Integer)key + ": " + aux1 +"\n";
                            correctedCode = correctedCode + aux;
                            correctedCode_f = correctedCode_f + aux;

                            //aux1 = aux1 + b[2];
                            aux = "\t" + ((Integer)key + 1) + ":\t" + b[1] +"\n";
                            //aux = "\t" + (Integer)key + ": " + b[0] +"\n";
                        }
                    }
                    else
                        aux =  "\t" + v.getLinesOfVulner().get(l) + ": "+ cl + "\n";
                    correctedCode = correctedCode + aux;
                    correctedCode_f = correctedCode_f + aux;
                }
            }
            }catch (Exception e){
                aux = "\tSome unexpected error in analysis happened. Sorry :-(";
                correctedCode = correctedCode + aux;
                correctedCode_f = correctedCode_f + aux;
            }            
           

            //String typeVul = getTypeVulInjection(f1);
            if (v.IsFP() == 0){
                System.out.println(setBoldText + "\n\t= = = =  Vulnerability n.: " + (i+1) + "  = = = =");
                System.out.println("\tType: " + typeVul + setPlainText);
                System.out.println(vulnerableCode);           
                System.out.println(correctedCode);
            }
            else{
                System.out.println(setBoldText + "\n\t= = = =  Vulnerability n.: " + (i+1) + "   >>> is a possible False Positive <<<  = = = =");
                System.out.println("\tType: " + typeVul + setPlainText);
                System.out.println(vulnerableCode);

                String justifyFP = v.getJustificationOfFP();
                System.out.println(setBoldText + "\n\tFalse Positive justification:" + setPlainText);
                System.out.println(justifyFP);
            }
            
            if(GlobalDataApp.args_flags[4] == 1){
                if (v.IsFP() == 0){
                    outFile.write("\n\t= = = =  Vulnerability n.: " + (i+1) + "  = = = =\n");
                    outFile.write("\tType: " + typeVul + "\n");
                    outFile.write(vulnerableCode_f);
                    outFile.write("\n" + correctedCode_f + "\n");
                }
                else{
                    outFile.write("\n\t= = = =  Vulnerability n.: " + (i+1) + "   >>> is a possible False Positive <<<  = = = =\n");
                    outFile.write("\tType: " + typeVul + "\n");
                    outFile.write(vulnerableCode_f);
                    String justifyFP = v.getJustificationOfFP();
                    outFile.write("\n\tFalse Positive justification:\n" + justifyFP);
                }
            }
            i++;
        }
    }
} public class buildWalkerTree_sqli {
       
    // *** CONSTRUCTORS
    public buildWalkerTree_sqli(CommonTreeNodeStream nodes, String filename, Map mst, Map mift, Map mft, Map mftt, Map mtt, UntaintedTable mus, Map mlct, Map mct, Map mobjt, List files) throws IOException, RecognitionException {
        try {           
            // Navegate into AST by walker tree
            Sqli def = new Sqli(nodes, mst, mift, mft, mftt, mtt, mus, mlct, mct, mobjt, filename, files);
            Sqli.prog_return prog = def.prog(); 
        } catch (RecognitionException ex) {
            Logger.getLogger(buildWalkerTree_sqli.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception e) {}

    }

} public class TaintedTable implements ScopeTainted{
    String nameFile;
    String functionNameCall = "";
    Map<String, RootTaintedSymbol> symbolsRootTainted;

    
    /* CONSTRUCTOR */
    public TaintedTable(String filename) {
     symbolsRootTainted = new LinkedHashMap<String, RootTaintedSymbol>();
     this.nameFile = filename;
    }
    
    // Constructor to user function and class method tainted table
    public TaintedTable(String functionName, String filename) {
     symbolsRootTainted = new LinkedHashMap<String, RootTaintedSymbol>();
     this.nameFile = filename;
     this.functionNameCall = functionName;
    }

    /* METHODS that satisfy TaintedScope interface*/

    /*
     * Give the the name of taintedScope. How this scope don't have parent, then
     * your name is "globaltainted"
     */
    public String getScopeTaintedName() {
        return nameFile;
    }
    
    /*
     * Give the the name of user function or class method.
     */
    public String getFunctionNameCall() {
        return functionNameCall;
    }    

    /*
     * If the tainted scope is enclosing in another (if have parent), give the
     * name of the parent scope.
     * How the Tainted Table is the main scope, then don't have parent (null)
     */
    public ScopeTainted getEnclosingScopeTainted() {
    	return null;
    }

    /*
     * Give the main Map that contain the tainted variables
     */
    public Map getTaintedMembers() {
        return symbolsRootTainted;
    }

    /*
     * Insert a tainted variable in main Map.
     * Each member of main Map is a RelatedTaintedSymbol, composed by:
     * Map VariableTaintedSymbol and List to store code lines of tainted variables
     */
    public void define(RootTaintedSymbol rts) {
    	symbolsRootTainted.put(rts.getScopeTaintedName(), rts);
    }

    /*
     * Give RelatedTaintedSymbol from main Map, search by a gived name
     */
    public RootTaintedSymbol resolve(String name) {
    	return symbolsRootTainted.get(name);
    }

    public TaintedTable copyTaintedTable() {
        TaintedTable tab = new TaintedTable("aux");
        for(Iterator <Symbol> it = this.getTaintedMembers().values().iterator(); it.hasNext();){
		Symbol cs = it.next();
            try {
                tab.getTaintedMembers().put(cs.getName(), cs.clone());
            } catch (CloneNotSupportedException ex) {
                Logger.getLogger(TaintedTable.class.getName()).log(Level.SEVERE, null, ex);
            }
	 }
    	return tab;
        
    }
    
    public void copyToMTS(TaintedTable m, UntaintedTable mu) { // m = mts
        Iterator <RootTaintedSymbol> it = this.getTaintedMembers().values().iterator(); // mts_aux
        RootTaintedSymbol rts, rts_m;
        RelatedTaintedSymbol rtt=null, rtt_m=null;
        VariableTaintedSymbol vts = null, vts_m;
        for(;it.hasNext();){//mts_aux
            rts = it.next();
            if (m.getTaintedMembers().containsKey(rts.getScopeTaintedName()) == false)
                m.getTaintedMembers().put(rts.getScopeTaintedName(), rts);
            else{
                rts_m = (RootTaintedSymbol) m.getTaintedMembers().get(rts.getScopeTaintedName());
                Iterator <Integer> it1;
                Iterator <String> it2 = rts.getFilesList().iterator();
                int i;
                String s;
                for (it1 = rts.getLinesList().iterator(); it1.hasNext();){
                    i = it1.next();
                    s = it2.next();
                    if (i != 0){ // as var globais em mts_aux tem linha = 0
                        if (rts_m.getLinesList().contains(i) == false ||
                            rts_m.getLinesList().contains(i) == true && rts_m.getFilesList().contains(s) == false){
                            rts_m.getLinesList().add(i);
                            rts_m.getFilesList().add(s);
                            for (Iterator <RelatedTaintedSymbol> it3 = rts.getListTaintedMembers().iterator(); it3.hasNext();){
                                rtt = it3.next();
                                if (rtt.getLineRts() == i && rtt.getFileRts().equals(s)){
                                    rts_m.define(rtt);
                                    break;
                                }
                            }
                        }
                        else{
                            // Obter RelatedTaintedSymbol de mts_princ de i e s
                            for (Iterator <RelatedTaintedSymbol> it3 = rts_m.getListTaintedMembers().iterator(); it3.hasNext();){
                                rtt_m = it3.next();
                                if (rtt_m.getLineRts() == i && rtt_m.getFileRts().equals(s))
                                    break;
                            }
                            // Obter RelatedTaintedSymbol de mts_aux de i e s para copiar os vts para mts_princ
                            for (Iterator <RelatedTaintedSymbol> it3 = rts.getListTaintedMembers().iterator(); it3.hasNext();){
                                rtt = it3.next();
                                if (rtt.getLineRts() == i && rtt.getFileRts().equals(s))
                                    break;
                            }
                            
                            Iterator <VariableTaintedSymbol> it3 = rtt.getTaintedMembers().values().iterator();
                            for (;it3.hasNext();){
                                vts = it3.next();
                                if (rtt_m.getTaintedMembers().containsKey(vts.getName()) == false){
                                    rtt_m.define(vts);
                                }
                                else{
                                    vts_m = (VariableTaintedSymbol) rtt_m.getTaintedMembers().get(vts.getName());
                                    Iterator <Integer> it4 = vts.getVariableLines().iterator();
                                    Iterator <String> it5 = vts.getVariableFiles().iterator();
                                    for (; it4.hasNext();){
                                        int ii = it4.next();
                                        String ss = it5.next();
                                        if (vts_m.getVariableLines().contains(ii) == false ||
                                            vts_m.getVariableLines().contains(ii) == true && vts_m.getVariableFiles().contains(ss) == false){
                                            vts_m.getVariableLines().add(ii);
                                            vts_m.getVariableFiles().add(ss);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                
                // Se rts passou de untainted (vindo de mus) para tainted (em mts_aux), retirar rts de mus
                Symbol sym = rts.getSymbol();
                if (mu.existSymbol(sym.getName()) == true) // verify if symbol pass to untaint to taint
                    mu.removeUntaintSymbol(sym);
            }
        }
    }
    
    public void copyGlobalsToMTS(TaintedTable mts_princ , UntaintedTable mus_princ , UntaintedTable mus_aux, MethodSymbol meth_sym_clone){
        for(Iterator <Symbol> it = meth_sym_clone.getGlobalVarsOfFunction().values().iterator(); it.hasNext();){
            Symbol sym = it.next();
            if (this.getTaintedMembers().containsKey(sym.getName()) == true && mus_aux.existSymbol(sym.getName()) == false){
                if (mts_princ.getTaintedMembers().containsKey(sym.getName()) == true){
                    // Se passou de untainted para tainted, retirar de untainted
                    if(mus_princ.existSymbol(sym.getName()) == true)
                        mus_princ.removeUntaintSymbol(sym);                   
                else{
                    RootTaintedSymbol rts_aux = (RootTaintedSymbol) this.getTaintedMembers().get(sym.getName());
                    RootTaintedSymbol rts_princ = (RootTaintedSymbol) mts_princ.getTaintedMembers().get(sym.getName());
                    int index = rts_aux.getLinesList().size()-1;
                    int i = (Integer) rts_aux.getLinesList().get(index);
                    String s = (String) rts_aux.getFilesList().get(index);
                    RelatedTaintedSymbol rtt_aux = (RelatedTaintedSymbol) rts_aux.getListTaintedMembers().get(index);
                    if (rts_princ.getLinesList().contains(i) == false){
                        rts_princ.getLinesList().add(i);
                        rts_princ.getFilesList().add(s);
                        rts_princ.getListTaintedMembers().add(rtt_aux);
                    }
                    else{
                        int index_princ = rts_princ.getLinesList().indexOf(i);
                        if (rts_princ.getFilesList().get(index_princ).equals(s) == false){
                            rts_princ.getLinesList().add(i);
                            rts_princ.getFilesList().add(s);
                            rts_princ.getListTaintedMembers().add(rtt_aux);
                        }
                        else{
                            rts_princ.getListTaintedMembers().set(index_princ, rtt_aux);
                        }
                    }
                }
                }
            }
        }
    }

public void removeDuplicates(Symbol sym){
    if (this.getTaintedMembers().containsKey(sym.getScope().getScopeName()) == true){
        RootTaintedSymbol Rrt = (RootTaintedSymbol) this.getTaintedMembers().get(sym.getScope().getScopeName());
        if (Rrt.getLinesList().size() > 1){
            int last_i = (Integer) Rrt.getLinesList().get(Rrt.getLinesList().size()-1);
            String last_s = (String) Rrt.getFilesList().get(Rrt.getFilesList().size()-1);
            
            int penultimate_i = (Integer) Rrt.getLinesList().get(Rrt.getLinesList().size()-2);
            String penultimate_s = (String) Rrt.getFilesList().get(Rrt.getFilesList().size()-2);
            if (last_i == penultimate_i && last_s.equals(penultimate_s) == true){
                Rrt.getLinesList().remove(Rrt.getLinesList().size()-1);
                Rrt.getFilesList().remove(Rrt.getFilesList().size()-1);
            }
        }
     }
}    
    
    
    public void printMTS(){
        TaintedTable mts = this;
        Iterator <RootTaintedSymbol> it = mts.getTaintedMembers().values().iterator();
        System.out.println("\n\nTainted File = "+mts.getScopeTaintedName()+"\n");
        System.out.println("Nº de Vars/funcoes tainted = "+mts.getTaintedMembers().size()+"\n");
        System.out.println("Mapa de Vars/funcoes tainted e suas dependencias:\n");
        System.out.println("**************************************************\n");
        VariableTaintedSymbol aux1;
        RelatedTaintedSymbol aux;
        RootTaintedSymbol raux;
        for(; it.hasNext();){
            raux = it.next();
            System.out.println("\nROOT_VAR: "+raux.getName());
            for(Iterator <RelatedTaintedSymbol> it2 = raux.getListTaintedMembers().iterator(); it2.hasNext();){
                aux = it2.next();
                System.out.println("\tLine: "+aux.getLineRts()+"  FILE: "+aux.getFileRts());
                Iterator <VariableTaintedSymbol> it3 = aux.getTaintedMembers().values().iterator();
                for(;it3.hasNext(); ){
                    aux1 = it3.next();
                    System.out.println("\t\tName: "+aux1.getName()+"  Lines: "+aux1.getVariableLines().toString()+
                                       "  FILES: "+aux1.getVariableFiles().toString());
                }
            }
        }
    }    
    
    
    public void cleanAll(){
        Collection <RootTaintedSymbol> c = symbolsRootTainted.values();
    	c.removeAll(c);
    	symbolsRootTainted.clear();
    }
    
    @Override
    public String toString() {
    	return getScopeTaintedName()+":"+symbolsRootTainted;
    }

    public void define(Symbol sym) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public List getListTaintedMembers() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

}
import org.homeunix.wap.utils.GlobalDataApp;
import org.homeunix.wap.utils.Dates;
import org.homeunix.wap.utils.ManageFiles;
import org.homeunix.wap.utils.buildAST;
import org.homeunix.wap.table.symbol.SymbolTable;
import org.homeunix.wap.table.symbol.Symbol;
import org.homeunix.wap.table.symbol.MethodTable;
import org.homeunix.wap.table.symbol.MethodSymbol;
import org.homeunix.wap.table.symbol.Scope;
import org.homeunix.wap.sqli.OutputAnalysisSqli;
import org.homeunix.wap.sqli.FuncAndIncSQLI;
import org.homeunix.wap.sqli.GlobalDataSqli;
import org.homeunix.wap.XSS.FuncAndIncXSS;
import org.homeunix.wap.XSS.GlobalDataXSS;
import org.homeunix.wap.XSS.OutputAnalysisXSS;
import org.homeunix.wap.XSS.buildWalkerTree_XSS;
import org.homeunix.wap.CodeInjection.GlobalDataCodeInj;
import org.homeunix.wap.CodeInjection.buildWalkerTree_CodeInj;
import org.homeunix.wap.CodeInjection.FuncAndIncCodeInj;
import org.homeunix.wap.CodeInjection.OutputAnalysisCodeInj;
import org.homeunix.wap.sqli.buildWalkerTree_sqli;
import org.homeunix.wap.table.tainted.TaintedTable;
import java.io.*;
import java.lang.reflect.Field;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.tree.CommonTreeNodeStream;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */


/**
 *
 * @author iberiam
 *
 * Classe que faz a analise dos tipos de analise passados nos argumentos da aplicacao
 */
public class wapAnalysis {
    List<String> fileList = new ArrayList<String>();
    SymbolTable st = null;

    public wapAnalysis (List<String> inputs, String type_analyse, String fileToOut) throws IOException {
        int i, j;
        String input="";
        FileWriter outFile = null;
        String diff_date=null, diff_date_sqli=null, diff_date_fidt=null, diff_date_xss=null;
        Long sumSecs_sqli = 0L, sumSecs_fidt = 0L, sumSecs_xss = 0L;
        
        if(GlobalDataApp.args_flags[4] == 1){
            File out = new File(fileToOut);
            outFile = new FileWriter(out);
        }
        
        //Inicio do TIMER        
        Date date = new Date(System.currentTimeMillis());
        Long begin_date = date.getTime();

        System.out.println("    * Collecting the number and type of files to analyse ......................... ");
        
        
        
        if (type_analyse.equals("files") == true){
            for (i = 0; i < inputs.size(); i++) {
                input = inputs.get(i);
                fileList.add(input);
            }
        }
        
        if (type_analyse.equals("project") == true){
            input = inputs.get(0);           
            ManageFiles projectDirectory = new ManageFiles(input);
            projectDirectory.searchPhpFiles(fileList);

            if (fileList.isEmpty() == true){
                String s = "There are no type of php files in the specified Project Directory... \n" + input;
                System.out.println(s);
            }
            else{
                projectDirectory.searchIndexPhp(fileList);
                System.setProperty("base.dir", input);
            }
        }
        //System.out.println("done");
        
        int num = fileList.size();
        //System.out.println("done\n");
        System.out.println("\n    * Generating AST's ........................................................... ");
        //System.out.println("done\n");
        
        System.out.println("\n    * Taint Analysis .............................................................");
        
        if(GlobalDataApp.args_flags[3] == 1)
        System.out.println("      - SQL Injection ");
        
        if(GlobalDataApp.args_flags[6] == 1)
        System.out.println("      - RFI, LFI, DT, SCD, OSCI and PHP code injection ");
        
        if(GlobalDataApp.args_flags[7] == 1)
        System.out.println("      - Cross Site Scripting - XSS ");

        System.out.println("\n        (this task can take several minutes, depending on number of the files to");        
        System.out.println("         analyze. So, you can take a coffee or something else :-) )");
        
        // Para ambos type_analyse (files or project)
        // Create AST and performs walker tree
        for(i=0; i<num; i++){
            input = fileList.get(i);
            CommonTreeNodeStream nodes = null;
            
            // Create AST
            try{
                buildAST ast = new buildAST(input, 1);
                nodes = ast.getNodes();
            } catch (IOException e){
                System.out.println("Error in processing of the file: "+input);
                fileList.remove(i);
                num--;
            }


            // SQLI - performs walker tree to create symboltables
            if(GlobalDataApp.args_flags[3] == 1){
                
                // inicio TIMER SQLI
               Date date1 = new Date(System.currentTimeMillis());
               Long begin_date_sqli = date1.getTime();

                // build walker tree to SQLI
               try{
                buildWalkerTree_sqli sqli = new buildWalkerTree_sqli(nodes, input, GlobalDataSqli.MainSymbolTable, GlobalDataSqli.MainIncludeFilesTable,