@Override
        public boolean hasNext() {
            if (queued != null) {
                return true;
            }

            while (!stack.isEmpty()) {
                // Every relationship is returned, even if the same shape is pointed
                // to multiple times from a single shape.
                Relationship relationship = stack.pop();

                // Only traverse this relationship if the shape it points to hasn't
                // already been traversed.
                if (traversed.add(relationship.getNeighborShapeId())) {
                    queued = relationship.getNeighborShape().get();
                    pushNeighbors(provider.getNeighbors(queued));
                    return true;
                }
            }

            return false;
        }
Lazily iterates over all of the unique shapes in the closure of
the given shape, including the given shape.

@param shape Shape to find the closure of.
@param predicate Predicate used to short-circuit relationship branches.
@return Returns an iterator of shapes connected to {@code shape}.
smithy-model/src/main/java/software/amazon/smithy/model/neighbor/Walker.java