public static <TKey extends TKeyT, TKeyT, TValue1 extends TValueT, TValueT> Map<? super TKey, TValueT> mergeMapWith(Map<TKeyT, TValueT> target, Map<? extends TKey, ? extends TValue1> source, Function<? super TValueT, Function<TValue1, ? extends TValueT>> merger) {
        for (Entry<? extends TKey, ? extends TValue1> entry2 : source.entrySet()) {
            TKey key2 = entry2.getKey();
            TValue1 val2 = entry2.getValue();
            if (target.containsKey(key2)) {
                TValueT val1 = target.get(key2);
                target.put(key2, merger.evaluate(val1).evaluate(val2));
            } else {
                target.put(key2, val2);
            }
        }
        return target;
    }