abstracting code, adding template support