generalize view controllers to allow subclassing
fully implements hard version