Refactored a bit to make it more parametric.