introducing a separate compiler interface to simplify the next step - which is to build different expressions from all targets based on whether a dynamic container is passed at runtime or not.  We then cache separate delegates to improve performance when dynamic containers are not being used.