Aggregate factory

Replaces #29 incorporating @kelvinj's work. This looks nothing like the original #29 so it has a new PR so that we can move on from here.
@simensen go for it. Might be a good time to squash those commits down as well :grin: