much cleanup and abstraction