### Question:
StrandBiasTableUtils { public static Double FisherExactPValueForContingencyTable(int[][] originalTable) { final int[][] normalizedTable = normalizeContingencyTable(originalTable); int[][] table = copyContingencyTable(normalizedTable); int[] rowSums = { sumRow(table, 0), sumRow(table, 1) }; int[] colSums = { sumColumn(table, 0), sumColumn(table, 1) }; int N = rowSums[0] + rowSums[1]; int sampleSize = colSums[0]; int numberOfNonSuccesses = rowSums[1]; int numberOfSuccesses = rowSums[0]; int lo = Math.max(0, sampleSize - numberOfNonSuccesses); int hi = Math.min(sampleSize, numberOfSuccesses); if (lo == hi) { return 1.0; } final HypergeometricDistribution dist = new HypergeometricDistribution(N, numberOfSuccesses, sampleSize); double pCutoff = dist.probability(table[0][0]) * REL_ERR; double pValue = 0.0; for(int i = lo; i <= hi; i++){ double pValuePiece = dist.probability(i); if(pValuePiece <= pCutoff) { pValue += pValuePiece; } } return Math.min(pValue, 1.0); }  static Double FisherExactPValueForContingencyTable(int[][] originalTable); static List<Integer> getContingencyArray( final int[][] table ); static void printTable(final String name, final int[][] table); static int [][] copyContingencyTable(int [][] t);  }### Answer:
@Test(dataProvider = "UsingTable") public void testPValueForContingencyTable(final int refpos, final int refneg, final int altpos, final int altneg, double expectedPvalue) throws Exception { final int[][] contingencyTable = new int[2][2]; contingencyTable[0][0] = refpos; contingencyTable[0][1] = refneg; contingencyTable[1][0] = altpos; contingencyTable[1][1] = altneg; final double pvalue = StrandBiasTableUtils.FisherExactPValueForContingencyTable(contingencyTable); Assert.assertEquals(pvalue, expectedPvalue, DELTA_PRECISION, "Pvalues"); }