f.Fisher_FDR <- function (exp.genes, uni.genes, GS.ls, pval_obs.nv, iter.n = 2000)
	{

	cat ("\n")

	# 1) PRE-PROCESSING

	# Reduce everything to the universe

	f.int_uni <- function (input.genes)
		{return (intersect (input.genes, uni.genes))}

	GS.ls <- lapply (GS.ls, f.int_uni)

	exp.genes <- intersect (exp.genes, uni.genes)

	# 2) COMPUTING
	
	exp.n <- length (exp.genes)
	uni.n <- length (uni.genes)

	dummy.ls <- as.list (rep (exp.n, iter.n))
	
	f.sample_Unit <- function (l.n)
		{return (sample (uni.genes, l.n))}
	
	exp_r.ls <- lapply (dummy.ls, f.sample_Unit)

	output.nv <- numeric (3)

	f.Fisher_PvalR_Unit <- function (exp.genes)
		{
			
		f.Enr_Fisher_Unit <- function (GS.genes)
			{
			enr.n    <- length (intersect (exp.genes, GS.genes))
			GS.n     <- length (GS.genes)

			table.mx <- matrix (
					ncol = 2, 
					nrow = 2, 
					data = c (
						enr.n, 
						GS.n  - enr.n, 
						exp.n - enr.n, 
						uni.n - (GS.n + exp.n - enr.n)
						), 
					byrow = T
					)

			pvalue.n <- fisher.test (table.mx, alternative = "greater")$p.value
			return (pvalue.n)
			}

		cat ("r")
			
		pvalues.nv <- sapply (GS.ls, f.Enr_Fisher_Unit)
		return (pvalues.nv)
		}
	
	pval_r.mx <- sapply (exp_r.ls, f.Fisher_PvalR_Unit)
	
	pval_obs.ls <- as.list (pval_obs.nv)
	
	f.count_Unit <- function (thr.n)
		{
		rand.n <- sum (pval_r.mx <= thr.n) / iter.n
		obs.n  <- sum (pval_obs.nv <= thr.n)
		return (rand.n / obs.n)
		}
	
	fdr.nv <- sapply (pval_obs.ls, f.count_Unit)
	
	return (fdr.nv)
		
	}