Complete implementation (not fully tested)