static Map mapKeys(O func, Map map) {
  Map m = similarEmptyMap(map); // TODO: this might break when key type changes through func
  for (O key : keys(map))
    m.put(callF(func, key), map.get(key));
  ret m;
}

static Map mapKeys(Map map, O func) {
  ret mapKeys(func, map);
}

static <A, B, C> Map<B, C> mapKeys(Map<A, C> map, IF1<A, B> func) {
  ret mapKeys(map, (O) func);
}

static <A, B, C> Map<B, C> lambdaMapLike mapKeys(IF1<A, B> func, Map<A, C> map) {
  ret mapKeys(map, func);
}

ifclass MultiMap
static <A, B, C> MultiMap<B, C> mapKeys(IF1<A, C> f, MultiMap<A, B> mm) {
  ret mapMultiMapKeys(f, mm);
}
endif

ifclass MultiSetMap
static <A, B, C> MultiSetMap<B, C> mapKeys(IF1<A, C> f, MultiSetMap<A, B> mm) {
  ret mapMultiSetMapKeys(f, mm);
}
endif