Make minor refactors and structural changes

This also adds failing tests for serialization/de-serialization. Our
de-serialized output should always match the serialized output (as long
as the serialized input consisted of only valid nodes).