make metadata storage pluggable

Returning a Map<String, Object> doesn't really make sense, here. The code that calls this assumes the values can be cast to byte[], but this is not stated anywhere.
We should either return a proper Task object directly, or at least return byte[], but I would prefer for the underlying implementation to deal with serialization / deserialization.