@SuppressWarnings("unchecked")
	public static <E> E[][] powerSet(E[] set) {
		if (set == null)
			return null;
		
		int setLength = set.length;
		Class<?> setClass = set.getClass().getComponentType();

		E[][] sets = (E[][]) Array.newInstance(set.getClass(), 1 << setLength);
		sets[0] = (E[]) Array.newInstance(setClass, 0);
		
		// iterate through the set, building the power set with one new element each loop
		for (int i = 0, currentSize = 1; i < setLength; i++, currentSize = currentSize << 1) {
			for (int j = 0; j < currentSize; j++) {
				E[] newSet = (E[]) Array.newInstance(setClass, sets[j].length + 1);
				
				// construct set
				int index = 0;
				for (E e : sets[j])
					newSet[index++] = e; // copy set
				newSet[sets[j].length] = set[i]; // append new element
				sets[currentSize + j] = newSet; // assign newSet to correct slot
			}
		}
		
		return sets;
	}