refactor to improve internal model and allow changed listener merging, #19