lots of restructuring and rewritting lot of code to make it abstract