finished initial implementation -- need to handle optional and required keys somehow
cleaned up code based on feedback