refactory & tests