REfactored for a more general case