You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2016/03/03 23:11:46 UTC

incubator-tinkerpop git commit: Added some crazy tests to SideEffectTest which verify that registered operators and suppliers as well as mid-traversal side-effect calls behave as expected in both OLTP and OLAP. This required lots of tinkering with Defaul

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1192 ff390381b -> f778b5b0a


Added some crazy tests to SideEffectTest which verify that registered operators and suppliers as well as mid-traversal side-effect calls behave as expected in both OLTP and OLAP. This required lots of tinkering with DefaultTraversalSideEffects to get the logic right around registeration. Removed a pointless TraversalSideEffectsTest we had. Doing all the complex logic in SideEffectTest.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/f778b5b0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/f778b5b0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/f778b5b0

Branch: refs/heads/TINKERPOP-1192
Commit: f778b5b0ab13c3860c30e39eadd64dcdd7af1c18
Parents: ff39038
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Thu Mar 3 15:11:40 2016 -0700
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Thu Mar 3 15:11:40 2016 -0700

----------------------------------------------------------------------
 .../process/traversal/TraversalSideEffects.java |  8 +--
 .../gremlin/process/traversal/Traverser.java    |  6 +--
 .../process/traversal/step/map/GroupStep.java   | 13 ++---
 .../step/sideEffect/GroupSideEffectStep.java    |  5 +-
 .../step/sideEffect/SideEffectCapStep.java      |  8 ++-
 .../strategy/decoration/SideEffectStrategy.java | 10 ++--
 .../util/DefaultTraversalSideEffects.java       | 46 +++++++++--------
 .../traversal/util/SideEffectHelper.java        | 14 +++--
 .../GroovyTraversalSideEffectsTest.groovy       | 31 -----------
 .../step/sideEffect/GroovySideEffectTest.groovy | 14 ++++-
 .../process/GroovyProcessStandardSuite.java     |  4 --
 .../gremlin/process/ProcessStandardSuite.java   |  7 ---
 .../traversal/TraversalSideEffectsTest.java     | 50 ------------------
 .../step/sideEffect/SideEffectTest.java         | 54 ++++++++++++++++++++
 14 files changed, 131 insertions(+), 139 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f778b5b0/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSideEffects.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSideEffects.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSideEffects.java
index b05a88e..d20ae71 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSideEffects.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSideEffects.java
@@ -84,6 +84,7 @@ public interface TraversalSideEffects extends Cloneable, Serializable {
 
     /**
      * Register a side-effect with the {@link TraversalSideEffects} providing a {@link Supplier} and a {@link BinaryOperator}.
+     * If a null value is provided for the supplier or reducer, then it no supplier or reducer is registered.
      *
      * @param key          the key of the side-effect value
      * @param initialValue the initial value supplier
@@ -95,6 +96,7 @@ public interface TraversalSideEffects extends Cloneable, Serializable {
     /**
      * Register a side-effect with the {@link TraversalSideEffects} providing a {@link Supplier} and a {@link BinaryOperator}.
      * The registration will only overwrite a supplier or reducer if no supplier or reducer existed prior.
+     * If a null value is provided for the supplier or reducer, then it no supplier or reducer is registered.
      *
      * @param key          the key of the side-effect value
      * @param initialValue the initial value supplier
@@ -267,9 +269,9 @@ public interface TraversalSideEffects extends Cloneable, Serializable {
      */
     @Deprecated
     public default <V> V getOrCreate(final String key, final Supplier<V> orCreate) {
-        final Optional<V> optional = this.get(key);
-        if (optional.isPresent())
-            return optional.get();
+        final V value = this.exists(key) ? this.get(key) : null;
+        if (null != value)
+            return value;
         final Optional<Supplier<V>> with = this.getRegisteredSupplier(key);
         if (with.isPresent()) {
             final V v = with.get().get();

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f778b5b0/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java
index be0a764..0a36b2c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java
@@ -96,7 +96,7 @@ public interface Traverser<T> extends Serializable, Comparable<Traverser<T>>, Cl
     public long bulk();
 
     /**
-     * Get a particular value from the sideEffects of the traverser.
+     * Get a particular value from the side-effects of the traverser (thus, traversal).
      *
      * @param sideEffectKey the key of the value to get from the sideEffects
      * @param <A>           the type of the returned object
@@ -107,13 +107,13 @@ public interface Traverser<T> extends Serializable, Comparable<Traverser<T>>, Cl
     }
 
     /**
-     * Set a particular value in the sideEffects of the traverser.
+     * Add a particular value to the respective side-effect of the traverser (thus, traversal).
      *
      * @param sideEffectKey   the key of the value to set int the sideEffects
      * @param sideEffectValue the value to set for the sideEffect key
      */
     public default void sideEffects(final String sideEffectKey, final Object sideEffectValue) throws IllegalArgumentException {
-        this.asAdmin().getSideEffects().set(sideEffectKey, sideEffectValue);
+        this.asAdmin().getSideEffects().add(sideEffectKey, sideEffectValue);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f778b5b0/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStep.java
index fbbdc6e..164395d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStep.java
@@ -246,15 +246,16 @@ public final class GroupStep<S, K, V> extends ReducingBarrierStep<S, Map<K, V>>
     }
 
     public static <K, V> Map<K, V> doFinalReduction(final Map<K, Object> map, final Traversal.Admin<?, V> reduceTraversal) {
-        final Map<K, V> reducedMap = new HashMap<>();
+        final Map<K, Object> tempMap = new HashMap<>(map);
+        map.clear();
         if (null != reduceTraversal) {
-            for (final K key : map.keySet()) {
+            for (final K key : tempMap.keySet()) {
                 final Traversal.Admin<?, V> reduceClone = reduceTraversal.clone();
-                reduceClone.addStarts(((TraverserSet) map.get(key)).iterator());
-                reducedMap.put(key, reduceClone.next());
+                reduceClone.addStarts(((TraverserSet) tempMap.get(key)).iterator());
+                map.put(key, reduceClone.next());
             }
         } else
-            map.forEach((key, traversal) -> reducedMap.put(key, ((Traversal.Admin<?, V>) traversal).next()));
-        return reducedMap;
+            tempMap.forEach((key, traversal) -> map.put(key, ((Traversal.Admin<?, V>) traversal).next()));
+        return (Map<K, V>) map;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f778b5b0/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStep.java
index 8bc6c34..0d2be9c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStep.java
@@ -37,7 +37,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.function.BinaryOperator;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -70,7 +69,7 @@ public final class GroupSideEffectStep<S, K, V> extends SideEffectStep<S> implem
             this.valueTraversal = this.integrateChild(splitTraversal.get(0));
             this.reduceTraversal = this.integrateChild(splitTraversal.get(1));
             this.state = 'x';
-            this.getTraversal().getSideEffects().register(this.sideEffectKey, this.getTraversal().getSideEffects().getRegisteredSupplier(this.sideEffectKey).get(), (BinaryOperator) new GroupStep.GroupBiOperator<>(this.valueReduceTraversal));
+            this.getTraversal().getSideEffects().register(this.sideEffectKey, null, new GroupStep.GroupBiOperator<>(this.valueReduceTraversal));
         } else {
             throw new IllegalStateException("The key and value traversals for group()-step have already been set: " + this);
         }
@@ -99,7 +98,7 @@ public final class GroupSideEffectStep<S, K, V> extends SideEffectStep<S> implem
     @Override
     public void onGraphComputer() {
         this.onGraphComputer = true;
-        this.getTraversal().getSideEffects().register(this.sideEffectKey, this.getTraversal().getSideEffects().getRegisteredSupplier(this.sideEffectKey).get(), (BinaryOperator) GroupStep.GroupBiOperator.computerInstance());
+        this.getTraversal().getSideEffects().register(this.sideEffectKey, null, GroupStep.GroupBiOperator.computerInstance());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f778b5b0/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/SideEffectCapStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/SideEffectCapStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/SideEffectCapStep.java
index e211b6a..5ac5b27 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/SideEffectCapStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/SideEffectCapStep.java
@@ -94,7 +94,9 @@ public final class SideEffectCapStep<S, E> extends SupplyingBarrierStep<S, E> {
             final String sideEffectKey = this.sideEffectKeys.get(0);
             final E result = this.getTraversal().getSideEffects().<E>get(sideEffectKey);
             final SideEffectCapable<Object, E> sideEffectCapable = this.sideEffectCapableSteps.get(sideEffectKey);
-            return null == sideEffectCapable ? result : sideEffectCapable.generateFinalResult(result);
+            final E finalResult = null == sideEffectCapable ? result : sideEffectCapable.generateFinalResult(result);
+            this.getTraversal().getSideEffects().set(sideEffectKey, finalResult);
+            return finalResult;
         } else
             return (E) this.getMapOfSideEffects();
     }
@@ -106,7 +108,9 @@ public final class SideEffectCapStep<S, E> extends SupplyingBarrierStep<S, E> {
             if (temp.exists(sideEffectKey)) {
                 final E result = temp.get(sideEffectKey);
                 final SideEffectCapable<Object, E> sideEffectCapable = this.sideEffectCapableSteps.get(sideEffectKey);
-                sideEffects.put(sideEffectKey, null == sideEffectCapable ? result : sideEffectCapable.generateFinalResult(result));
+                final E finalResult = null == sideEffectCapable ? result : sideEffectCapable.generateFinalResult(result);
+                temp.set(sideEffectKey, finalResult);
+                sideEffects.put(sideEffectKey, finalResult);
             }
         }
         return sideEffects;

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f778b5b0/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SideEffectStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SideEffectStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SideEffectStrategy.java
index f05c59f..ed8f1e3 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SideEffectStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SideEffectStrategy.java
@@ -44,11 +44,9 @@ public final class SideEffectStrategy extends AbstractTraversalStrategy<Traversa
 
     @Override
     public void apply(final Traversal.Admin<?, ?> traversal) {
-        if (traversal.getParent() instanceof EmptyStep)
-            this.sideEffects.forEach(triplet -> traversal.getSideEffects().register(
-                    triplet.getValue0(),
-                    null == triplet.getValue1() ? traversal.getSideEffects().exists(triplet.getValue0()) ? traversal.getSideEffects().getSupplier(triplet.getValue0()) : triplet.getValue1() : triplet.getValue1(),
-                    null == triplet.getValue2() ? traversal.getSideEffects().exists(triplet.getValue0()) ? traversal.getSideEffects().getReducer(triplet.getValue0()) : triplet.getValue2() : triplet.getValue2()));
+        if (traversal.getParent() instanceof EmptyStep) {
+            this.sideEffects.forEach(triplet -> traversal.getSideEffects().register(triplet.getValue0(), triplet.getValue1(), triplet.getValue2()));
+        }
     }
 
     public static <A> void addSideEffect(final TraversalStrategies traversalStrategies, final String key, final A value, final BinaryOperator<A> reducer) {
@@ -57,6 +55,6 @@ public final class SideEffectStrategy extends AbstractTraversalStrategy<Traversa
             strategy = new SideEffectStrategy();
             traversalStrategies.addStrategies(strategy);
         }
-        strategy.sideEffects.add(new Triplet<>(key, value instanceof Supplier ? (Supplier) value : new ConstantSupplier<>(value), reducer));
+        strategy.sideEffects.add(new Triplet<>(key, null == value ? null : value instanceof Supplier ? (Supplier) value : new ConstantSupplier<>(value), reducer));
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f778b5b0/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/DefaultTraversalSideEffects.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/DefaultTraversalSideEffects.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/DefaultTraversalSideEffects.java
index 067b07a..9bc9e45 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/DefaultTraversalSideEffects.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/DefaultTraversalSideEffects.java
@@ -37,6 +37,7 @@ import java.util.function.UnaryOperator;
  */
 public class DefaultTraversalSideEffects implements TraversalSideEffects {
 
+    protected Set<String> keys = new HashSet<>();
     protected Map<String, Object> objectMap = new HashMap<>();
     protected Map<String, Supplier> supplierMap = new HashMap<>();
     protected Map<String, BinaryOperator> reducerMap = new HashMap<>();
@@ -53,7 +54,7 @@ public class DefaultTraversalSideEffects implements TraversalSideEffects {
      */
     @Override
     public boolean exists(final String key) {
-        return this.supplierMap.containsKey(key);
+        return this.keys.contains(key);
     }
 
     /**
@@ -76,8 +77,8 @@ public class DefaultTraversalSideEffects implements TraversalSideEffects {
      */
     @Override
     public void set(final String key, final Object value) throws IllegalArgumentException {
-        SideEffectHelper.validateSideEffect(key, value);
-        if (!this.supplierMap.containsKey(key))
+        SideEffectHelper.validateSideEffectValue(value);
+        if (!this.keys.contains(key))
             throw TraversalSideEffects.Exceptions.sideEffectKeyDoesNotExist(key);
         this.objectMap.put(key, value);
     }
@@ -87,6 +88,7 @@ public class DefaultTraversalSideEffects implements TraversalSideEffects {
      */
     @Override
     public void add(final String key, final Object value) throws IllegalArgumentException {
+        SideEffectHelper.validateSideEffectValue(value);
         this.set(key, this.getReducer(key).apply(this.get(key), value));
     }
 
@@ -95,9 +97,13 @@ public class DefaultTraversalSideEffects implements TraversalSideEffects {
      */
     @Override
     public <V> void register(final String key, final Supplier<V> initialValue, final BinaryOperator<V> reducer) {
-        SideEffectHelper.validateSideEffect(key, initialValue);
-        this.supplierMap.put(key, initialValue);
-        this.reducerMap.put(key, reducer);
+        SideEffectHelper.validateSideEffectKey(key);
+        this.keys.add(key);
+        this.objectMap.remove(key);
+        if (null != initialValue)
+            this.supplierMap.put(key, initialValue);
+        if (null != reducer)
+            this.reducerMap.put(key, reducer);
     }
 
     /**
@@ -105,10 +111,13 @@ public class DefaultTraversalSideEffects implements TraversalSideEffects {
      */
     @Override
     public <V> void registerIfAbsent(final String key, final Supplier<V> initialValue, final BinaryOperator<V> reducer) {
-        if (null == this.supplierMap.get(key)) {
+        SideEffectHelper.validateSideEffectKey(key);
+        this.keys.add(key);
+        this.objectMap.remove(key);
+        if (null == this.supplierMap.get(key) && null != initialValue) {
             this.supplierMap.put(key, initialValue);
         }
-        if (null == this.reducerMap.get(key)) {
+        if (null == this.reducerMap.get(key) && null != reducer) {
             this.reducerMap.put(key, reducer);
         }
     }
@@ -205,6 +214,7 @@ public class DefaultTraversalSideEffects implements TraversalSideEffects {
     public DefaultTraversalSideEffects clone() {
         try {
             final DefaultTraversalSideEffects sideEffects = (DefaultTraversalSideEffects) super.clone();
+            sideEffects.keys = new HashSet<>(this.keys);
             sideEffects.objectMap = new HashMap<>(this.objectMap);
             sideEffects.supplierMap = new HashMap<>(this.supplierMap);
             sideEffects.reducerMap = new HashMap<>(this.reducerMap);
@@ -222,7 +232,7 @@ public class DefaultTraversalSideEffects implements TraversalSideEffects {
     @Deprecated
     @Override
     public void registerSupplier(final String key, final Supplier supplier) {
-        this.register(key, supplier, Operator.assign);
+        this.register(key, supplier, null);
 
     }
 
@@ -232,9 +242,7 @@ public class DefaultTraversalSideEffects implements TraversalSideEffects {
     @Deprecated
     @Override
     public void registerSupplierIfAbsent(final String key, final Supplier supplier) {
-        if (!this.supplierMap.containsKey(key)) {
-            this.register(key, supplier, Operator.assign);
-        }
+        this.registerIfAbsent(key, supplier, null);
     }
 
     /**
@@ -252,15 +260,13 @@ public class DefaultTraversalSideEffects implements TraversalSideEffects {
     @Override
     @Deprecated
     public <V> V getOrCreate(final String key, final Supplier<V> orCreate) {
-        final Optional<V> optional = this.get(key);
-        if (optional.isPresent())
-            return optional.get();
-        else {
-            final V value = orCreate.get();
-            this.objectMap.put(key, value);
+        final V value = this.exists(key) ? this.get(key) : null;
+        if (null != value)
             return value;
+        else {
+            final V newValue = orCreate.get();
+            this.objectMap.put(key, newValue);
+            return newValue;
         }
     }
-
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f778b5b0/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/SideEffectHelper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/SideEffectHelper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/SideEffectHelper.java
index 36b88af..d605c76 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/SideEffectHelper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/SideEffectHelper.java
@@ -28,12 +28,20 @@ public final class SideEffectHelper {
     private SideEffectHelper() {
     }
 
-    public static void validateSideEffect(final String key, final Object value) throws IllegalArgumentException {
-        if (null == value)
-            throw TraversalSideEffects.Exceptions.sideEffectValueCanNotBeNull();
+    public static void validateSideEffectKey(final String key) throws IllegalArgumentException {
         if (null == key)
             throw TraversalSideEffects.Exceptions.sideEffectKeyCanNotBeNull();
         if (key.isEmpty())
             throw TraversalSideEffects.Exceptions.sideEffectKeyCanNotBeEmpty();
     }
+
+    public static void validateSideEffectValue(final Object value) throws IllegalArgumentException {
+        if (null == value)
+            throw TraversalSideEffects.Exceptions.sideEffectValueCanNotBeNull();
+    }
+
+    public static void validateSideEffectKeyValue(final String key, final Object value) throws IllegalArgumentException {
+        SideEffectHelper.validateSideEffectKey(key);
+        SideEffectHelper.validateSideEffectValue(value);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f778b5b0/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/GroovyTraversalSideEffectsTest.groovy
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/GroovyTraversalSideEffectsTest.groovy b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/GroovyTraversalSideEffectsTest.groovy
deleted file mode 100644
index d0c6038..0000000
--- a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/GroovyTraversalSideEffectsTest.groovy
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tinkerpop.gremlin.process.traversal
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-abstract class GroovyTraversalSideEffectsTest {
-
-    public static class Traversals extends TraversalSideEffectsTest {
-        @Override
-        public TraversalSideEffects get_g_V_asAdmin_getSideEffects() {
-            g.V().asAdmin().getSideEffects()
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f778b5b0/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroovySideEffectTest.groovy
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroovySideEffectTest.groovy b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroovySideEffectTest.groovy
index 5870457..399b18a 100644
--- a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroovySideEffectTest.groovy
+++ b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroovySideEffectTest.groovy
@@ -56,6 +56,18 @@ public abstract class GroovySideEffectTest {
             new ScriptTraversal<>(g, "gremlin-groovy", "g.withSideEffect('a'){[:] as LinkedHashMap}.V.out.groupCount('a').by(label).out.out.cap('a')");
         }
 
-
+        @Override
+        public Traversal<Vertex, Map<String, Long>> get_g_withSideEffectsXa__linkedhashmapX_withSideEffectXb__arraylist__addAllX_withSideEffectXc__arrayList__addAllX_V_groupXaX_byXlabelX_byXcountX_sideEffectXb__1_2_3X_out_out_out_sideEffectXc__bob_danielX_capXaX() {
+            new ScriptTraversal<>(g, "gremlin-groovy", """
+                   g.withSideEffect('a'){[:] as LinkedHashMap}
+                    .withSideEffect('b',{[:] as ArrayList},addAll)
+                    .withSideEffect('c',{[:] as ArrayList},addAll)
+                    .V.group('a').by(label).by(count())
+                    .sideEffect{it.sideEffects('b', [1,2,3] as LinkedList)}
+                    .out.out.out
+                    .sideEffect{it.sideEffect('c',['bob','daniel'] as LinkedList)}
+                    .cap('a');
+                """);
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f778b5b0/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/process/GroovyProcessStandardSuite.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/process/GroovyProcessStandardSuite.java b/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/process/GroovyProcessStandardSuite.java
index 60fa5fc..870cb9a 100644
--- a/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/process/GroovyProcessStandardSuite.java
+++ b/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/process/GroovyProcessStandardSuite.java
@@ -23,7 +23,6 @@ import org.apache.tinkerpop.gremlin.GraphManager;
 import org.apache.tinkerpop.gremlin.groovy.loaders.SugarLoader;
 import org.apache.tinkerpop.gremlin.groovy.util.SugarTestHelper;
 import org.apache.tinkerpop.gremlin.process.traversal.CoreTraversalTest;
-import org.apache.tinkerpop.gremlin.process.traversal.GroovyTraversalSideEffectsTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.GroovyBranchTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.GroovyChooseTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.GroovyLocalTest;
@@ -163,9 +162,6 @@ public class GroovyProcessStandardSuite extends ProcessStandardSuite {
             GroovySubgraphTest.Traversals.class,
             GroovyTreeTest.Traversals.class,
 
-            // util
-            GroovyTraversalSideEffectsTest.Traversals.class,
-
             // compliance
             CoreTraversalTest.class,
     };

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f778b5b0/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
index 014b1b6..7850c3f 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
@@ -21,7 +21,6 @@ package org.apache.tinkerpop.gremlin.process;
 import org.apache.tinkerpop.gremlin.AbstractGremlinSuite;
 import org.apache.tinkerpop.gremlin.process.traversal.CoreTraversalTest;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine;
-import org.apache.tinkerpop.gremlin.process.traversal.TraversalSideEffectsTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.BranchTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.ChooseTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.LocalTest;
@@ -168,9 +167,6 @@ public class ProcessStandardSuite extends AbstractGremlinSuite {
             SubgraphTest.Traversals.class,
             TreeTest.Traversals.class,
 
-            // util
-            TraversalSideEffectsTest.Traversals.class,
-
             // compliance
             CoreTraversalTest.class,
 
@@ -245,9 +241,6 @@ public class ProcessStandardSuite extends AbstractGremlinSuite {
             StoreTest.class,
             SubgraphTest.class,
             TreeTest.class,
-
-            // util
-            TraversalSideEffectsTest.class
     };
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f778b5b0/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSideEffectsTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSideEffectsTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSideEffectsTest.java
deleted file mode 100644
index 62f0b4a..0000000
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSideEffectsTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tinkerpop.gremlin.process.traversal;
-
-import org.apache.tinkerpop.gremlin.LoadGraphWith;
-import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
-import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.junit.Test;
-
-import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public abstract class TraversalSideEffectsTest extends AbstractGremlinProcessTest {
-    public abstract TraversalSideEffects get_g_V_asAdmin_getSideEffects();
-
-    @Test
-    @LoadGraphWith(MODERN)
-    public void g_V_sideEffects() {
-        final TraversalSideEffects sideEffects = get_g_V_asAdmin_getSideEffects();
-        assertFalse(sideEffects.exists("a"));
-        assertEquals(StringFactory.traversalSideEffectsString(sideEffects), sideEffects.toString());
-    }
-
-    public static class Traversals extends TraversalSideEffectsTest {
-        @Override
-        public TraversalSideEffects get_g_V_asAdmin_getSideEffects() {
-            return g.V().asAdmin().getSideEffects();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f778b5b0/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/SideEffectTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/SideEffectTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/SideEffectTest.java
index d0b4e19..d5db425 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/SideEffectTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/SideEffectTest.java
@@ -22,17 +22,22 @@ import org.apache.tinkerpop.gremlin.LoadGraphWith;
 import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
 import org.apache.tinkerpop.gremlin.process.GremlinProcessRunner;
 import org.apache.tinkerpop.gremlin.process.IgnoreEngine;
+import org.apache.tinkerpop.gremlin.process.traversal.Operator;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalSideEffects;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.util.function.ArrayListSupplier;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Supplier;
@@ -57,6 +62,8 @@ public abstract class SideEffectTest extends AbstractGremlinProcessTest {
 
     public abstract Traversal<Vertex, Map<String, Long>> get_g_withSideEffectXa__linkedhashmapX_V_out_groupCountXaX_byXlabelX_out_out_capXaX();
 
+    public abstract Traversal<Vertex, Map<String, Long>> get_g_withSideEffectsXa__linkedhashmapX_withSideEffectXb__arraylist__addAllX_withSideEffectXc__arrayList__addAllX_V_groupXaX_byXlabelX_byXcountX_sideEffectXb__1_2_3X_out_out_out_sideEffectXc__bob_danielX_capXaX();
+
     @Test
     @LoadGraphWith(MODERN)
     @IgnoreEngine(TraversalEngine.Type.COMPUTER)
@@ -119,6 +126,41 @@ public abstract class SideEffectTest extends AbstractGremlinProcessTest {
         assertTrue(sideEffects.get("a") instanceof LinkedHashMap);
     }
 
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_withSideEffectsXa__linkedhashmapX_withSideEffectXb__arraylist__addAllX_withSideEffectXc__arrayList__addAllX_V_groupXaX_byXlabelX_byXcountX_sideEffectXb__1_2_3X_out_out_out_sideEffectXc__bob_danielX_capXaX() {
+        final Traversal<Vertex, Map<String, Long>> traversal = get_g_withSideEffectsXa__linkedhashmapX_withSideEffectXb__arraylist__addAllX_withSideEffectXc__arrayList__addAllX_V_groupXaX_byXlabelX_byXcountX_sideEffectXb__1_2_3X_out_out_out_sideEffectXc__bob_danielX_capXaX();
+        printTraversalForm(traversal);
+        Map<String, Long> map = traversal.next();
+        assertFalse(traversal.hasNext());
+        assertEquals(2, map.size());
+        assertEquals(2l, map.get("software").longValue());
+        assertEquals(4l, map.get("person").longValue());
+        final TraversalSideEffects sideEffects = traversal.asAdmin().getSideEffects();
+        map = sideEffects.get("a");
+        assertEquals(2, map.size());
+        assertEquals(2l, map.get("software").longValue());
+        assertEquals(4l, map.get("person").longValue());
+        ///
+        assertEquals(3, sideEffects.keys().size());
+        assertTrue(sideEffects.keys().contains("a"));
+        assertTrue(sideEffects.exists("a"));
+// TODO        assertTrue(sideEffects.get("a") instanceof LinkedHashMap);
+        //
+        assertTrue(sideEffects.keys().contains("b"));
+        assertTrue(sideEffects.exists("b"));
+        assertTrue(sideEffects.get("b") instanceof ArrayList);
+        assertEquals(18, sideEffects.<List<Integer>>get("b").size());
+        assertEquals(6l, sideEffects.<List<Integer>>get("b").stream().filter(t -> t == 1).count());
+        assertEquals(6l, sideEffects.<List<Integer>>get("b").stream().filter(t -> t == 2).count());
+        assertEquals(6l, sideEffects.<List<Integer>>get("b").stream().filter(t -> t == 3).count());
+        //
+        assertTrue(sideEffects.keys().contains("c"));
+        assertTrue(sideEffects.exists("c"));
+        assertTrue(sideEffects.get("c") instanceof ArrayList);
+        assertEquals(0, sideEffects.<List>get("c").size());
+    }
+
     public static class Traversals extends SideEffectTest {
 
         @Override
@@ -152,6 +194,18 @@ public abstract class SideEffectTest extends AbstractGremlinProcessTest {
         public Traversal<Vertex, Map<String, Long>> get_g_withSideEffectXa__linkedhashmapX_V_out_groupCountXaX_byXlabelX_out_out_capXaX() {
             return g.withSideEffect("a", new LinkedHashMapSupplier()).V().out().groupCount("a").by(T.label).out().out().cap("a");
         }
+
+        @Override
+        public Traversal<Vertex, Map<String, Long>> get_g_withSideEffectsXa__linkedhashmapX_withSideEffectXb__arraylist__addAllX_withSideEffectXc__arrayList__addAllX_V_groupXaX_byXlabelX_byXcountX_sideEffectXb__1_2_3X_out_out_out_sideEffectXc__bob_danielX_capXaX() {
+            return g.withSideEffect("a", new LinkedHashMapSupplier())
+                    .withSideEffect("b", (Supplier) ArrayListSupplier.instance(), Operator.addAll)
+                    .withSideEffect("c", (Supplier) ArrayListSupplier.instance(), Operator.addAll)
+                    .V().group("a").by(T.label).by(__.count())
+                    .sideEffect(t -> t.sideEffects("b", new LinkedList<>(Arrays.asList(1, 2, 3))))
+                    .out().out().out()
+                    .sideEffect(t -> t.sideEffects("c", new LinkedList<>(Arrays.asList("bob", "daniel"))))
+                    .cap("a");
+        }
     }
 
     private static class LinkedHashMapSupplier implements Supplier<LinkedHashMap> {