Based on sample code from PHP Objects, Patterns, and Practice by Matt Zandstra (phpdoc & cleaned up)