getNextPartitions <-
function(G,independenceClusters){
  
  if(length(G)==1) return(G)
  
  #test if A subset B
  isSubset = function(A,B){
    
    lengthA = length(A)
    checkAll = logical(lengthA)
    
    #check if A[i] \in B
    for(i in 1:lengthA)
      checkAll[i] = any(A[i]==B)
    
    #check if all A[i] in B
    return(all(checkAll))
  }
  
  #checks if each set of G is a subset of any set in independenceClusters
  isValidPartition = function(G,independenceClusters){
    
    #have to have same length
    if(length(unlist(independenceClusters)) != length(unlist(G)))
      return(FALSE)
    
    #same elements in partitions ? 
    if( any(sort(unlist(independenceClusters))!=sort(unlist(G))) )
      return(FALSE)
    
    rG = length(G)
    r  = length(independenceClusters)  
    
    #checkvector of is set is subset of any set in indClust.
    checkVector = logical(rG)
    
    for(i in 1:rG){
      checkvectorTMP = logical(r) 
      for(j in 1:r){
        checkvectorTMP[j] = isSubset(A=G[[i]],B=independenceClusters[[j]]) 
      }
      checkVector[i] = any(checkvectorTMP)
    }
    
    return(all(checkVector))
  }
  
  #given a partition G this functions finds all partitions combined two of the sets
  getAllSmallerPartitions = function(G){
    
    #set length of partition
    r= length(G)
    
    #get all possible combinations
    com = subsets(r, 2, v = 1:r)
    N=dim(com)[1]
    
    Glist = list()
    for(i in 1:N){
      j0 = com[i,] # j0 is vector, these groups should be combined
      Gtmp = G
      Gtmp[[(j0[1])]] = c(G[[(j0[1])]],G[[(j0[2])]])
      Gtmp[[(j0[2])]] = NULL
      Glist[[i]] = Gtmp
    }
    return(Glist)
  }
  
  #calculate all possible next partitions
  candidatePartitions = getAllSmallerPartitions(G)
  rCand = length(candidatePartitions)
  
  #only valid partitions should be kept...
  #initialize vecor
  keepThese = rep(FALSE,rCand)
  
  #check if a possible partition is valid
  for(i in 1:rCand){
    if(isValidPartition(G=candidatePartitions[[i]],independenceClusters))
      keepThese[i]=TRUE 
  }
  
  return(candidatePartitions[keepThese])
  
}
