public static <K,V> Map<K,Pair<List<V>,List<V>>> cogroup(List<Pair<K,V>> left,List<Pair<K,V>> right) {
        Map<K,Pair<List<V>,List<V>>> ret = new HashMap<>();

        //group by key first to consolidate values
        Map<K,List<V>> leftMap = groupByKey(left);
        Map<K,List<V>> rightMap = groupByKey(right);

        /**
         * Iterate over each key in the list
         * adding values to the left items
         * as values are found in the list.
         */
        for(Map.Entry<K,List<V>> entry : leftMap.entrySet()) {
            K key = entry.getKey();
            if(!ret.containsKey(key)) {
                List<V> leftListPair = new ArrayList<>();
                List<V> rightListPair = new ArrayList<>();
                Pair<List<V>,List<V>> p = Pair.of(leftListPair,rightListPair);
                ret.put(key,p);
            }

            Pair<List<V>,List<V>> p = ret.get(key);
            p.getFirst().addAll(entry.getValue());


        }

        /**
         * Iterate over each key in the list
         * adding values to the right items
         * as values are found in the list.
         */
        for(Map.Entry<K,List<V>> entry  : rightMap.entrySet()) {
            K key = entry.getKey();
            if(!ret.containsKey(key)) {
                List<V> leftListPair = new ArrayList<>();
                List<V> rightListPair = new ArrayList<>();
                Pair<List<V>,List<V>> p = Pair.of(leftListPair,rightListPair);
                ret.put(key,p);
            }

            Pair<List<V>,List<V>> p = ret.get(key);
            p.getSecond().addAll(entry.getValue());

        }

        return ret;
    }
@Test
    public void testCoGroup() {
        List<Pair<String,String>> leftMap = new ArrayList<>();
        List<Pair<String,String>> rightMap = new ArrayList<>();

        leftMap.add(Pair.of("cat","adam"));
        leftMap.add(Pair.of("dog","adam"));

        rightMap.add(Pair.of("fish","alex"));
        rightMap.add(Pair.of("cat","alice"));
        rightMap.add(Pair.of("dog","steve"));

        //[(fish,([],[alex])), (dog,([adam],[steve])), (cat,([adam],[alice]))]
        Map<String,Pair<List<String>,List<String>>> assertion = new HashMap<>();
        assertion.put("cat",Pair.of(Arrays.asList("adam"),Arrays.asList("alice")));
        assertion.put("dog",Pair.of(Arrays.asList("adam"),Arrays.asList("steve")));
        assertion.put("fish",Pair.of(Collections.<String>emptyList(),Arrays.asList("alex")));

        Map<String, Pair<List<String>, List<String>>> cogroup = FunctionalUtils.cogroup(leftMap, rightMap);
        assertEquals(assertion,cogroup);

    }