Refactored. still remains several bugs...