normalizeCallbacks = (callbacks, seenVertices) => {
  callbacks = callbacks || {};

  callbacks.allowTraversal =
    callbacks.allowTraversal ||
    (() => {
      const seen = {};
      seenVertices.forEach(vertex => {
        seen[vertex] = true;
      });

      return (vertex, neighbor) => {
        // It should still be possible to redefine other callbacks,
        // so we better do all at once here.

        if (!seen[neighbor]) {
          seen[neighbor] = true;
          return true;
        }
        return false;
      };
    })();

  const noop = () => {};
  callbacks.beforeTraversal = callbacks.beforeTraversal || noop;
  callbacks.afterTraversal = callbacks.afterTraversal || noop;
  callbacks.enterVertex = callbacks.enterVertex || noop;
  callbacks.leaveVertex = callbacks.leaveVertex || noop;

  return callbacks;
}
Fill in missing callbacks.
@param {Callbacks} callbacks
@param {Array} seenVertices - Vertices already discovered,
  used by default allowTraversal implementation.
@return {Callbacks} The same object or new one (if null passed).