implements #40, #45, #69, #82, #70