code: private ArrayList<List<?>> permute(List<?>... lists)
  	{
  
  		ArrayList<List<?>> output = new ArrayList<List<?>>();
  		if (lists.length == 0)
  		{
  			output.add(new ArrayList<Object>());
  			return output;
  		}
  
  		for (List<?> list : lists)
  		{
  			// We require that the result has as many elements as the number
  			// of lists passed - so if a list is empty, add in a single null.
  			if (list.size() == 0)
  				list.add(null);
  		}
  
  		List<?> first = lists[0];
  		List<?>[] rest = Arrays.copyOfRange(lists, 1, lists.length);
  
  		for (Object x : first)
  		{
  			ArrayList<List<?>> permuted = permute(rest);
  			for (List<?> tocombine : permuted)
  			{
  				ArrayList<Object> l = new ArrayList<Object>();
  				l.add(x);
  				l.addAll(tocombine);
  				output.add(l);
  			}
  		}
  
  		return output;
  	}
docs: /*
  Given two lists, this creates a list of permutations of those lists. e.g.
  Given [1,2], [[3,4]], returns [[1,3],[1,4],[2,3],[2,4]]