@SuppressWarnings("unchecked")
    public static <T, U, Y extends Collection<T>> Collection<Pair<U, Y>> chunk(Collection<T> c, Function<T, U> f, Class<?>... resultType) {
        verifyArguments(c, f);
        
        List<Pair<U, Y>> pairs = (List<Pair<U, Y>>) (resultType.length > 0 ? instantiate(resultType[0]) : new ArrayList<Pair<U, Y>>());

        Y previousChunk = (Y) (resultType.length > 0 ? instantiate(resultType[0]) : new ArrayList<T>());
        U previousChunkKey = null;
        for (T e : c) {
            U currentChunkKey = f.call(e);
            if ((null == previousChunkKey) || !currentChunkKey.equals(previousChunkKey)) {        
                if (previousChunk.size() > 0) {
                    pairs.add(new Pair<U, Y>(previousChunkKey, previousChunk));
                };
                previousChunk = (Y) (resultType.length > 0 ? instantiate(resultType[0]) : new ArrayList<T>());
                previousChunkKey = currentChunkKey;
            };
            previousChunk.add(e);
        };
        if (previousChunk.size() > 0) {
            pairs.add(new Pair<U, Y>(previousChunkKey, previousChunk));
        };

        return pairs;
    }