The class freemarker.template.EmptyMap implements a read-only empty map, much the same as Collections.EMPTY_MAP in later java versions. It returns "null" for get(anykey), and it throws UnsupportedOperationException on put(), because you can't put.
It *also* throws UnsupportedOperationException() on remove(key), because it is considered a "destructive" operation. However, on an empty map it really is not destructive, instead, it is a null operation which will not modify the map (new HashMap().remove(key) would not change the hash map, just return null). This is also mirrored in Collections.EMPTY_MAP, which just returns null.
The request is that EmptyMap.remove be implemented as a simple "return null", rather than throwing an exception.
The rationale for this thing, btw, is that we (want to) use map.remove() to get parameters for a directive, and then at the end check that the map is empty (so all parameters were in fact understood and present). This works nicely when there are parameters (remove() works properly), but when there are none, FreeMarker sends an EmptyMap, and the entire logic fails. It would work better if EmptyMap.remove() returns null.
Sure, it should just return null; I will fix that in the next release. However, your use-case is a bit strange, because the TemplateDirectoveModel API doesn't promise that the parameter Map is writable (but maybe it should). The usual way of consuming the named arguments is iterating through the Map.Entry-es with an else-if "switch", and if there's no match then throw an exception that says that the parameter name is wrong.
Yeah, I agree on the non-promise, so we'll proably copy the map instead.
As to the other mechanism suggested, that doesn't run well in this particular scenario, although we use it in other places.
OK, remove(key)/clear()/putAll(emptyMap) will work starting from 2.3.20. I don't know if I should demand remove() always to work in parameter maps... is there a frequent/important use-case for that?
Fixed in 2.3.20.