/*
         * Writes the results of the computation to a file.
         * First line is the headers (if exist) with the new columns added.
         * Each following line is the contingency table with the Fisher scores, FDR and q-value
         * */
        private List <string> getResults(List <ContingencyTable> actTables
                                         , Map <double, FDRData> slFDR)
        {
            int iTable = 0;
            ContingencyTable ctCurrent = null;
            double           dFisherTest = 0.0, dCurrentQValue = 0.0;
            double           dNextKey    = 0;
            string           sHeader     = "";
            FDRData          fdCurrent   = null;
            string           sOutputLine = "";
            List <string>    lResults    = new List <string>();
            bool             bFiltering  = m_pmEvaluatePi == PiMethod.Filtering;

            if (m_bReportProgress)
            {
                m_bContinue = m_prReport.reportPhase("Writing results.");
            }

            sHeader = m_sColumnHeaders + "\tp-value";
            if (m_bFullOutput)
            {
                sHeader += "\tpooled p-value\t";
                if (bFiltering)
                {
                    sHeader += "filtering pi\t";
                }
                if (m_bPositiveFDR)
                {
                    sHeader += "pr(R(p)>0)\tpFDR";
                }
                else
                {
                    sHeader += "FDR";
                }
            }
            sHeader += "\tq-value";
            lResults.Add(sHeader);


            List <KeyValuePair <double, double> > lPToQMappings = new List <KeyValuePair <double, double> >();

            //When the huge flag is used, the tables are not kept.
            //We now have to go over the entire input file, read each table,
            //compute p-value for it, and map it into FDR and q-value.
            if (m_bHuge)
            {
                StreamReader sr    = m_fiInput.OpenText();
                string       sLine = "";
                double       dFisherScoreCutoff = 0.0;
                bool         bUseTable          = true;

                if (m_dFDRCutoff > 0.0)
                {
                    dFisherScoreCutoff = mapFDR2FisherScore(slFDR, m_dFDRCutoff);
                }

                iTable = 0;
                while (!sr.EndOfStream)
                {
                    sLine = sr.ReadLine();
                    if (sLine.Length > 0)
                    {
                        ctCurrent = new ContingencyTable(sLine, m_cTableNamesColumns);
                        bUseTable = ctCurrent.validate();
                        if (bUseTable)
                        {
                            dFisherTest    = round(ctCurrent.getFisher2TailPermutationTest(dFisherScoreCutoff));
                            dNextKey       = getNextKey(slFDR.KeyList, dFisherTest);
                            fdCurrent      = slFDR[dNextKey];
                            dCurrentQValue = round(fdCurrent.QValue);
                            if (dCurrentQValue <= m_dFDRCutoff)
                            {
                                sOutputLine  = ctCurrent.ToString() + "\t";
                                sOutputLine += fdCurrent.getData(m_bFullOutput, bFiltering, m_bPositiveFDR);
                                lResults.Add(sOutputLine);
                                lPToQMappings.Add(new KeyValuePair <double, double>(dNextKey, dCurrentQValue));//will not work for huge because multiple tables will be missed
                            }
                        }
                        iTable++;
                        if (m_bReportProgress && (iTable % MAX_REPROT_POINT == 0))
                        {
                            m_bContinue = m_prReport.reportProcessedTables(iTable, m_cTables);
                            m_bContinue = m_prReport.reportMessage("Written " + iTable + " tables.", true);
                        }
                    }
                }
                sr.Close();
            }
            else//Not huge - all data is already in memory - just write the tables.
            {
                for (iTable = 0; iTable < actTables.Count; iTable++)
                {
                    ctCurrent      = (ContingencyTable)actTables[iTable];
                    dFisherTest    = ctCurrent.getFisher2TailPermutationTest();
                    dNextKey       = getNextKey(slFDR.KeyList, dFisherTest);
                    fdCurrent      = slFDR[dNextKey];
                    dCurrentQValue = floor(fdCurrent.QValue);
                    if (dCurrentQValue <= m_dFDRCutoff)
                    {
                        sOutputLine  = ctCurrent.ToString() + "\t";
                        sOutputLine += fdCurrent.getData(m_bFullOutput, bFiltering, m_bPositiveFDR);
                        lPToQMappings.Add(new KeyValuePair <double, double>(dNextKey, dCurrentQValue));
                        lResults.Add(sOutputLine);
                    }
                    if (m_bReportProgress && (iTable % MAX_REPROT_POINT == 0))
                    {
                        m_bContinue = m_prReport.reportProcessedTables(iTable, actTables.Count);
                    }


                    //swMarginalPValues.WriteLine(fdCurrent.PValue);
                }
            }
            PToQMapping = lPToQMappings;
            if (m_bReportProgress)
            {
                m_bContinue = m_prReport.reportMessage("Done writing results", true);
            }



            //swMarginalPValues.Close();


            return(lResults);
        }