(1) factor out some of the input validation into separate functions, (2) avoid large copies as much as possible