updated for better error handling and more modularity