Avoid closure, move planning code to _plan()