Cache entire merged property sets

Now that property sets are deeply merged, caching
individual property values results in too many cache
misses. This way, properties are only merged once per
scope between writes.
When options are passed, the cache isn't used right now.