Serialization and deserialization of schematics

Includes all these features and more:

* Handles constraints
* Serializes nodes and connections correctly (by specifying their typename)
* Handles derived intermediate types through a depth-first search algorithm (deserialization never sees a derived type before its base type).
Not quite, since we need to retrieve the corresponding key in addition to testing for membership. (I'm thinking of refactoring some of these maps to use bijective structures instead, which will make reverse lookup more efficient and will save us from maintaining two copies of the same data.)