Refactor read_multi support to be more general.

Most changes are consolidated to the engine and builder classes.
High-level, builder now defers the actual rendering (to hash) until
later on, allowing the engine a chance to evaluate all of the various
extends and so forth that may contain a cache directive. Once all of the
cache directives are found, it can generate all of the cache keys and fetch
them simultaneously using read_multi.