Significant refactoring. Need to think how to make this module extensible