The pigeonhole principle and its generalizations