reorganize implementation, avoiding globals