public static <T> List<List<T>> takeKFromList(List<T> list, int k) {
        checkParameters(list, k);
        if (k == 0) {
            return new ArrayList<List<T>>();
        }
        
        /* The algorithm creates the combinations by picking them out in lexicographic order.
         * 
         * Example:
         * If we were to sort the two-combinations from four elements lexicograpically,
         * we'd get the following list (here each integer i represents the i:th elements
         * of the list, starting from 1):
         * 
         * 12, 13, 14, 23, 24, 34.
         */
        
        /* We create the combinations recursively, starting by creating lists of one element.
         * We then add elements to the combinations, one element at a time, until
         * we reach the desired listsize k.
         */
                
        List<List<T>> currentCombinations = new ArrayList<List<T>>();
        List<List<T>> previousCombinations;
        /* These maps contain information about the largest index
         * in each of the combinations. This is needed so we can keep
         * the lexicographic order, and thus avoid creating the smae
         * combination twice. 
         */
        Map<Integer, Integer> currentLargestIndexInThisCombination = new HashMap<Integer,Integer>();        
        Map<Integer, Integer> previousLargestIndexInThisCombination;
        
        createOneElementCombinations(list, k, currentCombinations, currentLargestIndexInThisCombination);
        
        currentCombinations = fillOutCombinations(k, currentCombinations, currentLargestIndexInThisCombination, list);
        
        return currentCombinations;
    }