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/01 15:26:32 UTC

[21/50] incubator-tinkerpop git commit: out of my 24 hole. @dkuppitz -- I was wrong, you can't have XXXStep and XXXSideEffectStep as one in the same. I learned exactly what I learned about a year ago by trying. However, note that all GroupCountXXXStep an

out of my 24 hole. @dkuppitz -- I was wrong, you can't have XXXStep and XXXSideEffectStep as one in the same. I learned exactly what I learned about a year ago by trying. However, note that all GroupCountXXXStep and GroupXXXStep are no longer MapReduce-based, but GraphComputer.Memory-based and because of their alignment they share lots of the same code. All that is left is TreeStep, ProfileStep, and AggregateStep to convert to the GraphComputer.Memory model.


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

Branch: refs/heads/master
Commit: 2f3b2ac971ade400b4f2bfb794b451a612ed0f69
Parents: 980525c
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Thu Feb 25 08:29:23 2016 -0700
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Thu Feb 25 08:29:23 2016 -0700

----------------------------------------------------------------------
 .../traversal/dsl/graph/GraphTraversal.java     |  25 +-
 .../traversal/step/map/GroupCountStep.java      | 123 +++++++++
 .../process/traversal/step/map/GroupStep.java   | 259 +++++++++++++++++++
 .../traversal/step/map/GroupStepV3d0.java       | 170 ++++++++++++
 .../traversal/step/map/MaxGlobalStep.java       |   3 +-
 .../sideEffect/GroupCountSideEffectStep.java    | 121 +++++++++
 .../step/sideEffect/GroupCountStep.java         | 134 ----------
 .../step/sideEffect/GroupSideEffectStep.java    | 147 +++++++++++
 .../sideEffect/GroupSideEffectStepV3d0.java     | 158 +++++++++++
 .../traversal/step/sideEffect/GroupStep.java    | 240 -----------------
 .../step/sideEffect/GroupStepV3d0.java          | 182 -------------
 .../step/util/ReducingBarrierStep.java          |   2 +-
 .../gremlin/structure/io/gryo/GryoMapper.java   |   6 +-
 .../traversal/step/map/GroupCountStepTest.java  |  42 +++
 .../traversal/step/map/GroupStepTest.java       |  43 +++
 .../GroupCountSideEffectStepTest.java           |  44 ++++
 .../step/sideEffect/GroupCountStepTest.java     |  47 ----
 .../sideEffect/GroupSideEffectStepTest.java     |  45 ++++
 .../sideEffect/GroupSideEffectStepV3D0Test.java |  47 ++++
 .../step/sideEffect/GroupStepTest.java          |  48 ----
 .../step/sideEffect/GroupStepV3D0Test.java      |  47 ----
 .../io/PersistedInputOutputRDDTest.java         |  10 +-
 22 files changed, 1220 insertions(+), 723 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
index f1f6b94..69c84ad 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -72,6 +72,9 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeOtherVertexSt
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeVertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.FoldStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupCountStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStepV3d0;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.IdStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LabelStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.LambdaCollectingBarrierStep;
@@ -107,9 +110,9 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.UnfoldStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.VertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.AddPropertyStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.AggregateStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupCountStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupStepV3d0;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupCountSideEffectStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupSideEffectStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupSideEffectStepV3d0;
 import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.IdentityStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.InjectStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.LambdaSideEffectStep;
@@ -144,7 +147,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
-import java.util.UUID;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -638,8 +640,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
     }
 
     public default <K, V> GraphTraversal<S, Map<K, V>> group() {
-        final String id = UUID.randomUUID().toString();
-        return this.asAdmin().addStep(new GroupStep<>(this.asAdmin(), id)).cap(id);
+        return this.asAdmin().addStep(new GroupStep<>(this.asAdmin()));
     }
 
     /**
@@ -647,13 +648,11 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
      */
     @Deprecated
     public default <K, V> GraphTraversal<S, Map<K, V>> groupV3d0() {
-        final String id = UUID.randomUUID().toString();
-        return this.asAdmin().addStep(new GroupStepV3d0<>(this.asAdmin(), id)).cap(id);
+        return this.asAdmin().addStep(new GroupStepV3d0<>(this.asAdmin()));
     }
 
     public default <K> GraphTraversal<S, Map<K, Long>> groupCount() {
-        final String id = UUID.randomUUID().toString() + "destroy";
-        return this.asAdmin().addStep(new GroupCountStep<>(this.asAdmin(), id)).cap(id);
+        return this.asAdmin().addStep(new GroupCountStep<>(this.asAdmin()));
     }
 
     public default GraphTraversal<S, Tree> tree() {
@@ -989,18 +988,18 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
     }
 
     public default GraphTraversal<S, E> group(final String sideEffectKey) {
-        return this.asAdmin().addStep(new GroupStep<>(this.asAdmin(), sideEffectKey));
+        return this.asAdmin().addStep(new GroupSideEffectStep<>(this.asAdmin(), sideEffectKey));
     }
 
     /**
      * @deprecated As of release 3.1.0, replaced by {@link #group(String)}.
      */
     public default GraphTraversal<S, E> groupV3d0(final String sideEffectKey) {
-        return this.asAdmin().addStep(new GroupStepV3d0<>(this.asAdmin(), sideEffectKey));
+        return this.asAdmin().addStep(new GroupSideEffectStepV3d0<>(this.asAdmin(), sideEffectKey));
     }
 
     public default GraphTraversal<S, E> groupCount(final String sideEffectKey) {
-        return this.asAdmin().addStep(new GroupCountStep<>(this.asAdmin(), sideEffectKey));
+        return this.asAdmin().addStep(new GroupCountSideEffectStep<>(this.asAdmin(), sideEffectKey));
     }
 
     public default GraphTraversal<S, E> tree(final String sideEffectKey) {

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStep.java
new file mode 100644
index 0000000..433ad50
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStep.java
@@ -0,0 +1,123 @@
+/*
+ * 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.step.map;
+
+import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.MapHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BinaryOperator;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class GroupCountStep<S, E> extends ReducingBarrierStep<S, Map<E, Long>> implements TraversalParent, ByModulating {
+
+    private Traversal.Admin<S, E> keyTraversal = null;
+
+    public GroupCountStep(final Traversal.Admin traversal) {
+        super(traversal);
+        this.setSeedSupplier(HashMapSupplier.instance());
+        this.setReducingBiOperator(GroupCountBiOperator.instance());
+    }
+
+    @Override
+    public Map<E, Long> projectTraverser(final Traverser.Admin<S> traverser) {
+        return Collections.singletonMap(TraversalUtil.applyNullable(traverser, this.keyTraversal), traverser.bulk());
+    }
+
+    @Override
+    public void addLocalChild(final Traversal.Admin<?, ?> groupTraversal) {
+        this.keyTraversal = this.integrateChild(groupTraversal);
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return null == this.keyTraversal ? Collections.emptyList() : Collections.singletonList(this.keyTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return this.getSelfAndChildRequirements(TraverserRequirement.BULK);
+    }
+
+    @Override
+    public Optional<MemoryComputeKey> getMemoryComputeKey() {
+        return Optional.of(MemoryComputeKey.of(REDUCING, GroupCountBiOperator.instance(), false, false));
+    }
+
+    @Override
+    public void modulateBy(final Traversal.Admin<?, ?> keyTraversal) throws UnsupportedOperationException {
+        this.keyTraversal = this.integrateChild(keyTraversal);
+    }
+
+    @Override
+    public GroupCountStep<S, E> clone() {
+        final GroupCountStep<S, E> clone = (GroupCountStep<S, E>) super.clone();
+        if (null != this.keyTraversal)
+            clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.stepString(this, this.keyTraversal);
+    }
+
+    ///////////////////////////
+
+    public static final class GroupCountBiOperator<E> implements BinaryOperator<Map<E, Long>>, Serializable {
+
+        private static final GroupCountBiOperator INSTANCE = new GroupCountBiOperator();
+
+        @Override
+        public Map<E, Long> apply(final Map<E, Long> mutatingSeed, final Map<E, Long> map) {
+            for (final Map.Entry<E, Long> entry : map.entrySet()) {
+                MapHelper.incr(mutatingSeed, entry.getKey(), entry.getValue());
+            }
+            return mutatingSeed;
+        }
+
+        public static final <E> GroupCountBiOperator<E> instance() {
+            return INSTANCE;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/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
new file mode 100644
index 0000000..d86132b
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStep.java
@@ -0,0 +1,259 @@
+/*
+ * 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.step.map;
+
+import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.lambda.ElementValueTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.lambda.FunctionTraverser;
+import org.apache.tinkerpop.gremlin.process.traversal.lambda.IdentityTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.lambda.TokenTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Barrier;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BinaryOperator;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class GroupStep<S, K, V> extends ReducingBarrierStep<S, Map<K, V>> implements ByModulating, TraversalParent {
+
+    private char state = 'k';
+    private Traversal.Admin<S, K> keyTraversal = null;
+    private Traversal.Admin<S, ?> valueTraversal = this.integrateChild(__.identity().asAdmin());   // used in OLAP
+    private Traversal.Admin<?, V> reduceTraversal = this.integrateChild(__.fold().asAdmin());      // used in OLAP
+    public Traversal.Admin<S, V> valueReduceTraversal = this.integrateChild(__.fold().asAdmin()); // used in OLTP
+
+
+    public GroupStep(final Traversal.Admin traversal) {
+        super(traversal);
+        this.setReducingBiOperator(new GroupBiOperator<>(this.valueReduceTraversal));
+        this.setSeedSupplier(HashMapSupplier.instance());
+    }
+
+    @Override
+    public void onGraphComputer() {
+        super.onGraphComputer();
+        this.setReducingBiOperator(GroupBiOperator.computerInstance());
+    }
+
+    @Override
+    public void modulateBy(final Traversal.Admin<?, ?> kvTraversal) {
+        if ('k' == this.state) {
+            this.keyTraversal = this.integrateChild(kvTraversal);
+            this.state = 'v';
+        } else if ('v' == this.state) {
+            this.valueReduceTraversal = this.integrateChild(convertValueTraversal(kvTraversal));
+            final List<Traversal.Admin<?, ?>> splitTraversal = splitOnBarrierStep(this.valueReduceTraversal);
+            this.valueTraversal = this.integrateChild(splitTraversal.get(0));
+            this.reduceTraversal = this.integrateChild(splitTraversal.get(1));
+            this.state = 'x';
+            this.setReducingBiOperator(new GroupBiOperator<>(this.valueReduceTraversal));
+        } else {
+            throw new IllegalStateException("The key and value traversals for group()-step have already been set: " + this);
+        }
+    }
+
+    @Override
+    public Optional<MemoryComputeKey> getMemoryComputeKey() {
+        return Optional.of(MemoryComputeKey.of(REDUCING, GroupBiOperator.computerInstance(), false, false));
+    }
+
+    @Override
+    public Map<K, V> projectTraverser(final Traverser.Admin<S> traverser) {
+        return GroupStep.doInitialProjection(traverser, (Traversal.Admin) this.keyTraversal, this.onGraphComputer ? this.valueTraversal : null);
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.stepString(this, this.keyTraversal, this.valueReduceTraversal);
+    }
+
+    @Override
+    public List<Traversal.Admin<?, ?>> getLocalChildren() {
+        final List<Traversal.Admin<?, ?>> children = new ArrayList<>(4);
+        if (null != this.keyTraversal)
+            children.add((Traversal.Admin) this.keyTraversal);
+        children.add(this.valueReduceTraversal);
+        children.add(this.valueTraversal);
+        children.add(this.reduceTraversal);
+        return children;
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return this.getSelfAndChildRequirements(TraverserRequirement.OBJECT, TraverserRequirement.BULK, TraverserRequirement.SIDE_EFFECTS);
+    }
+
+    @Override
+    public GroupStep<S, K, V> clone() {
+        final GroupStep<S, K, V> clone = (GroupStep<S, K, V>) super.clone();
+        if (null != this.keyTraversal)
+            clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
+        clone.valueReduceTraversal = clone.integrateChild(this.valueReduceTraversal.clone());
+        clone.valueTraversal = clone.integrateChild(this.valueTraversal.clone());
+        clone.reduceTraversal = clone.integrateChild(this.reduceTraversal.clone());
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
+        result ^= this.valueReduceTraversal.hashCode();
+        return result;
+    }
+
+    @Override
+    public Object generateFinalResult(final Object object) {
+        return GroupStep.doFinalReduction((Map<K, Object>) object, this.onGraphComputer ? this.reduceTraversal : null);
+    }
+
+    ///////////////////////
+
+    public static final class GroupBiOperator<K, V> implements BinaryOperator<Map<K, V>>, Serializable {
+
+        private static final GroupBiOperator COMPUTER_INSTANCE = new GroupBiOperator();
+
+        private transient Traversal.Admin<?, V> valueReduceTraversal;
+        private transient Map<K, Integer> counters;
+        private final boolean onGraphComputer;
+
+        public GroupBiOperator(final Traversal.Admin<?, V> valueReduceTraversal) {
+            this.valueReduceTraversal = valueReduceTraversal;
+            this.counters = new HashMap<>();
+            this.onGraphComputer = false;
+        }
+
+        public GroupBiOperator() {
+            this.onGraphComputer = true;
+        }
+
+        @Override
+        public Map<K, V> apply(final Map<K, V> mutatingSeed, final Map<K, V> map) {
+            for (final K key : map.keySet()) {
+                if (this.onGraphComputer) {
+                    TraverserSet<?> traverserSet = (TraverserSet) mutatingSeed.get(key);
+                    if (null == traverserSet) {
+                        traverserSet = new TraverserSet<>();
+                        mutatingSeed.put(key, (V) traverserSet);
+                    }
+                    traverserSet.addAll((TraverserSet) map.get(key));
+                } else {
+                    final Traverser.Admin traverser = (Traverser.Admin) map.get(key);
+                    Traversal.Admin valueReduceTraversal = (Traversal.Admin) mutatingSeed.get(key);
+                    if (null == valueReduceTraversal) {
+                        this.counters.put(key, 0);
+                        valueReduceTraversal = this.valueReduceTraversal.clone();
+                        mutatingSeed.put(key, (V) valueReduceTraversal);
+                    }
+                    valueReduceTraversal.addStart(traverser);
+                    final int count = this.counters.compute(key, (k, i) -> ++i);
+                    if (count > 10000) {
+                        this.counters.put(key, 0);
+                        TraversalHelper.getFirstStepOfAssignableClass(Barrier.class, valueReduceTraversal).ifPresent(Barrier::processAllStarts);
+                    }
+                }
+            }
+            return mutatingSeed;
+        }
+
+        public static final <K, V> GroupBiOperator<K, V> computerInstance() {
+            return COMPUTER_INSTANCE;
+        }
+    }
+
+    ///////////////////////
+
+    public static <S, E> Traversal.Admin<S, E> convertValueTraversal(final Traversal.Admin<S, E> valueReduceTraversal) {
+        if (valueReduceTraversal instanceof ElementValueTraversal ||
+                valueReduceTraversal instanceof TokenTraversal ||
+                valueReduceTraversal instanceof IdentityTraversal ||
+                valueReduceTraversal.getStartStep() instanceof LambdaMapStep && ((LambdaMapStep) valueReduceTraversal.getStartStep()).getMapFunction() instanceof FunctionTraverser) {
+            return (Traversal.Admin<S, E>) __.map(valueReduceTraversal).fold();
+        } else {
+            return valueReduceTraversal;
+        }
+    }
+
+    public static List<Traversal.Admin<?, ?>> splitOnBarrierStep(final Traversal.Admin<?, ?> valueReduceTraversal) {
+        if (TraversalHelper.getFirstStepOfAssignableClass(Barrier.class, valueReduceTraversal).isPresent()) {
+            final Traversal.Admin<?, ?> first = __.identity().asAdmin();
+            final Traversal.Admin<?, ?> second = __.identity().asAdmin();
+            boolean onSecond = false;
+            for (final Step step : valueReduceTraversal.getSteps()) {
+                if (step instanceof Barrier)
+                    onSecond = true;
+                if (onSecond)
+                    second.addStep(step.clone());
+                else
+                    first.addStep(step.clone());
+            }
+            return Arrays.asList(first, second);
+        } else {
+            return Arrays.asList(valueReduceTraversal.clone(), __.identity().asAdmin());
+        }
+    }
+
+    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<>();
+        if (null != reduceTraversal) {
+            for (final K key : map.keySet()) {
+                final Traversal.Admin<?, V> reduceClone = reduceTraversal.clone();
+                reduceClone.addStarts(((TraverserSet) map.get(key)).iterator());
+                reducedMap.put(key, reduceClone.next());
+            }
+        } else
+            map.forEach((key, traversal) -> reducedMap.put(key, ((Traversal.Admin<?, V>) traversal).next()));
+        return reducedMap;
+    }
+
+    public static <S, K> Map<K, Object> doInitialProjection(final Traverser.Admin<S> traverser, final Traversal.Admin<S, K> keyTraversal, final Traversal.Admin<S, ?> valueTraversal) {
+        final K key = TraversalUtil.applyNullable(traverser, keyTraversal);
+        if (null != valueTraversal) {
+            final TraverserSet traverserSet = new TraverserSet();
+            valueTraversal.reset();
+            valueTraversal.addStart(traverser);
+            valueTraversal.getEndStep().forEachRemaining(t -> traverserSet.add(t.asAdmin()));
+            return Collections.singletonMap(key, traverserSet);
+        } else
+            return Collections.singletonMap(key,traverser);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStepV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStepV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStepV3d0.java
new file mode 100644
index 0000000..ade485b
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStepV3d0.java
@@ -0,0 +1,170 @@
+/*
+ * 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.step.map;
+
+import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BinaryOperator;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class GroupStepV3d0<S, K, V, R> extends ReducingBarrierStep<S, Map<K, R>> implements TraversalParent, ByModulating {
+
+    private char state = 'k';
+    private Traversal.Admin<S, K> keyTraversal = null;
+    private Traversal.Admin<S, V> valueTraversal = null;
+    private Traversal.Admin<Collection<V>, R> reduceTraversal = null;
+
+    public GroupStepV3d0(final Traversal.Admin traversal) {
+        super(traversal);
+        this.setSeedSupplier(HashMapSupplier.instance());
+        this.setReducingBiOperator(GroupBiOperatorV3d0.instance());
+    }
+
+    @Override
+    public Optional<MemoryComputeKey> getMemoryComputeKey() {
+        return Optional.of(MemoryComputeKey.of(REDUCING, GroupBiOperatorV3d0.INSTANCE, false, false));
+    }
+
+    @Override
+    public Map<K, R> projectTraverser(final Traverser.Admin<S> traverser) {
+        final K key = TraversalUtil.applyNullable(traverser, this.keyTraversal);
+        final BulkSet<V> values = new BulkSet<>();
+        final V value = TraversalUtil.applyNullable(traverser, this.valueTraversal);
+        TraversalHelper.addToCollectionUnrollIterator(values, value, traverser.bulk());
+        return Collections.singletonMap(key, (R) values);
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.stepString(this, this.keyTraversal, this.valueTraversal, this.reduceTraversal);
+    }
+
+    @Override
+    public Map<K, R> generateFinalResult(final Object valueMap) {
+        final Map<K, R> reducedMap = new HashMap<>();
+        for (final K key : ((Map<K, Collection<V>>) valueMap).keySet()) {
+            final R r = TraversalUtil.applyNullable(((Map<K, Collection<V>>) valueMap).get(key), this.reduceTraversal);
+            reducedMap.put(key, r);
+        }
+        return reducedMap;
+    }
+
+    @Override
+    public <A, B> List<Traversal.Admin<A, B>> getLocalChildren() {
+        final List<Traversal.Admin<A, B>> children = new ArrayList<>(3);
+        if (null != this.keyTraversal)
+            children.add((Traversal.Admin) this.keyTraversal);
+        if (null != this.valueTraversal)
+            children.add((Traversal.Admin) this.valueTraversal);
+        if (null != this.reduceTraversal)
+            children.add((Traversal.Admin) this.reduceTraversal);
+        return children;
+    }
+
+    @Override
+    public void modulateBy(final Traversal.Admin<?, ?> kvrTraversal) {
+        if ('k' == this.state) {
+            this.keyTraversal = this.integrateChild(kvrTraversal);
+            this.state = 'v';
+        } else if ('v' == this.state) {
+            this.valueTraversal = this.integrateChild(kvrTraversal);
+            this.state = 'r';
+        } else if ('r' == this.state) {
+            this.reduceTraversal = this.integrateChild(kvrTraversal);
+            this.state = 'x';
+        } else {
+            throw new IllegalStateException("The key, value, and reduce functions for group()-step have already been set");
+        }
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return this.getSelfAndChildRequirements(TraverserRequirement.SIDE_EFFECTS, TraverserRequirement.BULK);
+    }
+
+    @Override
+    public GroupStepV3d0<S, K, V, R> clone() {
+        final GroupStepV3d0<S, K, V, R> clone = (GroupStepV3d0<S, K, V, R>) super.clone();
+        if (null != this.keyTraversal)
+            clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
+        if (null != this.valueTraversal)
+            clone.valueTraversal = clone.integrateChild(this.valueTraversal.clone());
+        if (null != this.reduceTraversal)
+            clone.reduceTraversal = clone.integrateChild(this.reduceTraversal.clone());
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
+        if (this.valueTraversal != null) result ^= this.valueTraversal.hashCode();
+        if (this.reduceTraversal != null) result ^= this.reduceTraversal.hashCode();
+        return result;
+    }
+
+    //////////
+
+    @Deprecated
+    public static class GroupBiOperatorV3d0<K, V> implements BinaryOperator<Map<K, V>>, Serializable {
+
+        private final static GroupBiOperatorV3d0 INSTANCE = new GroupBiOperatorV3d0();
+
+        @Override
+        public Map<K, V> apply(final Map<K, V> mutatingSeed, final Map<K, V> map) {
+            for (final K key : map.keySet()) {
+                final BulkSet<V> values = (BulkSet<V>) map.get(key);
+                BulkSet<V> seedValues = (BulkSet<V>) mutatingSeed.get(key);
+                if (null == seedValues) {
+                    seedValues = new BulkSet<>();
+                    mutatingSeed.put(key, (V) seedValues);
+                }
+                seedValues.addAll(values);
+            }
+            return mutatingSeed;
+        }
+
+        public static final <K, V> GroupBiOperatorV3d0<K, V> instance() {
+            return INSTANCE;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxGlobalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxGlobalStep.java
index c409ae4..70788ed 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxGlobalStep.java
@@ -38,13 +38,12 @@ import static org.apache.tinkerpop.gremlin.process.traversal.NumberHelper.max;
  */
 public final class MaxGlobalStep<S extends Number> extends ReducingBarrierStep<S, S> {
 
-
     private static final Double NAN = Double.valueOf(Double.NaN);
 
     public MaxGlobalStep(final Traversal.Admin traversal) {
         super(traversal);
         this.setSeedSupplier(new ConstantSupplier<>((S) NAN));
-        this.setReducingBiOperator(new MaxGlobalBiOperator<>());
+        this.setReducingBiOperator(MaxGlobalBiOperator.INSTANCE);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountSideEffectStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountSideEffectStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountSideEffectStep.java
new file mode 100644
index 0000000..d2de613
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountSideEffectStep.java
@@ -0,0 +1,121 @@
+/*
+ * 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.step.sideEffect;
+
+import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GraphComputing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.SideEffectCapable;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupCountStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.MapHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class GroupCountSideEffectStep<S, E> extends SideEffectStep<S> implements SideEffectCapable, GraphComputing, TraversalParent, ByModulating {
+
+    private Traversal.Admin<S, E> keyTraversal = null;
+    private String sideEffectKey;
+
+    public GroupCountSideEffectStep(final Traversal.Admin traversal, final String sideEffectKey) {
+        super(traversal);
+        this.sideEffectKey = sideEffectKey;
+        this.traversal.asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, HashMapSupplier.instance());
+    }
+
+    @Override
+    protected void sideEffect(final Traverser.Admin<S> traverser) {
+        final Map<Object, Long> groupCountMap = traverser.sideEffects(this.sideEffectKey);
+        MapHelper.incr(groupCountMap, TraversalUtil.applyNullable(traverser.asAdmin(), this.keyTraversal), traverser.bulk());
+    }
+
+    @Override
+    public String getSideEffectKey() {
+        return this.sideEffectKey;
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.stepString(this, this.sideEffectKey, this.keyTraversal);
+    }
+
+    @Override
+    public void addLocalChild(final Traversal.Admin<?, ?> groupTraversal) {
+        this.keyTraversal = this.integrateChild(groupTraversal);
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return null == this.keyTraversal ? Collections.emptyList() : Collections.singletonList(this.keyTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return this.getSelfAndChildRequirements(TraverserRequirement.BULK, TraverserRequirement.SIDE_EFFECTS);
+    }
+
+    @Override
+    public GroupCountSideEffectStep<S, E> clone() {
+        final GroupCountSideEffectStep<S, E> clone = (GroupCountSideEffectStep<S, E>) super.clone();
+        if (null != this.keyTraversal)
+            clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode() ^ this.sideEffectKey.hashCode();
+        if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
+        return result;
+    }
+
+    @Override
+    public void modulateBy(final Traversal.Admin<?, ?> keyTraversal) throws UnsupportedOperationException {
+        this.keyTraversal = this.integrateChild(keyTraversal);
+    }
+
+    @Override
+    public void onGraphComputer() {
+
+    }
+
+    @Override
+    public Object generateFinalResult(final Object map) {
+        return map;
+    }
+
+    @Override
+    public Optional<MemoryComputeKey> getMemoryComputeKey() {
+        return Optional.of(MemoryComputeKey.of(this.getSideEffectKey(), GroupCountStep.GroupCountBiOperator.instance(), false, false));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountStep.java
deleted file mode 100644
index 1a655ea..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountStep.java
+++ /dev/null
@@ -1,134 +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.step.sideEffect;
-
-import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
-import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
-import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
-import org.apache.tinkerpop.gremlin.process.traversal.step.GraphComputing;
-import org.apache.tinkerpop.gremlin.process.traversal.step.SideEffectCapable;
-import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
-import org.apache.tinkerpop.gremlin.process.traversal.step.util.MapHelper;
-import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.BinaryOperator;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class GroupCountStep<S, E> extends SideEffectStep<S> implements SideEffectCapable, GraphComputing, TraversalParent, ByModulating {
-
-    private Traversal.Admin<S, E> keyTraversal = null;
-    private String sideEffectKey;
-
-    public GroupCountStep(final Traversal.Admin traversal, final String sideEffectKey) {
-        super(traversal);
-        this.sideEffectKey = sideEffectKey;
-        this.traversal.asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, HashMapSupplier.instance());
-    }
-
-    @Override
-    protected void sideEffect(final Traverser.Admin<S> traverser) {
-        final Map<Object, Long> groupCountMap = traverser.sideEffects(this.sideEffectKey);
-        MapHelper.incr(groupCountMap, TraversalUtil.applyNullable(traverser.asAdmin(), this.keyTraversal), traverser.bulk());
-    }
-
-    @Override
-    public String getSideEffectKey() {
-        return this.sideEffectKey;
-    }
-
-    @Override
-    public String toString() {
-        return StringFactory.stepString(this, this.sideEffectKey, this.keyTraversal);
-    }
-
-    @Override
-    public void addLocalChild(final Traversal.Admin<?, ?> groupTraversal) {
-        this.keyTraversal = this.integrateChild(groupTraversal);
-    }
-
-    @Override
-    public List<Traversal.Admin<S, E>> getLocalChildren() {
-        return null == this.keyTraversal ? Collections.emptyList() : Collections.singletonList(this.keyTraversal);
-    }
-
-    @Override
-    public Set<TraverserRequirement> getRequirements() {
-        return this.getSelfAndChildRequirements(TraverserRequirement.BULK, TraverserRequirement.SIDE_EFFECTS);
-    }
-
-    @Override
-    public GroupCountStep<S, E> clone() {
-        final GroupCountStep<S, E> clone = (GroupCountStep<S, E>) super.clone();
-        if (null != this.keyTraversal)
-            clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
-        return clone;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = super.hashCode() ^ this.sideEffectKey.hashCode();
-        if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
-        return result;
-    }
-
-    @Override
-    public void modulateBy(final Traversal.Admin<?, ?> keyTraversal) throws UnsupportedOperationException {
-        this.keyTraversal = this.integrateChild(keyTraversal);
-    }
-
-    @Override
-    public void onGraphComputer() {
-
-    }
-
-    @Override
-    public Object generateFinalResult(final Object map) {
-        return map;
-    }
-
-    @Override
-    public Optional<MemoryComputeKey> getMemoryComputeKey() {
-        return Optional.of(MemoryComputeKey.of(this.getSideEffectKey(), GroupCountBiOperator.INSTANCE, false, false));
-    }
-
-    ///////
-
-    public static final class GroupCountBiOperator<E> implements BinaryOperator<Map<E, Long>>, Serializable {
-
-        private static GroupCountBiOperator INSTANCE = new GroupCountBiOperator();
-
-        @Override
-        public Map<E, Long> apply(final Map<E, Long> mutatingSeed, final Map<E, Long> map) {
-            map.forEach((k, v) -> MapHelper.incr(mutatingSeed, k, v));
-            return mutatingSeed;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/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
new file mode 100644
index 0000000..307f211
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStep.java
@@ -0,0 +1,147 @@
+/*
+ * 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.step.sideEffect;
+
+import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GraphComputing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.SideEffectCapable;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStep;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class GroupSideEffectStep<S, K, V> extends SideEffectStep<S> implements SideEffectCapable, TraversalParent, ByModulating, GraphComputing {
+
+    private char state = 'k';
+    private Traversal.Admin<S, K> keyTraversal = null;
+    private Traversal.Admin<S, ?> valueTraversal = this.integrateChild(__.identity().asAdmin());   // used in OLAP
+    private Traversal.Admin<?, V> reduceTraversal = this.integrateChild(__.fold().asAdmin());      // used in OLAP
+    private Traversal.Admin<S, V> valueReduceTraversal = this.integrateChild(__.fold().asAdmin()); // used in OLTP
+    ///
+    private String sideEffectKey;
+    private boolean onGraphComputer = false;
+    private GroupStep.GroupBiOperator<K, V> standardOperator = new GroupStep.GroupBiOperator<>(this.valueReduceTraversal);
+
+    public GroupSideEffectStep(final Traversal.Admin traversal, final String sideEffectKey) {
+        super(traversal);
+        this.sideEffectKey = sideEffectKey;
+        this.traversal.asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, HashMapSupplier.instance());
+    }
+
+    @Override
+    public void modulateBy(final Traversal.Admin<?, ?> kvTraversal) {
+        if ('k' == this.state) {
+            this.keyTraversal = this.integrateChild(kvTraversal);
+            this.state = 'v';
+        } else if ('v' == this.state) {
+            this.valueReduceTraversal = this.integrateChild(GroupStep.convertValueTraversal(kvTraversal));
+            final List<Traversal.Admin<?, ?>> splitTraversal = GroupStep.splitOnBarrierStep(this.valueReduceTraversal);
+            this.valueTraversal = this.integrateChild(splitTraversal.get(0));
+            this.reduceTraversal = this.integrateChild(splitTraversal.get(1));
+            this.state = 'x';
+            this.standardOperator = new GroupStep.GroupBiOperator<>(this.valueReduceTraversal);
+        } else {
+            throw new IllegalStateException("The key and value traversals for group()-step have already been set: " + this);
+        }
+    }
+
+    @Override
+    public Optional<MemoryComputeKey> getMemoryComputeKey() {
+        return Optional.of(MemoryComputeKey.of(this.getSideEffectKey(), new GroupStep.GroupBiOperator<>(), false, false));
+    }
+
+    @Override
+    protected void sideEffect(final Traverser.Admin<S> traverser) {
+        final Map<K, Object> groupMap = traverser.sideEffects(this.sideEffectKey);
+        final Map<K, Object> map = GroupStep.doInitialProjection(traverser.split(), this.keyTraversal, this.onGraphComputer ? this.valueTraversal : null);
+        if (this.onGraphComputer)
+            GroupStep.GroupBiOperator.computerInstance().apply((Map) groupMap, (Map) map);
+        else
+            this.standardOperator.apply((Map) groupMap, (Map) map);
+    }
+
+    @Override
+    public String getSideEffectKey() {
+        return this.sideEffectKey;
+    }
+
+    @Override
+    public void onGraphComputer() {
+        this.onGraphComputer = true;
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.stepString(this, this.sideEffectKey, this.keyTraversal, this.valueReduceTraversal);
+    }
+
+    @Override
+    public List<Traversal.Admin<?, ?>> getLocalChildren() {
+        final List<Traversal.Admin<?, ?>> children = new ArrayList<>(4);
+        if (null != this.keyTraversal)
+            children.add((Traversal.Admin) this.keyTraversal);
+        children.add(this.valueReduceTraversal);
+        children.add(this.valueTraversal);
+        children.add(this.reduceTraversal);
+        return children;
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return this.getSelfAndChildRequirements(TraverserRequirement.OBJECT, TraverserRequirement.BULK, TraverserRequirement.SIDE_EFFECTS);
+    }
+
+    @Override
+    public GroupSideEffectStep<S, K, V> clone() {
+        final GroupSideEffectStep<S, K, V> clone = (GroupSideEffectStep<S, K, V>) super.clone();
+        if (null != this.keyTraversal)
+            clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
+        clone.valueReduceTraversal = clone.integrateChild(this.valueReduceTraversal.clone());
+        clone.valueTraversal = clone.integrateChild(this.valueTraversal.clone());
+        clone.reduceTraversal = clone.integrateChild(this.reduceTraversal.clone());
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode() ^ this.sideEffectKey.hashCode();
+        if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
+        result ^= this.valueReduceTraversal.hashCode();
+        return result;
+    }
+
+    @Override
+    public Object generateFinalResult(final Object object) {
+        return GroupStep.doFinalReduction((Map<K, Object>) object, this.onGraphComputer ? this.reduceTraversal : null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStepV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStepV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStepV3d0.java
new file mode 100644
index 0000000..a4555bc
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStepV3d0.java
@@ -0,0 +1,158 @@
+/*
+ * 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.step.sideEffect;
+
+import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GraphComputing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.SideEffectCapable;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStepV3d0;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+@Deprecated
+public final class GroupSideEffectStepV3d0<S, K, V, R> extends SideEffectStep<S> implements SideEffectCapable, TraversalParent, ByModulating, GraphComputing {
+
+    private char state = 'k';
+    private Traversal.Admin<S, K> keyTraversal = null;
+    private Traversal.Admin<S, V> valueTraversal = null;
+    private Traversal.Admin<Collection<V>, R> reduceTraversal = null;
+    private String sideEffectKey;
+
+    public GroupSideEffectStepV3d0(final Traversal.Admin traversal, final String sideEffectKey) {
+        super(traversal);
+        this.sideEffectKey = sideEffectKey;
+        this.traversal.asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, HashMapSupplier.instance());
+    }
+
+    @Override
+    public Optional<MemoryComputeKey> getMemoryComputeKey() {
+        return Optional.of(MemoryComputeKey.of(this.getSideEffectKey(), GroupStepV3d0.GroupBiOperatorV3d0.instance(), false, false));
+    }
+
+    @Override
+    protected void sideEffect(final Traverser.Admin<S> traverser) {
+        final Map<K, Collection<V>> groupMap = traverser.sideEffects(this.sideEffectKey);
+        final K key = TraversalUtil.applyNullable(traverser, keyTraversal);
+        final V value = TraversalUtil.applyNullable(traverser, valueTraversal);
+        Collection<V> values = groupMap.get(key);
+        if (null == values) {
+            values = new BulkSet<>();
+            groupMap.put(key, values);
+        }
+        TraversalHelper.addToCollectionUnrollIterator(values, value, traverser.bulk());
+    }
+
+    @Override
+    public String getSideEffectKey() {
+        return this.sideEffectKey;
+    }
+
+    @Override
+    public void onGraphComputer() {
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.stepString(this, this.sideEffectKey, this.keyTraversal, this.valueTraversal, this.reduceTraversal);
+    }
+
+    @Override
+    public Map<K, R> generateFinalResult(final Object valueMap) {
+        final Map<K, R> reducedMap = new HashMap<>();
+        for (final K key : ((Map<K, Collection<V>>) valueMap).keySet()) {
+            final R r = TraversalUtil.applyNullable(((Map<K, Collection<V>>) valueMap).get(key), this.reduceTraversal);
+            reducedMap.put(key, r);
+        }
+        return reducedMap;
+    }
+
+    @Override
+    public <A, B> List<Traversal.Admin<A, B>> getLocalChildren() {
+        final List<Traversal.Admin<A, B>> children = new ArrayList<>(3);
+        if (null != this.keyTraversal)
+            children.add((Traversal.Admin) this.keyTraversal);
+        if (null != this.valueTraversal)
+            children.add((Traversal.Admin) this.valueTraversal);
+        if (null != this.reduceTraversal)
+            children.add((Traversal.Admin) this.reduceTraversal);
+        return children;
+    }
+
+    @Override
+    public void modulateBy(final Traversal.Admin<?, ?> kvrTraversal) {
+        if ('k' == this.state) {
+            this.keyTraversal = this.integrateChild(kvrTraversal);
+            this.state = 'v';
+        } else if ('v' == this.state) {
+            this.valueTraversal = this.integrateChild(kvrTraversal);
+            this.state = 'r';
+        } else if ('r' == this.state) {
+            this.reduceTraversal = this.integrateChild(kvrTraversal);
+            this.state = 'x';
+        } else {
+            throw new IllegalStateException("The key, value, and reduce functions for group()-step have already been set");
+        }
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return this.getSelfAndChildRequirements(TraverserRequirement.SIDE_EFFECTS, TraverserRequirement.BULK);
+    }
+
+    @Override
+    public GroupSideEffectStepV3d0<S, K, V, R> clone() {
+        final GroupSideEffectStepV3d0<S, K, V, R> clone = (GroupSideEffectStepV3d0<S, K, V, R>) super.clone();
+        if (null != this.keyTraversal)
+            clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
+        if (null != this.valueTraversal)
+            clone.valueTraversal = clone.integrateChild(this.valueTraversal.clone());
+        if (null != this.reduceTraversal)
+            clone.reduceTraversal = clone.integrateChild(this.reduceTraversal.clone());
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode() ^ this.sideEffectKey.hashCode();
+        if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
+        if (this.valueTraversal != null) result ^= this.valueTraversal.hashCode();
+        if (this.reduceTraversal != null) result ^= this.reduceTraversal.hashCode();
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStep.java
deleted file mode 100644
index 845591a..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStep.java
+++ /dev/null
@@ -1,240 +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.step.sideEffect;
-
-import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
-import org.apache.tinkerpop.gremlin.process.traversal.Step;
-import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
-import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
-import org.apache.tinkerpop.gremlin.process.traversal.lambda.ElementValueTraversal;
-import org.apache.tinkerpop.gremlin.process.traversal.lambda.FunctionTraverser;
-import org.apache.tinkerpop.gremlin.process.traversal.lambda.IdentityTraversal;
-import org.apache.tinkerpop.gremlin.process.traversal.lambda.TokenTraversal;
-import org.apache.tinkerpop.gremlin.process.traversal.step.Barrier;
-import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
-import org.apache.tinkerpop.gremlin.process.traversal.step.GraphComputing;
-import org.apache.tinkerpop.gremlin.process.traversal.step.SideEffectCapable;
-import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
-import org.apache.tinkerpop.gremlin.process.traversal.step.map.LambdaMapStep;
-import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
-import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.BinaryOperator;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class GroupStep<S, K, V> extends SideEffectStep<S> implements SideEffectCapable, TraversalParent, ByModulating, GraphComputing {
-
-    private char state = 'k';
-    private Traversal.Admin<S, K> keyTraversal = null;
-    private Traversal.Admin<S, ?> valueTraversal = this.integrateChild(__.identity().asAdmin());   // used in OLAP
-    private Traversal.Admin<?, V> reduceTraversal = this.integrateChild(__.fold().asAdmin());      // used in OLAP
-    private Traversal.Admin<S, V> valueReduceTraversal = this.integrateChild(__.fold().asAdmin()); // used in OLTP
-    ///
-    private String sideEffectKey;
-    private boolean onGraphComputer = false;
-
-    public GroupStep(final Traversal.Admin traversal, final String sideEffectKey) {
-        super(traversal);
-        this.sideEffectKey = sideEffectKey;
-        this.traversal.asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, HashMapSupplier.instance());
-    }
-
-    @Override
-    public void modulateBy(final Traversal.Admin<?, ?> kvTraversal) {
-        if ('k' == this.state) {
-            this.keyTraversal = this.integrateChild(kvTraversal);
-            this.state = 'v';
-        } else if ('v' == this.state) {
-            this.valueReduceTraversal = this.integrateChild(GroupStep.convertValueTraversal(kvTraversal));
-            final List<Traversal.Admin<?, ?>> splitTraversal = GroupStep.splitOnBarrierStep(this.valueReduceTraversal);
-            this.valueTraversal = this.integrateChild(splitTraversal.get(0));
-            this.reduceTraversal = this.integrateChild(splitTraversal.get(1));
-            this.state = 'x';
-        } else {
-            throw new IllegalStateException("The key and value traversals for group()-step have already been set: " + this);
-        }
-    }
-
-    @Override
-    public Optional<MemoryComputeKey> getMemoryComputeKey() {
-        return Optional.of(MemoryComputeKey.of(this.getSideEffectKey(), GroupBiOperator.INSTANCE, false, false));
-    }
-
-    @Override
-    protected void sideEffect(final Traverser.Admin<S> traverser) {
-        Map<K, Object> map = traverser.sideEffects(this.sideEffectKey);
-        final K key = TraversalUtil.applyNullable(traverser, this.keyTraversal);
-        final TraverserSet<Object> traverserSet = new TraverserSet<>();
-        if (this.onGraphComputer) {
-            this.valueTraversal.reset();
-            this.valueTraversal.addStart(traverser);
-            this.valueTraversal.getEndStep().forEachRemaining(t -> traverserSet.add((Traverser.Admin) t.asAdmin()));
-            final TraverserSet<Object> set = (TraverserSet) map.get(key);
-            if (null == set)
-                map.put(key, traverserSet);
-            else
-                set.addAll(traverserSet);
-        } else {
-            traverserSet.add((Traverser.Admin) traverser.split());
-            Traversal.Admin valueReduceTraversal = (Traversal.Admin) map.get(key);
-            if (null == valueReduceTraversal) {
-                valueReduceTraversal = this.valueReduceTraversal.clone();
-                map.put(key, valueReduceTraversal);
-            }
-            traverserSet.forEach(valueReduceTraversal::addStart);
-            // TODO: TraversalHelper.getFirstStepOfAssignableClass(Barrier.class, valueReduceTraversal).ifPresent(Barrier::processAllStarts);
-        }
-    }
-
-    @Override
-    public String getSideEffectKey() {
-        return this.sideEffectKey;
-    }
-
-    @Override
-    public void onGraphComputer() {
-        this.onGraphComputer = true;
-    }
-
-    @Override
-    public String toString() {
-        return StringFactory.stepString(this, this.sideEffectKey, this.keyTraversal, this.valueReduceTraversal);
-    }
-
-    @Override
-    public List<Traversal.Admin<?, ?>> getLocalChildren() {
-        final List<Traversal.Admin<?, ?>> children = new ArrayList<>(4);
-        if (null != this.keyTraversal)
-            children.add((Traversal.Admin) this.keyTraversal);
-        children.add(this.valueReduceTraversal);
-        children.add(this.valueTraversal);
-        children.add(this.reduceTraversal);
-        return children;
-    }
-
-    @Override
-    public Set<TraverserRequirement> getRequirements() {
-        return this.getSelfAndChildRequirements(TraverserRequirement.OBJECT, TraverserRequirement.BULK, TraverserRequirement.SIDE_EFFECTS);
-    }
-
-    @Override
-    public GroupStep<S, K, V> clone() {
-        final GroupStep<S, K, V> clone = (GroupStep<S, K, V>) super.clone();
-        if (null != this.keyTraversal)
-            clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
-        clone.valueReduceTraversal = clone.integrateChild(this.valueReduceTraversal.clone());
-        clone.valueTraversal = clone.integrateChild(this.valueTraversal.clone());
-        clone.reduceTraversal = clone.integrateChild(this.reduceTraversal.clone());
-        return clone;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = super.hashCode() ^ this.sideEffectKey.hashCode();
-        if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
-        result ^= this.valueReduceTraversal.hashCode();
-        return result;
-    }
-
-    @Override
-    public Object generateFinalResult(final Object object) {
-        final Map<K, Object> map = (Map<K, Object>) object;
-        final Map<K, Object> reducedMap = new HashMap<>();
-        if (this.onGraphComputer) {
-            for (final K key : map.keySet()) {
-                final Traversal.Admin<?, V> reduceClone = this.reduceTraversal.clone();
-                reduceClone.addStarts(((TraverserSet) map.get(key)).iterator());
-                reducedMap.put(key, reduceClone.next());
-            }
-        } else
-            map.forEach((key, traversal) -> reducedMap.put(key, ((Traversal.Admin) traversal).next()));
-        return reducedMap;
-    }
-
-    /////////////////////////////
-
-    private static <S, E> Traversal.Admin<S, E> convertValueTraversal(final Traversal.Admin<S, E> valueReduceTraversal) {
-        if (valueReduceTraversal instanceof ElementValueTraversal ||
-                valueReduceTraversal instanceof TokenTraversal ||
-                valueReduceTraversal instanceof IdentityTraversal ||
-                valueReduceTraversal.getStartStep() instanceof LambdaMapStep && ((LambdaMapStep) valueReduceTraversal.getStartStep()).getMapFunction() instanceof FunctionTraverser) {
-            return (Traversal.Admin<S, E>) __.map(valueReduceTraversal).fold();
-        } else {
-            return valueReduceTraversal;
-        }
-    }
-
-    private static List<Traversal.Admin<?, ?>> splitOnBarrierStep(final Traversal.Admin<?, ?> valueReduceTraversal) {
-        if (TraversalHelper.getFirstStepOfAssignableClass(Barrier.class, valueReduceTraversal).isPresent()) {
-            final Traversal.Admin<?, ?> first = __.identity().asAdmin();
-            final Traversal.Admin<?, ?> second = __.identity().asAdmin();
-            boolean onSecond = false;
-            for (final Step step : valueReduceTraversal.getSteps()) {
-                if (step instanceof Barrier)
-                    onSecond = true;
-                if (onSecond)
-                    second.addStep(step.clone());
-                else
-                    first.addStep(step.clone());
-            }
-            return Arrays.asList(first, second);
-        } else {
-            return Arrays.asList(valueReduceTraversal.clone(), __.identity().asAdmin());
-        }
-    }
-
-    /////////////////////////////
-
-    public static final class GroupBiOperator<K, V> implements BinaryOperator<Map<K, V>>, Serializable {
-
-        private static final GroupBiOperator INSTANCE = new GroupBiOperator();
-
-        private GroupBiOperator() {
-
-        }
-
-        @Override
-        public Map<K, V> apply(final Map<K, V> mutatingSeed, final Map<K, V> map) {
-            for (final K key : map.keySet()) {
-                TraverserSet traverserSet = (TraverserSet) mutatingSeed.get(key);
-                if (null == traverserSet) {
-                    traverserSet = new TraverserSet<>();
-                    mutatingSeed.put(key, (V) traverserSet);
-                }
-                traverserSet.addAll((TraverserSet) map.get(key));
-            }
-            return mutatingSeed;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStepV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStepV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStepV3d0.java
deleted file mode 100644
index edc571b..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStepV3d0.java
+++ /dev/null
@@ -1,182 +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.step.sideEffect;
-
-import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
-import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
-import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
-import org.apache.tinkerpop.gremlin.process.traversal.step.GraphComputing;
-import org.apache.tinkerpop.gremlin.process.traversal.step.SideEffectCapable;
-import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
-import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
-import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.BinaryOperator;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-@Deprecated
-public final class GroupStepV3d0<S, K, V, R> extends SideEffectStep<S> implements SideEffectCapable, TraversalParent, ByModulating, GraphComputing {
-
-    private char state = 'k';
-    private Traversal.Admin<S, K> keyTraversal = null;
-    private Traversal.Admin<S, V> valueTraversal = null;
-    private Traversal.Admin<Collection<V>, R> reduceTraversal = null;
-    private String sideEffectKey;
-
-    public GroupStepV3d0(final Traversal.Admin traversal, final String sideEffectKey) {
-        super(traversal);
-        this.sideEffectKey = sideEffectKey;
-        this.traversal.asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, HashMapSupplier.instance());
-    }
-
-    @Override
-    public Optional<MemoryComputeKey> getMemoryComputeKey() {
-        return Optional.of(MemoryComputeKey.of(this.getSideEffectKey(), GroupBiOperatorV3d0.INSTANCE, false, false));
-    }
-
-    @Override
-    protected void sideEffect(final Traverser.Admin<S> traverser) {
-        final Map<K, Collection<V>> groupMap = traverser.sideEffects(this.sideEffectKey);
-        final K key = TraversalUtil.applyNullable(traverser, keyTraversal);
-        final V value = TraversalUtil.applyNullable(traverser, valueTraversal);
-        Collection<V> values = groupMap.get(key);
-        if (null == values) {
-            values = new BulkSet<>();
-            groupMap.put(key, values);
-        }
-        TraversalHelper.addToCollectionUnrollIterator(values, value, traverser.bulk());
-    }
-
-    @Override
-    public String getSideEffectKey() {
-        return this.sideEffectKey;
-    }
-
-    @Override
-    public void onGraphComputer() {
-    }
-
-    @Override
-    public String toString() {
-        return StringFactory.stepString(this, this.sideEffectKey, this.keyTraversal, this.valueTraversal, this.reduceTraversal);
-    }
-
-    @Override
-    public Map<K, R> generateFinalResult(final Object valueMap) {
-        final Map<K, R> reducedMap = new HashMap<>();
-        for (final K key : ((Map<K, Collection<V>>) valueMap).keySet()) {
-            final R r = TraversalUtil.applyNullable(((Map<K, Collection<V>>) valueMap).get(key), this.reduceTraversal);
-            reducedMap.put(key, r);
-        }
-        return reducedMap;
-    }
-
-    @Override
-    public <A, B> List<Traversal.Admin<A, B>> getLocalChildren() {
-        final List<Traversal.Admin<A, B>> children = new ArrayList<>(3);
-        if (null != this.keyTraversal)
-            children.add((Traversal.Admin) this.keyTraversal);
-        if (null != this.valueTraversal)
-            children.add((Traversal.Admin) this.valueTraversal);
-        if (null != this.reduceTraversal)
-            children.add((Traversal.Admin) this.reduceTraversal);
-        return children;
-    }
-
-    @Override
-    public void modulateBy(final Traversal.Admin<?, ?> kvrTraversal) {
-        if ('k' == this.state) {
-            this.keyTraversal = this.integrateChild(kvrTraversal);
-            this.state = 'v';
-        } else if ('v' == this.state) {
-            this.valueTraversal = this.integrateChild(kvrTraversal);
-            this.state = 'r';
-        } else if ('r' == this.state) {
-            this.reduceTraversal = this.integrateChild(kvrTraversal);
-            this.state = 'x';
-        } else {
-            throw new IllegalStateException("The key, value, and reduce functions for group()-step have already been set");
-        }
-    }
-
-    @Override
-    public Set<TraverserRequirement> getRequirements() {
-        return this.getSelfAndChildRequirements(TraverserRequirement.SIDE_EFFECTS, TraverserRequirement.BULK);
-    }
-
-    @Override
-    public GroupStepV3d0<S, K, V, R> clone() {
-        final GroupStepV3d0<S, K, V, R> clone = (GroupStepV3d0<S, K, V, R>) super.clone();
-        if (null != this.keyTraversal)
-            clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
-        if (null != this.valueTraversal)
-            clone.valueTraversal = clone.integrateChild(this.valueTraversal.clone());
-        if (null != this.reduceTraversal)
-            clone.reduceTraversal = clone.integrateChild(this.reduceTraversal.clone());
-        return clone;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = super.hashCode() ^ this.sideEffectKey.hashCode();
-        if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
-        if (this.valueTraversal != null) result ^= this.valueTraversal.hashCode();
-        if (this.reduceTraversal != null) result ^= this.reduceTraversal.hashCode();
-        return result;
-    }
-
-    //////////
-
-    @Deprecated
-    public static class GroupBiOperatorV3d0<K, V> implements BinaryOperator<Map<K, V>>, Serializable {
-
-        private final static GroupBiOperatorV3d0 INSTANCE = new GroupBiOperatorV3d0();
-
-        @Override
-        public Map<K, V> apply(final Map<K, V> mutatingSeed, final Map<K, V> map) {
-            for (final K key : map.keySet()) {
-                final BulkSet<V> values = (BulkSet<V>) map.get(key);
-                BulkSet<V> seedValues = (BulkSet<V>) mutatingSeed.get(key);
-                if (null == seedValues) {
-                    seedValues = new BulkSet<>();
-                    mutatingSeed.put(key, (V) seedValues);
-                }
-                seedValues.addAll(values);
-            }
-            return mutatingSeed;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ReducingBarrierStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ReducingBarrierStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ReducingBarrierStep.java
index b147092..e54fdca 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ReducingBarrierStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ReducingBarrierStep.java
@@ -100,7 +100,7 @@ public abstract class ReducingBarrierStep<S, E> extends AbstractStep<S, E> imple
             throw FastNoSuchElementException.instance();
         this.processAllStarts();
         this.done = true;
-        final Traverser<E> traverser = TraversalHelper.getRootTraversal(this.getTraversal()).getTraverserGenerator().generate(this.onGraphComputer ? this.seed : FinalGet.tryFinalGet(this.seed), (Step) this, 1l);
+        final Traverser<E> traverser = TraversalHelper.getRootTraversal(this.getTraversal()).getTraverserGenerator().generate(this.onGraphComputer ? this.seed : this.generateFinalResult(this.seed), (Step) this, 1l);
         this.seed = null;
         return traverser;
     }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
index 2bf387a..d60142b 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
@@ -26,14 +26,14 @@ import org.apache.tinkerpop.gremlin.process.traversal.Operator;
 import org.apache.tinkerpop.gremlin.process.traversal.Path;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.FoldStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupCountStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStepV3d0;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.MaxGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.MeanGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.MinGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.SumGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.TreeStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupCountStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupStepV3d0;
 import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.StoreStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStepTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStepTest.java
new file mode 100644
index 0000000..f4eb7ac
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStepTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.step.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class GroupCountStepTest extends StepTest {
+
+    @Override
+    protected List<Traversal> getTraversals() {
+        return Arrays.asList(
+                __.groupCount(),
+                __.groupCount().by("name"),
+                __.groupCount().by("age")
+        );
+    }
+}