Updated with several improvements