First version. Works but needs optimization.