Initial version, needs optimisation and refactoring