use multimaps to cut down on boilerplate