fixed reference classes into two layers:
1. generic layer where the information hiding happens, not caring about types
2. templated layer on top to ensure parent/child types matching