private static Set<Scoping.Variable> getVariableLocations(final Set<Scoping.Variable> variables, final Traversal.Admin<?, ?> traversal) {
        if (variables.size() == 2) return variables;    // has both START and END so no need to compute further
        final Step<?, ?> startStep = traversal.getStartStep();
        if (StartStep.isVariableStartStep(startStep))
            variables.add(Scoping.Variable.START);
        else if (startStep instanceof WherePredicateStep) {
            if (((WherePredicateStep) startStep).getStartKey().isPresent())
                variables.add(Scoping.Variable.START);
        } else if (startStep instanceof WhereTraversalStep.WhereStartStep) {
            if (!((WhereTraversalStep.WhereStartStep) startStep).getScopeKeys().isEmpty())
                variables.add(Scoping.Variable.START);
        } else if (startStep instanceof MatchStep.MatchStartStep) {
            if (((MatchStep.MatchStartStep) startStep).getSelectKey().isPresent())
                variables.add(Scoping.Variable.START);
        } else if (startStep instanceof MatchStep) {
            for (final Traversal.Admin<?, ?> global : ((MatchStep<?, ?>) startStep).getGlobalChildren()) {
                TraversalHelper.getVariableLocations(variables, global);
            }
        } else if (startStep instanceof ConnectiveStep || startStep instanceof NotStep || startStep instanceof WhereTraversalStep) {
            for (final Traversal.Admin<?, ?> local : ((TraversalParent) startStep).getLocalChildren()) {
                TraversalHelper.getVariableLocations(variables, local);
            }
        }
        ///
        final Step<?, ?> endStep = traversal.getEndStep();
        if (endStep instanceof WherePredicateStep) {
            if (((WherePredicateStep) endStep).getStartKey().isPresent())
                variables.add(Scoping.Variable.END);
        } else if (endStep instanceof WhereTraversalStep.WhereEndStep) {
            if (!((WhereTraversalStep.WhereEndStep) endStep).getScopeKeys().isEmpty())
                variables.add(Scoping.Variable.END);
        } else if (endStep instanceof MatchStep.MatchEndStep) {
            if (((MatchStep.MatchEndStep) endStep).getMatchKey().isPresent())
                variables.add(Scoping.Variable.END);
        } else if (!endStep.getLabels().isEmpty())
            variables.add(Scoping.Variable.END);
        ///
        return variables;
    }
Returns the name of <i>step</i> truncated to <i>maxLength</i>. An ellipses is appended when the name exceeds
<i>maxLength</i>.

@param step
@param maxLength Includes the 3 "..." characters that will be appended when the length of the name exceeds
                 maxLength.
@return short step name.
gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java