now templated and with more exported functions