Source: https://www.lsi.upc.edu/~gavalda/pa2/6_OOP2.pdf