@Override
    protected void sideEffect(final Traverser.Admin<S> traverser) {
        final Object k = this.parameters.get(traverser, T.key, () -> {
            throw new IllegalStateException("The AddPropertyStep does not have a provided key: " + this);
        }).get(0);

        // T identifies immutable components of elements. only property keys can be modified.
        if (k instanceof T)
            throw new IllegalStateException(String.format("T.%s is immutable on existing elements", ((T) k).name()));

        final String key = (String) k;
        final Object value = this.parameters.get(traverser, T.value, () -> {
            throw new IllegalStateException("The AddPropertyStep does not have a provided value: " + this);
        }).get(0);
        final Object[] vertexPropertyKeyValues = this.parameters.getKeyValues(traverser, T.key, T.value);

        final Element element = traverser.get();

        // can't set cardinality if the element is something other than a vertex as only vertices can have
        // a cardinality of properties. if we don't throw an error here we end up with a confusing cast exception
        // which doesn't explain what went wrong
        if (this.cardinality != null && !(element instanceof Vertex))
            throw new IllegalStateException(String.format(
                    "Property cardinality can only be set for a Vertex but the traversal encountered %s for key: %s",
                    element.getClass().getSimpleName(), key));

        final Optional<EventStrategy> optEventStrategy = getTraversal().getStrategies().getStrategy(EventStrategy.class);
        final boolean eventingIsConfigured = EventUtil.hasAnyCallbacks(callbackRegistry)
                && optEventStrategy.isPresent();
        final EventStrategy es = optEventStrategy.orElse(null);

        // find property to remove. only need to capture the removedProperty if eventing is configured
        final Property removedProperty = eventingIsConfigured ?
                captureRemovedProperty(element, key, value, es) :
                VertexProperty.empty();

        final VertexProperty.Cardinality card = this.cardinality != null
                ? this.cardinality
                : element.graph().features().vertex().getCardinality(key);

        // update property
        if (element instanceof Vertex) {
            if (null != card) {
                ((Vertex) element).property(card, key, value, vertexPropertyKeyValues);
            } else if (vertexPropertyKeyValues.length > 0) {
                ((Vertex) element).property(key, value, vertexPropertyKeyValues);
            } else {
                ((Vertex) element).property(key, value);
            }
        } else if (element instanceof Edge) {
            element.property(key, value);
        } else if (element instanceof VertexProperty) {
            element.property(key, value);
        }

        // trigger event callbacks
        if (eventingIsConfigured) {
            EventUtil.registerPropertyChange(callbackRegistry, es, element, removedProperty, value, vertexPropertyKeyValues);
        }
    }
@author Marko A. Rodriguez (http://markorodriguez.com)
gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStep.java