upgraded with better functions