@Override
    public void apply(final Traversal.Admin<?, ?> traversal) {
        TraversalHelper.getStepsOfAssignableClass(HasStep.class, traversal).stream().
                forEach(hasStep -> ((HasStep<?>) hasStep).getHasContainers().stream().
                            filter(container -> container.getKey().equals(T.id.getAccessor())).
                                     forEach(container -> container.setKey(this.idPropertyKey)));

        if (traversal.getStartStep() instanceof GraphStep) {
            final GraphStep graphStep = (GraphStep) traversal.getStartStep();
            // only need to apply the custom id if ids were assigned - otherwise we want the full iterator.
            // note that it is then only necessary to replace the step if the id is a non-element.  other tests
            // in the suite validate that items in getIds() is uniform so it is ok to just test the first item
            // in the list.
            final Object[] ids = graphStep.getIdsAsValues();
            if (ids.length > 0 && !(ids[0] instanceof Element)) {
                if (graphStep instanceof HasContainerHolder)
                    ((HasContainerHolder) graphStep).addHasContainer(new HasContainer(this.idPropertyKey, P.within(Arrays.asList(ids))));
                else
                    TraversalHelper.insertAfterStep(new HasStep(traversal, new HasContainer(this.idPropertyKey, P.within(Arrays.asList(ids)))), graphStep, traversal);
                graphStep.clearIds();
            }
        }
        TraversalHelper.getStepsOfAssignableClass(IdStep.class, traversal).stream().forEach(step -> {
            TraversalHelper.replaceStep(step, new PropertiesStep(traversal, PropertyType.VALUE, idPropertyKey), traversal);
        });

        // in each case below, determine if the T.id is present and if so, replace T.id with the idPropertyKey or if
        // it is not present then shove it in there and generate an id
        traversal.getSteps().forEach(step -> {
            if (step instanceof AddVertexStep || step instanceof AddVertexStartStep || step instanceof AddEdgeStep) {
                final Parameterizing parameterizing = (Parameterizing) step;
                if (parameterizing.getParameters().contains(T.id))
                    parameterizing.getParameters().rename(T.id, this.idPropertyKey);
                else if (!parameterizing.getParameters().contains(this.idPropertyKey))
                    parameterizing.getParameters().set(null, this.idPropertyKey, idMaker.get());
            }
        });
    }
Provides a degree of control over element identifier assignment as some graphs don't provide that feature. This
strategy provides for identifier assignment by enabling users to utilize vertex and edge indices under the hood,
thus simulating that capability.
<p/>
By default, when an identifier is not supplied by the user, newly generated identifiers are {@link UUID} objects.
This behavior can be overridden by setting the {@link Builder#idMaker(Supplier)}.
<p/>
Unless otherwise specified the identifier is stored in the {@code __id} property.  This can be changed by setting
the {@link Builder#idPropertyKey(String)}

@author Marko A. Rodriguez (http://markorodriguez.com)
@author Stephen Mallette (http://stephen.genoprime.com)
gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ElementIdStrategy.java