simplify and fix some logic
add docblocks, allow join() chaining