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 2015/03/19 19:26:45 UTC

[27/40] incubator-tinkerpop git commit: the traversal steps provided by TinkerPop are the foundation for all dsl. GraphTraversal is just a dsl of traversal. Refactored the process API to reflect this concept. Fixed #592.

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/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..d43d694
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStep.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.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.computer.KeyValue;
+import org.apache.tinkerpop.gremlin.process.computer.MapReduce;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.TraversalVertexProgram;
+import org.apache.tinkerpop.gremlin.process.computer.util.StaticMapReduce;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.MapReducer;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.MapHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BiFunction;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class GroupCountStep<S, E> extends ReducingBarrierStep<S, Map<E, Long>> implements MapReducer, TraversalParent {
+
+    private Traversal.Admin<S, E> groupTraversal = null;
+
+    public GroupCountStep(final Traversal.Admin traversal) {
+        super(traversal);
+        this.setSeedSupplier(HashMapSupplier.instance());
+        this.setBiFunction(new GroupCountBiFunction());
+    }
+
+
+    @Override
+    public void addLocalChild(final Traversal.Admin<?, ?> groupTraversal) {
+        this.groupTraversal = this.integrateChild(groupTraversal);
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return null == this.groupTraversal ? Collections.emptyList() : Collections.singletonList(this.groupTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return this.getSelfAndChildRequirements(TraverserRequirement.BULK);
+    }
+
+    @Override
+    public MapReduce<E, Long, E, Long, Map<E, Long>> getMapReduce() {
+        return GroupCountMapReduce.instance();
+    }
+
+    @Override
+    public GroupCountStep<S, E> clone() {
+        final GroupCountStep<S, E> clone = (GroupCountStep<S, E>) super.clone();
+        if (null != this.groupTraversal)
+            clone.groupTraversal = clone.integrateChild(this.groupTraversal.clone());
+        return clone;
+    }
+
+    @Override
+    public Traverser<Map<E, Long>> processNextStart() {
+        if (this.byPass) {
+            final Traverser.Admin<S> traverser = this.starts.next();
+            return traverser.asAdmin().split(TraversalUtil.applyNullable(traverser, (Traversal.Admin<S, Map<E, Long>>) this.groupTraversal), this);
+        } else {
+            return super.processNextStart();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.groupTraversal);
+    }
+
+    ///////////
+
+    private class GroupCountBiFunction implements BiFunction<Map<E, Long>, Traverser<S>, Map<E, Long>>, Serializable {
+
+        private GroupCountBiFunction() {
+
+        }
+
+        @Override
+        public Map<E, Long> apply(final Map<E, Long> mutatingSeed, final Traverser<S> traverser) {
+            MapHelper.incr(mutatingSeed, TraversalUtil.applyNullable(traverser.asAdmin(), GroupCountStep.this.groupTraversal), traverser.bulk());
+            return mutatingSeed;
+        }
+    }
+
+    ///////////
+
+    public static final class GroupCountMapReduce<E> extends StaticMapReduce<E, Long, E, Long, Map<E, Long>> {
+
+        private static final GroupCountMapReduce INSTANCE = new GroupCountMapReduce();
+
+        private GroupCountMapReduce() {
+
+        }
+
+        @Override
+        public boolean doStage(final Stage stage) {
+            return true;
+        }
+
+        @Override
+        public void map(final Vertex vertex, final MapEmitter<E, Long> emitter) {
+            vertex.<TraverserSet<E>>property(TraversalVertexProgram.HALTED_TRAVERSERS).ifPresent(traverserSet -> traverserSet.forEach(traverser -> emitter.emit(traverser.get(), traverser.bulk())));
+        }
+
+        @Override
+        public void reduce(final E key, final Iterator<Long> values, final ReduceEmitter<E, Long> emitter) {
+            long counter = 0;
+            while (values.hasNext()) {
+                counter = counter + values.next();
+            }
+            emitter.emit(key, counter);
+        }
+
+        @Override
+        public void combine(final E key, final Iterator<Long> values, final ReduceEmitter<E, Long> emitter) {
+            reduce(key, values, emitter);
+        }
+
+        @Override
+        public Map<E, Long> generateFinalResult(final Iterator<KeyValue<E, Long>> keyValues) {
+            final Map<E, Long> map = new HashMap<>();
+            keyValues.forEachRemaining(keyValue -> map.put(keyValue.getKey(), keyValue.getValue()));
+            return map;
+        }
+
+        @Override
+        public String getMemoryKey() {
+            return REDUCING;
+        }
+
+        public static final <E> GroupCountMapReduce<E> instance() {
+            return INSTANCE;
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/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..2dc1be6
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStep.java
@@ -0,0 +1,277 @@
+/*
+ * 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.commons.configuration.Configuration;
+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.computer.KeyValue;
+import org.apache.tinkerpop.gremlin.process.computer.MapReduce;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.TraversalVertexProgram;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMatrix;
+import org.apache.tinkerpop.gremlin.process.traversal.step.MapReducer;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.Supplier;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class GroupStep<S, K, V, R> extends ReducingBarrierStep<S, Map<K, R>> implements MapReducer, TraversalParent {
+
+    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 GroupStep(final Traversal.Admin traversal) {
+        super(traversal);
+        this.setSeedSupplier((Supplier) new GroupMapSupplier());
+        this.setBiFunction((BiFunction) new GroupBiFunction());
+    }
+
+    @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;
+    }
+
+    public Traversal.Admin<Collection<V>, R> getReduceTraversal() {
+        return this.reduceTraversal;
+    }
+
+    @Override
+    public void addLocalChild(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 GroupStep<S, K, V, R> clone() {
+        final GroupStep<S, K, V, R> clone = (GroupStep<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 MapReduce<K, Collection<V>, K, R, Map<K, R>> getMapReduce() {
+        return new GroupMapReduce<>(this);
+    }
+
+    @Override
+    public Traverser<Map<K, R>> processNextStart() {
+        if (this.byPass) {
+            final Traverser.Admin<S> traverser = this.starts.next();
+            final Object[] kvPair = new Object[]{TraversalUtil.applyNullable(traverser, (Traversal.Admin<S, Map>) this.keyTraversal), TraversalUtil.applyNullable(traverser, (Traversal.Admin<S, Map>) this.valueTraversal)};
+            return traverser.asAdmin().split(kvPair, (Step) this);
+        } else {
+            return super.processNextStart();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.keyTraversal, this.valueTraversal, this.reduceTraversal);
+    }
+
+    ///////////
+
+    private class GroupBiFunction implements BiFunction<Map<K, Collection<V>>, Traverser.Admin<S>, Map<K, Collection<V>>>, Serializable {
+
+        private GroupBiFunction() {
+
+        }
+
+        @Override
+        public Map<K, Collection<V>> apply(final Map<K, Collection<V>> mutatingSeed, final Traverser.Admin<S> traverser) {
+            final K key = TraversalUtil.applyNullable(traverser, GroupStep.this.keyTraversal);
+            final V value = TraversalUtil.applyNullable(traverser, GroupStep.this.valueTraversal);
+            Collection<V> values = mutatingSeed.get(key);
+            if (null == values) {
+                values = new BulkSet<>();
+                mutatingSeed.put(key, values);
+            }
+            TraversalHelper.addToCollectionUnrollIterator(values, value, traverser.bulk());
+            return mutatingSeed;
+        }
+    }
+
+    //////////
+
+    private class GroupMap extends HashMap<K, Collection<V>> implements FinalGet<Map<K, R>> {
+
+        @Override
+        public Map<K, R> getFinal() {
+            if (null == GroupStep.this.reduceTraversal)
+                return (Map<K, R>) this;
+            else {
+                final Map<K, R> reduceMap = new HashMap<>();
+                this.forEach((k, vv) -> reduceMap.put(k, TraversalUtil.applyNullable(vv, GroupStep.this.reduceTraversal)));
+                return reduceMap;
+            }
+        }
+    }
+
+    private class GroupMapSupplier implements Supplier<GroupMap>, Serializable {
+
+        private GroupMapSupplier() {
+        }
+
+        @Override
+        public GroupMap get() {
+            return new GroupMap();
+        }
+    }
+
+    ///////////
+
+    public static final class GroupMapReduce<K, V, R> implements MapReduce<K, Collection<V>, K, R, Map<K, R>> {
+
+        public static final String GROUP_BY_STEP_STEP_ID = "gremlin.groupStep.stepId";
+
+        private String groupStepId;
+        private Traversal.Admin<Collection<V>, R> reduceTraversal;
+
+        private GroupMapReduce() {
+
+        }
+
+        public GroupMapReduce(final GroupStep<?, K, V, R> step) {
+            this.groupStepId = step.getId();
+            this.reduceTraversal = step.getReduceTraversal();
+        }
+
+        @Override
+        public void storeState(final Configuration configuration) {
+            MapReduce.super.storeState(configuration);
+            configuration.setProperty(GROUP_BY_STEP_STEP_ID, this.groupStepId);
+        }
+
+        @Override
+        public void loadState(final Configuration configuration) {
+            this.groupStepId = configuration.getString(GROUP_BY_STEP_STEP_ID);
+            final Traversal.Admin<?, ?> traversal = TraversalVertexProgram.getTraversalSupplier(configuration).get();
+            if (!traversal.isLocked())
+                traversal.applyStrategies(); // TODO: this is a scary error prone requirement, but only a problem for GroupStep
+            final GroupStep groupStep = new TraversalMatrix<>(traversal).getStepById(this.groupStepId);
+            this.reduceTraversal = groupStep.getReduceTraversal();
+        }
+
+        @Override
+        public boolean doStage(final Stage stage) {
+            return !stage.equals(Stage.COMBINE);
+        }
+
+        @Override
+        public void map(final Vertex vertex, final MapEmitter<K, Collection<V>> emitter) {
+            vertex.<TraverserSet<Object[]>>property(TraversalVertexProgram.HALTED_TRAVERSERS).ifPresent(traverserSet -> traverserSet.forEach(traverser -> {
+                final Object[] objects = traverser.get();
+                if (objects[1] instanceof Collection)
+                    emitter.emit((K) objects[0], (Collection<V>) objects[1]);
+                else {
+                    final List<V> collection = new ArrayList<>();
+                    collection.add((V) objects[1]);
+                    emitter.emit((K) objects[0], collection);
+                }
+            }));
+        }
+
+        @Override
+        public void reduce(final K key, final Iterator<Collection<V>> values, final ReduceEmitter<K, R> emitter) {
+            final Set<V> set = new BulkSet<>();
+            values.forEachRemaining(set::addAll);
+            emitter.emit(key, TraversalUtil.applyNullable(set, this.reduceTraversal));
+        }
+
+        @Override
+        public Map<K, R> generateFinalResult(final Iterator<KeyValue<K, R>> keyValues) {
+            final Map<K, R> map = new HashMap<>();
+            keyValues.forEachRemaining(keyValue -> map.put(keyValue.getKey(), keyValue.getValue()));
+            return map;
+        }
+
+        @Override
+        public String getMemoryKey() {
+            return REDUCING;
+        }
+
+        @Override
+        public GroupMapReduce<K, V, R> clone() {
+            try {
+                final GroupMapReduce<K, V, R> clone = (GroupMapReduce<K, V, R>) super.clone();
+                if (null != clone.reduceTraversal)
+                    clone.reduceTraversal = this.reduceTraversal.clone();
+                return clone;
+            } catch (final CloneNotSupportedException e) {
+                throw new IllegalStateException(e.getMessage(), e);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return StringFactory.mapReduceString(this, this.getMemoryKey());
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/IdStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/IdStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/IdStep.java
new file mode 100644
index 0000000..018c91e
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/IdStep.java
@@ -0,0 +1,47 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.structure.Element;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class IdStep<S extends Element> extends MapStep<S, Object> {
+
+    public IdStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected Object map(final Traverser.Admin<S> traverser) {
+        return traverser.get().id();
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/KeyStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/KeyStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/KeyStep.java
new file mode 100644
index 0000000..1666c6c
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/KeyStep.java
@@ -0,0 +1,47 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.structure.Property;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class KeyStep extends MapStep<Property, String> {
+
+    public KeyStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected String map(final Traverser.Admin<Property> traverser) {
+        return traverser.get().key();
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LabelStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LabelStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LabelStep.java
new file mode 100644
index 0000000..2b2313f
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LabelStep.java
@@ -0,0 +1,47 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.structure.Element;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class LabelStep<S extends Element> extends MapStep<S, String> {
+
+    public LabelStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected String map(final Traverser.Admin<S> traverser) {
+        return traverser.get().label();
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LambdaFlatMapStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LambdaFlatMapStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LambdaFlatMapStep.java
new file mode 100644
index 0000000..3a039c3
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LambdaFlatMapStep.java
@@ -0,0 +1,49 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+
+import java.util.Iterator;
+import java.util.function.Function;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class LambdaFlatMapStep<S, E> extends FlatMapStep<S, E> {
+
+    private final Function<Traverser<S>, Iterator<E>> function;
+
+    public LambdaFlatMapStep(final Traversal.Admin traversal, final Function<Traverser<S>, Iterator<E>> function) {
+        super(traversal);
+        this.function = function;
+    }
+
+    @Override
+    protected Iterator<E> flatMap(final Traverser.Admin<S> traverser) {
+        return this.function.apply(traverser);
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.function);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LambdaMapStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LambdaMapStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LambdaMapStep.java
new file mode 100644
index 0000000..4d505b7
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LambdaMapStep.java
@@ -0,0 +1,48 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+
+import java.util.function.Function;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class LambdaMapStep<S, E> extends MapStep<S, E> {
+
+    private final Function<Traverser<S>, E> function;
+
+    public LambdaMapStep(final Traversal.Admin traversal, final Function<Traverser<S>, E> function) {
+        super(traversal);
+        this.function = function;
+    }
+
+    @Override
+    protected E map(final Traverser.Admin<S> traverser) {
+        return this.function.apply(traverser);
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.function);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MapStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MapStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MapStep.java
new file mode 100644
index 0000000..4d1dc9d
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MapStep.java
@@ -0,0 +1,53 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public abstract class MapStep<S, E> extends AbstractStep<S, E> {
+
+    public MapStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected Traverser<E> processNextStart() {
+        while (true) {
+            final Traverser.Admin<S> traverser = this.starts.next();
+            return traverser.split(this.map(traverser), this);
+        }
+    }
+
+    protected abstract E map(final Traverser.Admin<S> traverser);
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.PATH_ACCESS); // TODO: this is bad -- just a hack right now.
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/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
new file mode 100644
index 0000000..c59ef33
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxGlobalStep.java
@@ -0,0 +1,133 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.computer.KeyValue;
+import org.apache.tinkerpop.gremlin.process.computer.MapReduce;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.TraversalVertexProgram;
+import org.apache.tinkerpop.gremlin.process.computer.util.StaticMapReduce;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.MapReducer;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.util.function.ConstantSupplier;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.function.BiFunction;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class MaxGlobalStep<S extends Number> extends ReducingBarrierStep<S, S> implements MapReducer {
+
+    public MaxGlobalStep(final Traversal.Admin traversal) {
+        super(traversal);
+        this.setSeedSupplier(new ConstantSupplier<>(null));
+        this.setBiFunction(MaxGlobalBiFunction.<S>instance());
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+
+    @Override
+    public MapReduce<MapReduce.NullObject, Number, MapReduce.NullObject, Number, Number> getMapReduce() {
+        return MaxGlobalMapReduce.instance();
+    }
+
+    /////
+
+    private static class MaxGlobalBiFunction<S extends Number> implements BiFunction<S, Traverser<S>, S>, Serializable {
+
+        private static final MaxGlobalBiFunction INSTANCE = new MaxGlobalBiFunction();
+
+        private MaxGlobalBiFunction() {
+
+        }
+
+        @Override
+        public S apply(final S mutatingSeed, final Traverser<S> traverser) {
+            return mutatingSeed != null && mutatingSeed.doubleValue() >= traverser.get().doubleValue() ? mutatingSeed : traverser.get();
+        }
+
+        public final static <S extends Number> MaxGlobalBiFunction<S> instance() {
+            return INSTANCE;
+        }
+    }
+
+    ///////////
+
+    private static class MaxGlobalMapReduce extends StaticMapReduce<MapReduce.NullObject, Number, MapReduce.NullObject, Number, Number> {
+
+        private static final MaxGlobalMapReduce INSTANCE = new MaxGlobalMapReduce();
+
+        private MaxGlobalMapReduce() {
+
+        }
+
+        @Override
+        public boolean doStage(final MapReduce.Stage stage) {
+            return true;
+        }
+
+        @Override
+        public void map(final Vertex vertex, final MapEmitter<NullObject, Number> emitter) {
+            vertex.<TraverserSet<Number>>property(TraversalVertexProgram.HALTED_TRAVERSERS).ifPresent(traverserSet -> traverserSet.forEach(traverser -> emitter.emit(traverser.get())));
+        }
+
+        @Override
+        public void combine(final NullObject key, final Iterator<Number> values, final ReduceEmitter<NullObject, Number> emitter) {
+            this.reduce(key, values, emitter);
+        }
+
+        @Override
+        public void reduce(final NullObject key, final Iterator<Number> values, final ReduceEmitter<NullObject, Number> emitter) {
+            if (values.hasNext()) {
+                Number max = -Double.MAX_VALUE;
+                while (values.hasNext()) {
+                    final Number value = values.next();
+                    if (value.doubleValue() > max.doubleValue())
+                        max = value;
+                }
+                emitter.emit(max);
+            }
+        }
+
+        @Override
+        public String getMemoryKey() {
+            return REDUCING;
+        }
+
+        @Override
+        public Number generateFinalResult(final Iterator<KeyValue<NullObject, Number>> keyValues) {
+            return keyValues.hasNext() ? keyValues.next().getValue() : Double.NaN;
+        }
+
+        public static final MaxGlobalMapReduce instance() {
+            return INSTANCE;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxLocalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxLocalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxLocalStep.java
new file mode 100644
index 0000000..6d2a228
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxLocalStep.java
@@ -0,0 +1,59 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public final class MaxLocalStep<E extends Number, S extends Iterable<E>> extends MapStep<S, E> {
+
+    public MaxLocalStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected E map(final Traverser.Admin<S> traverser) {
+        Number result;
+        final Iterator<E> iterator = traverser.get().iterator();
+        if (iterator.hasNext()) {
+            result = iterator.next();
+            while (iterator.hasNext()) {
+                final Number curr = iterator.next();
+                if (result.doubleValue() < curr.doubleValue()) result = curr;
+            }
+        } else {
+            result = Double.NaN;
+        }
+        return (E) result;
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MeanGlobalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MeanGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MeanGlobalStep.java
new file mode 100644
index 0000000..7f2b39d
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MeanGlobalStep.java
@@ -0,0 +1,218 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.computer.KeyValue;
+import org.apache.tinkerpop.gremlin.process.computer.MapReduce;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.TraversalVertexProgram;
+import org.apache.tinkerpop.gremlin.process.computer.util.StaticMapReduce;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.MapReducer;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.util.function.MeanNumberSupplier;
+
+import java.io.Serializable;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.Supplier;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public final class MeanGlobalStep<S extends Number, E extends Number> extends ReducingBarrierStep<S, E> implements MapReducer {
+
+    private static final Set<TraverserRequirement> REQUIREMENTS = EnumSet.of(TraverserRequirement.OBJECT, TraverserRequirement.BULK);
+
+    public MeanGlobalStep(final Traversal.Admin traversal) {
+        super(traversal);
+        this.setSeedSupplier((Supplier) MeanNumberSupplier.instance());
+        this.setBiFunction((BiFunction) MeanGlobalBiFunction.instance());
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return REQUIREMENTS;
+    }
+
+    @Override
+    public MapReduce<Number, Long, Number, Long, Double> getMapReduce() {
+        return MeanGlobalMapReduce.instance();
+    }
+
+    /////
+
+    private static class MeanGlobalBiFunction<S extends Number> implements BiFunction<S, Traverser<S>, S>, Serializable {
+
+        private static final MeanGlobalBiFunction INSTANCE = new MeanGlobalBiFunction();
+
+        private MeanGlobalBiFunction() {
+
+        }
+
+        @Override
+        public S apply(final S mutatingSeed, final Traverser<S> traverser) {
+            return (S) ((MeanNumber) mutatingSeed).add(traverser.get(), traverser.bulk());
+        }
+
+        public final static <S extends Number> MeanGlobalBiFunction<S> instance() {
+            return INSTANCE;
+        }
+    }
+
+    ///////////
+
+    private static final class MeanGlobalMapReduce extends StaticMapReduce<Number, Long, Number, Long, Double> {
+
+        private static final MeanGlobalMapReduce INSTANCE = new MeanGlobalMapReduce();
+
+        private MeanGlobalMapReduce() {
+
+        }
+
+        @Override
+        public boolean doStage(final MapReduce.Stage stage) {
+            return true;
+        }
+
+        @Override
+        public void map(final Vertex vertex, final MapEmitter<Number, Long> emitter) {
+            vertex.<TraverserSet<Number>>property(TraversalVertexProgram.HALTED_TRAVERSERS).ifPresent(traverserSet -> traverserSet.forEach(traverser -> emitter.emit(traverser.get(), traverser.bulk())));
+        }
+
+        @Override
+        public void combine(final Number key, final Iterator<Long> values, final ReduceEmitter<Number, Long> emitter) {
+            this.reduce(key, values, emitter);
+        }
+
+        @Override
+        public void reduce(final Number key, final Iterator<Long> values, final ReduceEmitter<Number, Long> emitter) {
+            long counter = 0;
+            while (values.hasNext()) {
+                counter = counter + values.next();
+            }
+            emitter.emit(key, counter);
+        }
+
+        @Override
+        public String getMemoryKey() {
+            return REDUCING;
+        }
+
+        @Override
+        public Double generateFinalResult(final Iterator<KeyValue<Number, Long>> keyValues) {
+            if (keyValues.hasNext()) {
+                KeyValue<Number, Long> pair = keyValues.next();
+                double result = pair.getKey().doubleValue() * pair.getValue();
+                long counter = pair.getValue();
+                while (keyValues.hasNext()) {
+                    pair = keyValues.next();
+                    result += pair.getKey().doubleValue() * pair.getValue();
+                    counter += pair.getValue();
+                }
+                return result / counter;
+            }
+            return Double.NaN;
+        }
+
+        public static final MeanGlobalMapReduce instance() {
+            return INSTANCE;
+        }
+    }
+
+    ///
+
+    public static final class MeanNumber extends Number implements Comparable<Number>, FinalGet<Double> {
+
+        private long count;
+        private double sum;
+
+        public MeanNumber() {
+            this(0.0d, 0l);
+        }
+
+        public MeanNumber(final double number, final long count) {
+            this.count = count;
+            this.sum = number * count;
+        }
+
+        public MeanNumber add(final Number amount, final long count) {
+            this.count += count;
+            this.sum += amount.doubleValue() * count;
+            return this;
+        }
+
+        public MeanNumber add(final MeanNumber other) {
+            this.count += other.count;
+            this.sum += other.sum;
+            return this;
+        }
+
+        @Override
+        public int intValue() {
+            return (int) (this.sum / this.count);
+        }
+
+        @Override
+        public long longValue() {
+            return (long) (this.sum / this.count);
+        }
+
+        @Override
+        public float floatValue() {
+            return (float) (this.sum / this.count);
+        }
+
+        @Override
+        public double doubleValue() {
+            return this.sum / this.count;
+        }
+
+        @Override
+        public String toString() {
+            return Double.toString(this.doubleValue());
+        }
+
+        @Override
+        public int compareTo(final Number number) {
+            return Double.valueOf(this.doubleValue()).compareTo(number.doubleValue());
+        }
+
+        @Override
+        public boolean equals(final Object object) {
+            return object instanceof Number && Double.valueOf(this.doubleValue()).equals(((Number) object).doubleValue());
+        }
+
+        @Override
+        public int hashCode() {
+            return Double.valueOf(this.doubleValue()).hashCode();
+        }
+
+        @Override
+        public Double getFinal() {
+            return this.doubleValue();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MeanLocalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MeanLocalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MeanLocalStep.java
new file mode 100644
index 0000000..e2db6af
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MeanLocalStep.java
@@ -0,0 +1,59 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public final class MeanLocalStep<E extends Number, S extends Iterable<E>> extends MapStep<S, Double> {
+
+    public MeanLocalStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected Double map(final Traverser.Admin<S> traverser) {
+        final Iterator<E> iterator = traverser.get().iterator();
+        if (iterator.hasNext()) {
+            Long counter = 1L;
+            Double result = iterator.next().doubleValue();
+            while (iterator.hasNext()) {
+                result += iterator.next().doubleValue();
+                counter++;
+            }
+            return result / counter;
+        } else {
+            return Double.NaN;
+        }
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MinGlobalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MinGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MinGlobalStep.java
new file mode 100644
index 0000000..ef28d79
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MinGlobalStep.java
@@ -0,0 +1,133 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.computer.KeyValue;
+import org.apache.tinkerpop.gremlin.process.computer.MapReduce;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.TraversalVertexProgram;
+import org.apache.tinkerpop.gremlin.process.computer.util.StaticMapReduce;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.MapReducer;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.util.function.ConstantSupplier;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.function.BiFunction;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class MinGlobalStep<S extends Number> extends ReducingBarrierStep<S, S> implements MapReducer {
+
+    public MinGlobalStep(final Traversal.Admin traversal) {
+        super(traversal);
+        this.setSeedSupplier(new ConstantSupplier<>(null));
+        this.setBiFunction(MinGlobalBiFunction.instance());
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+
+    @Override
+    public MapReduce<MapReduce.NullObject, Number, MapReduce.NullObject, Number, Number> getMapReduce() {
+        return MinGlobalMapReduce.instance();
+    }
+
+    /////
+
+    private static class MinGlobalBiFunction<S extends Number> implements BiFunction<S, Traverser<S>, S>, Serializable {
+
+        private static final MinGlobalBiFunction INSTANCE = new MinGlobalBiFunction();
+
+        private MinGlobalBiFunction() {
+
+        }
+
+        @Override
+        public S apply(final S mutatingSeed, final Traverser<S> traverser) {
+            return mutatingSeed != null && mutatingSeed.doubleValue() <= traverser.get().doubleValue() ? mutatingSeed : traverser.get();
+        }
+
+        public final static <S extends Number> MinGlobalBiFunction<S> instance() {
+            return INSTANCE;
+        }
+    }
+
+    ///////////
+
+    private static class MinGlobalMapReduce extends StaticMapReduce<MapReduce.NullObject, Number, MapReduce.NullObject, Number, Number> {
+
+        private static final MinGlobalMapReduce INSTANCE = new MinGlobalMapReduce();
+
+        private MinGlobalMapReduce() {
+
+        }
+
+        @Override
+        public boolean doStage(final MapReduce.Stage stage) {
+            return true;
+        }
+
+        @Override
+        public void map(final Vertex vertex, final MapEmitter<NullObject, Number> emitter) {
+            vertex.<TraverserSet<Number>>property(TraversalVertexProgram.HALTED_TRAVERSERS).ifPresent(traverserSet -> traverserSet.forEach(traverser -> emitter.emit(traverser.get())));
+        }
+
+        @Override
+        public void combine(final NullObject key, final Iterator<Number> values, final ReduceEmitter<NullObject, Number> emitter) {
+            this.reduce(key, values, emitter);
+        }
+
+        @Override
+        public void reduce(final NullObject key, final Iterator<Number> values, final ReduceEmitter<NullObject, Number> emitter) {
+            if (values.hasNext()) {
+                Number min = Double.MAX_VALUE;
+                while (values.hasNext()) {
+                    final Number value = values.next();
+                    if (value.doubleValue() < min.doubleValue())
+                        min = value;
+                }
+                emitter.emit(min);
+            }
+        }
+
+        @Override
+        public String getMemoryKey() {
+            return REDUCING;
+        }
+
+        @Override
+        public Number generateFinalResult(final Iterator<KeyValue<NullObject, Number>> keyValues) {
+            return keyValues.hasNext() ? keyValues.next().getValue() : Double.NaN;
+        }
+
+        public static final MinGlobalMapReduce instance() {
+            return INSTANCE;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MinLocalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MinLocalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MinLocalStep.java
new file mode 100644
index 0000000..2959285
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MinLocalStep.java
@@ -0,0 +1,59 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public final class MinLocalStep<E extends Number, S extends Iterable<E>> extends MapStep<S, E> {
+
+    public MinLocalStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected E map(final Traverser.Admin<S> traverser) {
+        Number result;
+        final Iterator<E> iterator = traverser.get().iterator();
+        if (iterator.hasNext()) {
+            result = iterator.next();
+            while (iterator.hasNext()) {
+                final Number curr = iterator.next();
+                if (result.doubleValue() > curr.doubleValue()) result = curr;
+            }
+        } else {
+            result = Double.NaN;
+        }
+        return (E) result;
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderGlobalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderGlobalStep.java
new file mode 100644
index 0000000..39d98ef
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderGlobalStep.java
@@ -0,0 +1,95 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ComparatorHolder;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.CollectingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
+import org.apache.tinkerpop.gremlin.structure.Order;
+import org.apache.tinkerpop.gremlin.util.function.ChainedComparator;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class OrderGlobalStep<S> extends CollectingBarrierStep<S> implements ComparatorHolder<S> {
+
+    private final List<Comparator<S>> comparators = new ArrayList<>();
+
+    public OrderGlobalStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    public void barrierConsumer(final TraverserSet<S> traverserSet) {
+        traverserSet.sort(this.comparators.isEmpty() ? new ComparatorTraverser(Order.incr) : new ChainedComparator(ComparatorTraverser.convertComparator((List) this.comparators)));
+    }
+
+    @Override
+    public void addComparator(final Comparator<S> comparator) {
+        this.comparators.add(comparator);
+    }
+
+    @Override
+    public List<Comparator<S>> getComparators() {
+        return this.comparators.isEmpty() ? Arrays.asList((Comparator) Order.incr) : this.comparators;
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.comparators);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+
+    /////
+
+    private static class ComparatorTraverser<S> implements Comparator<Traverser<S>>, Serializable {
+
+        private final Comparator<S> comparator;
+
+        public ComparatorTraverser(final Comparator<S> comparator) {
+            this.comparator = comparator;
+        }
+
+        @Override
+        public int compare(final Traverser<S> traverserA, final Traverser<S> traverserB) {
+            return this.comparator.compare(traverserA.get(), traverserB.get());
+        }
+
+        public static <S> List<ComparatorTraverser<S>> convertComparator(final List<Comparator<S>> comparators) {
+            return comparators.stream().map(comparator -> new ComparatorTraverser<>(comparator)).collect(Collectors.toList());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderLocalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderLocalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderLocalStep.java
new file mode 100644
index 0000000..cdd8f2b
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderLocalStep.java
@@ -0,0 +1,100 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ComparatorHolder;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class OrderLocalStep<S, M> extends MapStep<S, S> implements ComparatorHolder<M> {
+
+    private final List<Comparator<M>> comparators = new ArrayList<>();
+    private Comparator<M> chainedComparator = null;
+
+    public OrderLocalStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected S map(final Traverser.Admin<S> traverser) {
+        final S start = traverser.get();
+        if (start instanceof Collection)
+            return (S) OrderLocalStep.sortCollection((List) start, this.chainedComparator);
+        else if (start instanceof Map)
+            return (S) OrderLocalStep.sortMap((Map) start, this.chainedComparator);
+        else
+            return start;
+    }
+
+    @Override
+    public void addComparator(final Comparator<M> comparator) {
+        this.comparators.add(comparator);
+        this.chainedComparator = this.comparators.stream().reduce((a, b) -> a.thenComparing(b)).get();
+    }
+
+    @Override
+    public List<Comparator<M>> getComparators() {
+        return this.comparators;
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.comparators);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+
+    /////////////
+
+    private static final <A> List<A> sortCollection(final Collection<A> collection, final Comparator<?> comparator) {
+        if (collection instanceof List) {
+            Collections.sort((List) collection, (Comparator) comparator);
+            return (List<A>) collection;
+        } else {
+            final List<A> list = new ArrayList<>(collection);
+            Collections.sort(list, (Comparator) comparator);
+            return list;
+        }
+    }
+
+    private static final <K, V> Map<K, V> sortMap(final Map<K, V> map, final Comparator<?> comparator) {
+        final List<Map.Entry<K, V>> entries = new ArrayList<>(map.entrySet());
+        Collections.sort(entries, (Comparator) comparator);
+        final LinkedHashMap<K, V> sortedMap = new LinkedHashMap<>();
+        entries.forEach(entry -> sortedMap.put(entry.getKey(), entry.getValue()));
+        return sortedMap;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PathStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PathStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PathStep.java
new file mode 100644
index 0000000..fcb6b9a
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PathStep.java
@@ -0,0 +1,95 @@
+/*
+ * 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.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalRing;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.MutablePath;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class PathStep<S> extends MapStep<S, Path> implements TraversalParent {
+
+    private TraversalRing<Object, Object> traversalRing;
+
+    public PathStep(final Traversal.Admin traversal) {
+        super(traversal);
+        this.traversalRing = new TraversalRing<>();
+    }
+
+    @Override
+    protected Path map(final Traverser.Admin<S> traverser) {
+        final Path path;
+        if (this.traversalRing.isEmpty())
+            path = traverser.path();
+        else {
+            path = MutablePath.make();
+            traverser.path().forEach((object, labels) -> path.extend(TraversalUtil.apply(object, this.traversalRing.next()), labels.toArray(new String[labels.size()])));
+        }
+        this.traversalRing.reset();
+        return path;
+    }
+
+    @Override
+    public PathStep<S> clone() {
+        final PathStep<S> clone = (PathStep<S>) super.clone();
+        clone.traversalRing = new TraversalRing<>();
+        for (final Traversal.Admin<Object, Object> traversal : this.traversalRing.getTraversals()) {
+            clone.traversalRing.addTraversal(clone.integrateChild(traversal.clone()));
+        }
+        return clone;
+    }
+
+    @Override
+    public void reset() {
+        super.reset();
+        this.traversalRing.reset();
+    }
+
+    @Override
+    public List<Traversal.Admin<Object, Object>> getLocalChildren() {
+        return this.traversalRing.getTraversals();
+    }
+
+    @Override
+    public void addLocalChild(final Traversal.Admin<?, ?> pathTraversal) {
+        this.traversalRing.addTraversal(this.integrateChild(pathTraversal));
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.traversalRing);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.PATH);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertiesStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertiesStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertiesStep.java
new file mode 100644
index 0000000..2504e05
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertiesStep.java
@@ -0,0 +1,71 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.structure.Element;
+import org.apache.tinkerpop.gremlin.structure.PropertyType;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class PropertiesStep<E> extends FlatMapStep<Element, E> {
+
+    protected final String[] propertyKeys;
+    protected final PropertyType returnType;
+
+    public PropertiesStep(final Traversal.Admin traversal, final PropertyType propertyType, final String... propertyKeys) {
+        super(traversal);
+        this.returnType = propertyType;
+        this.propertyKeys = propertyKeys;
+    }
+
+    @Override
+    protected Iterator<E> flatMap(final Traverser.Admin<Element> traverser) {
+        return this.returnType.equals(PropertyType.VALUE) ?
+                traverser.get().values(this.propertyKeys) :
+                (Iterator) traverser.get().properties(this.propertyKeys);
+    }
+
+    public PropertyType getReturnType() {
+        return this.returnType;
+    }
+
+    public String[] getPropertyKeys() {
+        return this.propertyKeys;
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, Arrays.asList(this.propertyKeys), this.returnType.name().toLowerCase());
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyElementStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyElementStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyElementStep.java
new file mode 100644
index 0000000..7cb78e8
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyElementStep.java
@@ -0,0 +1,50 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.structure.Element;
+import org.apache.tinkerpop.gremlin.structure.Property;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class PropertyElementStep<E> extends MapStep<Property<E>, Element> {
+
+    public PropertyElementStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected Element map(final Traverser.Admin<Property<E>> traverser) {
+        return traverser.get().element();
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+
+    // TODO: reverse()
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyMapStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyMapStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyMapStep.java
new file mode 100644
index 0000000..f63faf8
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyMapStep.java
@@ -0,0 +1,91 @@
+/*
+ * 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.T;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.structure.Element;
+import org.apache.tinkerpop.gremlin.structure.PropertyType;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class PropertyMapStep<E> extends MapStep<Element, Map<String, E>> {   // TODO: Map<Object,E> cause of T.
+
+    protected final String[] propertyKeys;
+    protected final PropertyType returnType;
+    protected final boolean includeTokens;
+
+    public PropertyMapStep(final Traversal.Admin traversal, final boolean includeTokens, final PropertyType propertyType, final String... propertyKeys) {
+        super(traversal);
+        this.includeTokens = includeTokens;
+        this.propertyKeys = propertyKeys;
+        this.returnType = propertyType;
+    }
+
+    @Override
+    protected Map<String, E> map(final Traverser.Admin<Element> traverser) {
+        if (this.returnType.equals(PropertyType.VALUE)) {
+            final Element element = traverser.get();
+            final Map map = traverser.get() instanceof Vertex ?
+                    (Map) ElementHelper.vertexPropertyValueMap((Vertex) element, propertyKeys) :
+                    (Map) ElementHelper.propertyValueMap(element, propertyKeys);
+            if (includeTokens) {
+                if (element instanceof VertexProperty) {
+                    map.put(T.id, element.id());
+                    map.put(T.key, ((VertexProperty) element).key());
+                    map.put(T.value, ((VertexProperty) element).value());
+                } else {
+                    map.put(T.id, element.id());
+                    map.put(T.label, element.label());
+                }
+            }
+            return map;
+
+        } else {
+            return traverser.get() instanceof Vertex ?
+                    (Map) ElementHelper.vertexPropertyMap((Vertex) traverser.get(), propertyKeys) :
+                    (Map) ElementHelper.propertyMap(traverser.get(), propertyKeys);
+        }
+    }
+
+    public PropertyType getReturnType() {
+        return this.returnType;
+    }
+
+    public String toString() {
+        return TraversalHelper.makeStepString(this, Arrays.asList(this.propertyKeys), this.returnType.name().toLowerCase());
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyValueStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyValueStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyValueStep.java
new file mode 100644
index 0000000..eab0ea6
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyValueStep.java
@@ -0,0 +1,47 @@
+/*
+ * 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.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.structure.Property;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class PropertyValueStep<E> extends MapStep<Property<E>, E> {
+
+    public PropertyValueStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected E map(final Traverser.Admin<Property<E>> traverser) {
+        return traverser.get().value();
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+}