`CLEAN` <-
function(tree, allGenes, CategoryID2GeneID, CategoryID2Desc, refGenes, maxSize=1000, minSize=10, maxNumOfClusters=NULL, sigFDR = 0.1,
		minGenesInCategory=10, maxGenesInCategory=1000, inBkg=TRUE, estimateNullDistribution = FALSE, 
		saveDataObjects = FALSE, verbose = TRUE) {
	
	l <- geneSigInClustering(tree = tree, allGenes = allGenes, CategoryID2GeneID = CategoryID2GeneID,
		refGenes = refGenes, maxSize = maxSize, minSize = minSize, maxNumOfClusters=maxNumOfClusters, 
		minGenesInCategory = minGenesInCategory, maxGenesInCategory = maxGenesInCategory, 
		verbose=verbose, inBkg = inBkg, sigFDR = sigFDR)
	
	geneMatrixSig <- matrix(1, dim(l$geneMatrixSigs)[1], dim(l$geneMatrixSigs)[2])
	refCategories <- l$refCategories 
	for(i in 1:length(l$sigCategories)) {
		clusterGenes <- refCategories$AllGeneIDs[l$allClusters[[i]]]
		if(!is.null(l$sigCategories[[i]])) {
			if(dim(l$sigCategories[[i]])[1] > 0) {
				for(j in 1:(dim(l$sigCategories[[i]])[1])) {
					categoryGenes <- unique(refCategories$CategoriesWithGenes[[as.character(l$sigCategories[[i]][j,1])]])
					index <- intersect(l$allClusters[[i]][!is.na(match(clusterGenes, categoryGenes))], which(geneMatrixSig[, i] > l$sigCategories[[i]][j,3]))
					geneMatrixSig[index, i] <- l$sigCategories[[i]][j,3]
				}
			}
		}
	}
	CLEANscore <- -log10(apply(geneMatrixSig, 1, min))

	if(estimateNullDistribution) {
		CLEANscore_nullDistr <- geneSigInClustering_nullDistr(allClusters = l$allClusters, 
			allGenes = allGenes[sample(length(allGenes),length(allGenes))], 
			CategoryID2GeneID = CategoryID2GeneID, refCategories = l$refCategories,  
			minGenesInCategory = minGenesInCategory, maxGenesInCategory = maxGenesInCategory, 
			verbose = verbose, inBkg = inBkg, sigFDR = sigFDR)
	} else {
		CLEANscore_nullDistr <- NULL
	}
	
	if(any(l$minFDR > 0)) cwCLEANscore <- pruneMinFDR(l) else cwCLEANscore <- l$sminFDR

	if(!saveDataObjects) {
		l$geneMatrixSigs <- NULL
		l$geneMatrixORs <- NULL
	}
	
	list(c(l, CategoryID2Desc = CategoryID2Desc, allGenes = list(allGenes), 
		CLEANscore = list(CLEANscore), cwCLEANscore = list(cwCLEANscore), 
		CLEANscore_nullDistr = list(CLEANscore_nullDistr)))
}
