@Override
    public void processAllStarts() {
        final TraversalSideEffects sideEffects = this.getTraversal().getSideEffects();

        // addAll and assign operator collect solutions as a BulkSet. And addAll merges them with an existing
        // sideEffect value which is expected to be Collection. assign replaces the existing value with the new BulkSet.
        // Therefore, they need a different treatment how they gather inputs.
        final boolean bulkReducingOperator = sideEffects.getReducer(sideEffectKey) == Operator.addAll ||
                sideEffects.getReducer(sideEffectKey) == Operator.assign;

        if (this.starts.hasNext()) {
            final BulkSet<Object> bulkSet = new BulkSet<>();

            while (this.starts.hasNext()) {
                final Traverser.Admin<S> traverser = this.starts.next();
                TraversalUtil.produce(traverser, aggregateTraversal).ifProductive(p -> bulkSet.add(p, traverser.bulk()));

                traverser.setStepId(this.getNextStep().getId());

                // when barrier is reloaded, the traversers should be at the next step
                this.barrier.add(traverser);
            }

            if (bulkReducingOperator) {
                sideEffects.add(this.sideEffectKey, bulkSet);
            } else {
                bulkSet.forEach(p -> sideEffects.add(sideEffectKey, p));
            }
        }
    }
@author Marko A. Rodriguez (http://markorodriguez.com)
gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AggregateGlobalStep.java