@Override
    public boolean hasNext() {
        // value traversal is a bit of a special case for next/hasNext(). prior to "noStarts" this method would always
        // return true and next() would always return the value. in other words if the ValueTraversal had a successful
        // addStart(Traverser) it would indefinitely return the start. other parts of the processing engine must
        // account for this behavior and only call the ValueTraversal once. With the change to use "noStarts" we rely
        // on that same behavior in the processing engine and assume a single call but now hasNext() will always
        // either always be true or always be false and next() will throw NoSuchElementException
        return !noStarts;
    }
If there is a "start" traverser this method will return {@code true} and otherwise {@code false} and in either
case will always return as such, irrespective of calls to {@link #next()}. Calling methods should account for
this behavior on their own.
gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ValueTraversal.java