refactor serialization to be self-contained