Fix 3 and 451

This uses both #444 and #445 as diffbases, so reviewing the diffs here will be way too overwhelming before they get merged.

Fixes #3.
Fixes #451.

Other notes:
- There are a few comments sprinkled about with "DJH" about things I wanted to discuss.
- I'm unclear if we should use `key.kind()` or `key.kind`. Since immutable, I went with all `@property`s (i.e. `key.kind`).
- There are some places that are hacky, but I tried to note this since further changes along the lines of the [design doc][1] for the new API make them only temporary hacks.

[1]: https://docs.google.com/document/d/1xKw8Tz6lfN5uOcv0my4uUgFSeDoRzwCLho2UGlBpqDU/edit