Improvements to splice operations - closes #406 and #536

This pull request addresses the semi-related issues #406 and #536. There were a few different things going on which weren't directly relevant to each other, hence the slightly broad scope of this PR:

* When `section.splice()` was called internally, it 'reassigned' more fragments than necessary (reassignment is basically the process of changing the keypath of an existing dependant, to allow array mutations to update the DOM in the most conservative manner possible). That's now fixed, and the relevant code has been refactored to be a bit more readable.
* When initialising components, default data on the child component should be propagated up to the parent (e.g. with `<widget foo='{{bar}}'/>`, if 'bar' is initialised, `foo` is set to the same value). But in an edge case exposed by #406, the child would overwrite the wrong data on the parent - I call this 'backwash'. Now, `bar` only propagates back up as `foo` if `foo` wasn't already initialised.
* Expression resolvers, which are responsible for turning expressions like `{{ foo * bar }}` into keypaths for dependency tracking, couldn't be reassigned - they could only be torn down and reinitialised. That meant unnecessary work got done (see #536).

@martypdx - thanks for beating the code into sufficiently good shape that this work could get done. Implementing the `reassign` method on different classes rather than having that octopus-like helper function saved me hours of pain and confusion.