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:46 UTC

[28/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/filter/FilterStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/FilterStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/FilterStep.java
new file mode 100644
index 0000000..ab364d8
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/FilterStep.java
@@ -0,0 +1,45 @@
+/*
+ * 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.filter;
+
+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;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public abstract class FilterStep<S> extends AbstractStep<S, S> {
+
+    public FilterStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected Traverser<S> processNextStart() {
+        while (true) {
+            final Traverser.Admin<S> traverser = this.starts.next();
+            if (this.filter(traverser)) {
+                return traverser;
+            }
+        }
+    }
+
+    protected abstract boolean filter(final Traverser.Admin<S> traverser);
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasStep.java
new file mode 100644
index 0000000..3efbe5b
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasStep.java
@@ -0,0 +1,69 @@
+/*
+ * 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.filter;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.HasContainerHolder;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.HasContainer;
+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 java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class HasStep<S extends Element> extends FilterStep<S> implements HasContainerHolder {   // TODO: make final when graph strategies are fixed up
+
+    private final HasContainer hasContainer;
+
+    public HasStep(final Traversal.Admin traversal, final HasContainer hasContainer) {
+        super(traversal);
+        this.hasContainer = hasContainer;
+    }
+
+    @Override
+    protected boolean filter(final Traverser.Admin<S> traverser) {
+        return this.hasContainer.test(traverser.get());
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.hasContainer);
+    }
+
+    @Override
+    public List<HasContainer> getHasContainers() {
+        return Collections.singletonList(this.hasContainer);
+    }
+
+    @Override
+    public void addHasContainer(final HasContainer hasContainer) {
+        throw new UnsupportedOperationException(this.getClass().getSimpleName() + " does not support adding new HasContainers");
+    }
+
+    @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/filter/HasTraversalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasTraversalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasTraversalStep.java
new file mode 100644
index 0000000..4cdfc8f
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasTraversalStep.java
@@ -0,0 +1,80 @@
+/*
+ * 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.filter;
+
+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.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 java.util.Collections;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public final class HasTraversalStep<S> extends AbstractStep<S, S> implements TraversalParent {
+
+    private Traversal.Admin<S, ?> hasTraversal;
+    private final boolean negate;
+
+    public HasTraversalStep(final Traversal.Admin traversal, final Traversal.Admin<S, ?> hasTraversal, final boolean negate) {
+        super(traversal);
+        this.negate = negate;
+        this.hasTraversal = this.integrateChild(hasTraversal);
+    }
+
+    @Override
+    protected Traverser<S> processNextStart() throws NoSuchElementException {
+        while (true) {
+            final Traverser.Admin<S> start = this.starts.next();
+            if (TraversalUtil.test(start, this.hasTraversal) != this.negate)
+                return start;
+        }
+    }
+
+    @Override
+    public String toString() {
+        final String stepString = TraversalHelper.makeStepString(this, this.hasTraversal);
+        return this.negate ? stepString.replaceFirst("\\(", "(!") : stepString;
+    }
+
+    @Override
+    public List<Traversal<S, ?>> getLocalChildren() {
+        return Collections.singletonList(this.hasTraversal);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return this.getSelfAndChildRequirements();
+    }
+
+    @Override
+    public HasTraversalStep<S> clone() {
+        final HasTraversalStep<S> clone = (HasTraversalStep<S>) super.clone();
+        clone.hasTraversal = clone.integrateChild(this.hasTraversal.clone());
+        return clone;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/IsStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/IsStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/IsStep.java
new file mode 100644
index 0000000..0f33178
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/IsStep.java
@@ -0,0 +1,66 @@
+/*
+ * 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.filter;
+
+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 java.util.Collections;
+import java.util.Set;
+import java.util.function.BiPredicate;
+
+/**
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public final class IsStep<S> extends FilterStep<S> {
+
+    private final Object value;
+    private final BiPredicate<S, Object> biPredicate;
+
+    public IsStep(final Traversal.Admin traversal, final BiPredicate<S, Object> biPredicate, final Object value) {
+        super(traversal);
+        this.value = value;
+        this.biPredicate = biPredicate;
+    }
+
+    @Override
+    protected boolean filter(final Traverser.Admin<S> traverser) {
+        return this.biPredicate.test(traverser.get(), this.value);
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.biPredicate, this.value);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    public BiPredicate<S, Object> getPredicate() {
+        return biPredicate;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/LambdaFilterStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/LambdaFilterStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/LambdaFilterStep.java
new file mode 100644
index 0000000..0036733
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/LambdaFilterStep.java
@@ -0,0 +1,52 @@
+/*
+ * 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.filter;
+
+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.Predicate;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class LambdaFilterStep<S> extends FilterStep<S> {
+
+    private final Predicate<Traverser<S>> predicate;
+
+    public LambdaFilterStep(final Traversal.Admin traversal, final Predicate<Traverser<S>> predicate) {
+        super(traversal);
+        this.predicate = predicate;
+    }
+
+    public Predicate<Traverser<S>> getPredicate() {
+        return predicate;
+    }
+
+    @Override
+    protected boolean filter(final Traverser.Admin<S> traverser) {
+        return this.predicate.test(traverser);
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this,this.predicate);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/OrStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/OrStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/OrStep.java
new file mode 100644
index 0000000..9f2dec8
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/OrStep.java
@@ -0,0 +1,39 @@
+/*
+ * 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.filter;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class OrStep<S> extends ConjunctionStep<S> implements TraversalParent {
+
+    public OrStep(final Traversal.Admin traversal, final Traversal.Admin<S, ?>... orTraversals) {
+        super(traversal, orTraversals);
+
+    }
+
+    public static final class OrMarker<S> extends ConjunctionMarker<S> {
+        public OrMarker(final Traversal.Admin traversal) {
+            super(traversal);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
new file mode 100644
index 0000000..72e92ef
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -0,0 +1,113 @@
+/*
+ * 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.filter;
+
+import org.apache.tinkerpop.gremlin.process.traversal.FastNoSuchElementException;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Ranging;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * @author Bob Briody (http://bobbriody.com)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging {
+
+    private final long low;
+    private final long high;
+    private AtomicLong counter = new AtomicLong(0l);
+
+    public RangeGlobalStep(final Traversal.Admin traversal, final long low, final long high) {
+        super(traversal);
+        if (low != -1 && high != -1 && low > high) {
+            throw new IllegalArgumentException("Not a legal range: [" + low + ", " + high + ']');
+        }
+        this.low = low;
+        this.high = high;
+    }
+
+    @Override
+    protected boolean filter(final Traverser.Admin<S> traverser) {
+        if (this.high != -1 && this.counter.get() >= this.high) {
+            throw FastNoSuchElementException.instance();
+        }
+
+        long avail = traverser.bulk();
+        if (this.counter.get() + avail <= this.low) {
+            // Will not surpass the low w/ this traverser. Skip and filter the whole thing.
+            this.counter.getAndAdd(avail);
+            return false;
+        }
+
+        // Skip for the low and trim for the high. Both can happen at once.
+
+        long toSkip = 0;
+        if (this.counter.get() < this.low) {
+            toSkip = this.low - this.counter.get();
+        }
+
+        long toTrim = 0;
+        if (this.high != -1 && this.counter.get() + avail >= this.high) {
+            toTrim = this.counter.get() + avail - this.high;
+        }
+
+        long toEmit = avail - toSkip - toTrim;
+        this.counter.getAndAdd(toSkip + toEmit);
+        traverser.asAdmin().setBulk(toEmit);
+
+        return true;
+    }
+
+    @Override
+    public void reset() {
+        super.reset();
+        this.counter.set(0l);
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.low, this.high);
+    }
+
+    public long getLowRange() {
+        return this.low;
+    }
+
+    public long getHighRange() {
+        return this.high;
+    }
+
+    @Override
+    public RangeGlobalStep<S> clone() {
+        final RangeGlobalStep<S> clone = (RangeGlobalStep<S>) super.clone();
+        clone.counter = new AtomicLong(0l);
+        return clone;
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.BULK);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RetainStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RetainStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RetainStep.java
new file mode 100644
index 0000000..bc217d3
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RetainStep.java
@@ -0,0 +1,97 @@
+/*
+ * 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.filter;
+
+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 java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class RetainStep<S> extends FilterStep<S> {
+
+    private final String sideEffectKeyOrPathLabel;
+    private final Collection<S> retainCollection;
+    private final S retainObject;
+    private final short choice;
+
+    public RetainStep(final Traversal.Admin traversal, final String sideEffectKeyOrPathLabel) {
+        super(traversal);
+        this.sideEffectKeyOrPathLabel = sideEffectKeyOrPathLabel;
+        this.retainCollection = null;
+        this.retainObject = null;
+        this.choice = 0;
+    }
+
+    public RetainStep(final Traversal.Admin traversal, final Collection<S> retainCollection) {
+        super(traversal);
+        this.sideEffectKeyOrPathLabel = null;
+        this.retainCollection = retainCollection;
+        this.retainObject = null;
+        this.choice = 1;
+    }
+
+    public RetainStep(final Traversal.Admin traversal, final S retainObject) {
+        super(traversal);
+        this.sideEffectKeyOrPathLabel = null;
+        this.retainCollection = null;
+        this.retainObject = retainObject;
+        this.choice = 2;
+    }
+
+    @Override
+    protected boolean filter(final Traverser.Admin<S> traverser) {
+        switch (this.choice) {
+            case 0: {
+                final Object retain = traverser.asAdmin().getSideEffects().exists(this.sideEffectKeyOrPathLabel) ?
+                        traverser.sideEffects(this.sideEffectKeyOrPathLabel) :
+                        traverser.path(this.sideEffectKeyOrPathLabel);
+                return retain instanceof Collection ?
+                        ((Collection) retain).contains(traverser.get()) :
+                        retain.equals(traverser.get());
+            }
+            case 1:
+                return this.retainCollection.contains(traverser.get());
+            default:
+                return this.retainObject.equals(traverser.get());
+        }
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.sideEffectKeyOrPathLabel);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return null == this.sideEffectKeyOrPathLabel ?
+                Collections.singleton(TraverserRequirement.OBJECT) :
+                Stream.of(TraverserRequirement.OBJECT,
+                        TraverserRequirement.SIDE_EFFECTS,
+                        TraverserRequirement.PATH_ACCESS).collect(Collectors.toSet());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/SampleGlobalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/SampleGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/SampleGlobalStep.java
new file mode 100644
index 0000000..5817f37
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/SampleGlobalStep.java
@@ -0,0 +1,117 @@
+/*
+ * 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.filter;
+
+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.CollectingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.lambda.ConstantTraversal;
+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.traverser.util.TraverserSet;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class SampleGlobalStep<S> extends CollectingBarrierStep<S> implements TraversalParent {
+
+    private Traversal.Admin<S, Number> probabilityTraversal = new ConstantTraversal<>(1.0d);
+    private final int amountToSample;
+    private static final Random RANDOM = new Random();
+
+    public SampleGlobalStep(final Traversal.Admin traversal, final int amountToSample) {
+        super(traversal);
+        this.amountToSample = amountToSample;
+    }
+
+    @Override
+    public List<Traversal.Admin<S, Number>> getLocalChildren() {
+        return Collections.singletonList(this.probabilityTraversal);
+    }
+
+    @Override
+    public void addLocalChild(final Traversal.Admin<?, ?> probabilityTraversal) {
+        this.probabilityTraversal = this.integrateChild(probabilityTraversal);
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.amountToSample, this.probabilityTraversal);
+    }
+
+    @Override
+    public void barrierConsumer(final TraverserSet<S> traverserSet) {
+        // return the entire traverser set if the set is smaller than the amount to sample
+        if (traverserSet.bulkSize() <= this.amountToSample)
+            return;
+        //////////////// else sample the set
+        double totalWeight = 0.0d;
+        for (final Traverser<S> s : traverserSet) {
+            totalWeight = totalWeight + TraversalUtil.apply(s.asAdmin(), this.probabilityTraversal).doubleValue() * s.bulk();
+        }
+        ///////
+        final TraverserSet<S> sampledSet = new TraverserSet<>();
+        int runningAmountToSample = 0;
+        while (runningAmountToSample < this.amountToSample) {
+            boolean reSample = false;
+            double runningWeight = 0.0d;
+            for (final Traverser.Admin<S> s : traverserSet) {
+                long sampleBulk = sampledSet.contains(s) ? sampledSet.get(s).bulk() : 0;
+                if (sampleBulk < s.bulk()) {
+                    final double currentWeight = TraversalUtil.apply(s, this.probabilityTraversal).doubleValue();
+                    for (int i = 0; i < (s.bulk() - sampleBulk); i++) {
+                        runningWeight = runningWeight + currentWeight;
+                        if (RANDOM.nextDouble() <= (runningWeight / totalWeight)) {
+                            final Traverser.Admin<S> split = s.asAdmin().split();
+                            split.asAdmin().setBulk(1l);
+                            sampledSet.add(split);
+                            runningAmountToSample++;
+                            totalWeight = totalWeight - currentWeight;
+                            reSample = true;
+                            break;
+                        }
+                    }
+                    if (reSample || (runningAmountToSample >= this.amountToSample))
+                        break;
+                }
+            }
+        }
+        traverserSet.clear();
+        traverserSet.addAll(sampledSet);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return this.getSelfAndChildRequirements(TraverserRequirement.BULK);
+    }
+
+    @Override
+    public SampleGlobalStep<S> clone() {
+        final SampleGlobalStep<S> clone = (SampleGlobalStep<S>) super.clone();
+        clone.probabilityTraversal = clone.integrateChild(this.probabilityTraversal.clone());
+        return clone;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/SimplePathStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/SimplePathStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/SimplePathStep.java
new file mode 100644
index 0000000..5789803
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/SimplePathStep.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.filter;
+
+
+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.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class SimplePathStep<S> extends FilterStep<S> {
+
+    public SimplePathStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected boolean filter(final Traverser.Admin<S> traverser) {
+        return traverser.path().isSimple();
+    }
+
+    @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/filter/TimeLimitStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TimeLimitStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TimeLimitStep.java
new file mode 100644
index 0000000..c0e5f28
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TimeLimitStep.java
@@ -0,0 +1,80 @@
+/*
+ * 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.filter;
+
+import org.apache.tinkerpop.gremlin.process.traversal.FastNoSuchElementException;
+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.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * @author Randall Barnhart (random pi)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public final class TimeLimitStep<S> extends FilterStep<S> {
+
+    private AtomicLong startTime = new AtomicLong(-1);
+    private final long timeLimit;
+    private AtomicBoolean timedOut = new AtomicBoolean(false);
+
+
+    public TimeLimitStep(final Traversal.Admin traversal, final long timeLimit) {
+        super(traversal);
+        this.timeLimit = timeLimit;
+    }
+
+    @Override
+    protected boolean filter(final Traverser.Admin<S> traverser) {
+        if (this.startTime.get() == -1l)
+            this.startTime.set(System.currentTimeMillis());
+        if ((System.currentTimeMillis() - this.startTime.get()) >= this.timeLimit) {
+            this.timedOut.set(true);
+            throw FastNoSuchElementException.instance();
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.timeLimit);
+    }
+
+    @Override
+    public void reset() {
+        super.reset();
+        this.startTime.set(-1l);
+        this.timedOut.set(false);
+    }
+
+    public boolean getTimedOut() {
+        return this.timedOut.get();
+    }
+
+    @Override
+    public TimeLimitStep<S> clone() {
+        final TimeLimitStep<S> clone = (TimeLimitStep<S>) super.clone();
+        clone.timedOut = new AtomicBoolean(this.timedOut.get());
+        clone.startTime = new AtomicLong(this.startTime.get());
+        return clone;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/4c97e964/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
new file mode 100644
index 0000000..14c541a
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
@@ -0,0 +1,132 @@
+/*
+ * 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.filter;
+
+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.step.util.MarkerIdentityStep;
+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.traverser.TraverserRequirement;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BiPredicate;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class WhereStep<E> extends FilterStep<Map<String, E>> implements TraversalParent {
+
+    private final String firstKey;
+    private final String secondKey;
+    private final BiPredicate biPredicate;
+    private Traversal.Admin constraint;
+
+
+    public WhereStep(final Traversal.Admin traversal, final String firstKey, final String secondKey, final BiPredicate<E, E> biPredicate) {
+        super(traversal);
+        this.firstKey = firstKey;
+        this.secondKey = secondKey;
+        this.biPredicate = biPredicate;
+        this.constraint = null;
+    }
+
+    public WhereStep(final Traversal.Admin traversal, final Traversal.Admin constraint) {
+        super(traversal);
+        this.firstKey = null;
+        this.secondKey = null;
+        this.biPredicate = null;
+        this.constraint = this.integrateChild(constraint);
+    }
+
+    @Override
+    protected boolean filter(final Traverser.Admin<Map<String, E>> traverser) {
+        if (null == this.constraint) {
+            final Map<String, E> map = traverser.get();
+            if (!map.containsKey(this.firstKey))
+                throw new IllegalArgumentException("The provided key is not in the current map: " + this.firstKey);
+            if (!map.containsKey(this.secondKey))
+                throw new IllegalArgumentException("The provided key is not in the current map: " + this.secondKey);
+            return this.biPredicate.test(map.get(this.firstKey), map.get(this.secondKey));
+        } else {
+            final Step<?, ?> startStep = this.constraint.getStartStep();
+            Step<?, ?> endStep = this.constraint.getEndStep();
+            if (endStep instanceof MarkerIdentityStep) // DAH!
+                endStep = endStep.getPreviousStep();
+
+            final Map<String, E> map = traverser.get();
+            if (!map.containsKey(startStep.getLabel().get()))
+                throw new IllegalArgumentException("The provided key is not in the current map: " + startStep.getLabel().get());
+            final Object startObject = map.get(startStep.getLabel().get());
+            final Object endObject;
+            if (endStep.getLabel().isPresent()) {
+                if (!map.containsKey(endStep.getLabel().get()))
+                    throw new IllegalArgumentException("The provided key is not in the current map: " + endStep.getLabel().get());
+                endObject = map.get(endStep.getLabel().get());
+            } else
+                endObject = null;
+
+            startStep.addStart(this.getTraversal().asAdmin().getTraverserGenerator().generate(startObject, (Step) startStep, traverser.bulk()));
+            if (null == endObject) {
+                if (this.constraint.hasNext()) {
+                    this.constraint.reset();
+                    return true;
+                } else {
+                    return false;
+                }
+
+            } else {
+                while (this.constraint.hasNext()) {
+                    if (this.constraint.next().equals(endObject)) {
+                        this.constraint.reset();
+                        return true;
+                    }
+                }
+                return false;
+            }
+        }
+    }
+
+    @Override
+    public List<Traversal.Admin> getLocalChildren() {
+        return null == this.constraint ? Collections.emptyList() : Collections.singletonList(this.constraint);
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.firstKey, this.biPredicate, this.secondKey, this.constraint);
+    }
+
+    @Override
+    public WhereStep<E> clone() {
+        final WhereStep<E> clone = (WhereStep<E>) super.clone();
+        if (null != this.constraint)
+            clone.constraint = clone.integrateChild(this.constraint.clone());
+        return clone;
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return this.getSelfAndChildRequirements(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/AddEdgeByPathStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeByPathStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeByPathStep.java
new file mode 100644
index 0000000..9671f34
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeByPathStep.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.Mutating;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class AddEdgeByPathStep extends MapStep<Vertex, Edge> implements Mutating {
+
+    private static final Set<TraverserRequirement> REQUIREMENTS = EnumSet.of(
+            TraverserRequirement.PATH,
+            TraverserRequirement.OBJECT
+    );
+
+    // TODO: Weight key based on Traverser.getCount() ?
+
+    private final Direction direction;
+    private final String edgeLabel;
+    private final String stepLabel;
+    private final Object[] keyValues;
+
+    public AddEdgeByPathStep(final Traversal.Admin traversal, final Direction direction, final String edgeLabel, final String stepLabel, final Object... keyValues) {
+        super(traversal);
+        this.direction = direction;
+        if (this.direction.equals(Direction.BOTH))
+            throw new IllegalArgumentException("Only in- and out- directions are supported by " + AddEdgeByPathStep.class.getSimpleName());
+        this.edgeLabel = edgeLabel;
+        this.stepLabel = stepLabel;
+        this.keyValues = keyValues;
+    }
+
+    public Direction getDirection() {
+        return direction;
+    }
+
+    public String getEdgeLabel() {
+        return edgeLabel;
+    }
+
+    public String getStepLabel() {
+        return stepLabel;
+    }
+
+    public Object[] getKeyValues() {
+        return keyValues;
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.direction.name(), this.edgeLabel, this.stepLabel);
+    }
+
+    @Override
+    protected Edge map(Traverser.Admin<Vertex> traverser) {
+        final Vertex currentVertex = traverser.get();
+        final Vertex otherVertex = traverser.path().get(this.stepLabel);
+        if (this.direction.equals(Direction.IN))
+            return otherVertex.addEdge(this.edgeLabel, currentVertex, this.keyValues);
+        else
+            return currentVertex.addEdge(this.edgeLabel, otherVertex, this.keyValues);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return REQUIREMENTS;
+    }
+}

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/AddEdgeStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java
new file mode 100644
index 0000000..e96c65f
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java
@@ -0,0 +1,86 @@
+/*
+ * 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.Mutating;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class AddEdgeStep extends FlatMapStep<Vertex, Edge> implements Mutating {
+
+    private static final Set<TraverserRequirement> REQUIREMENTS = EnumSet.of(TraverserRequirement.OBJECT);
+
+    private final String edgeLabel;
+    private final Object[] keyValues;
+    private final List<Vertex> vertices;
+    private final Direction direction;
+
+    public AddEdgeStep(final Traversal.Admin traversal, final Direction direction, final String edgeLabel, final Vertex vertex, final Object... keyValues) {
+        this(traversal, direction, edgeLabel, IteratorUtils.of(vertex), keyValues);
+    }
+
+    public AddEdgeStep(final Traversal.Admin traversal, final Direction direction, final String edgeLabel, final Iterator<Vertex> vertices, final Object... keyValues) {
+        super(traversal);
+        this.direction = direction;
+        this.edgeLabel = edgeLabel;
+        this.vertices = IteratorUtils.list(vertices);
+        this.keyValues = keyValues;
+    }
+
+    public Direction getDirection() {
+        return direction;
+    }
+
+    public String getEdgeLabel() {
+        return edgeLabel;
+    }
+
+    public Object[] getKeyValues() {
+        return keyValues;
+    }
+
+    public List<Vertex> getVertices() {
+        return vertices;
+    }
+
+    @Override
+    protected Iterator<Edge> flatMap(final Traverser.Admin<Vertex> traverser) {
+        return IteratorUtils.map(this.vertices.iterator(), this.direction.equals(Direction.OUT) ?
+                vertex -> traverser.get().addEdge(this.edgeLabel, vertex, this.keyValues) :
+                vertex -> vertex.addEdge(this.edgeLabel, traverser.get(), this.keyValues));
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return REQUIREMENTS;
+    }
+}

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/AddVertexStartStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.java
new file mode 100644
index 0000000..2f90ea1
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.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.FastNoSuchElementException;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Mutating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class AddVertexStartStep extends AbstractStep<Vertex, Vertex> implements Mutating {
+
+    private final Object[] keyValues;
+    private boolean first = true;
+
+    public AddVertexStartStep(final Traversal.Admin traversal, final Object... keyValues) {
+        super(traversal);
+        this.keyValues = keyValues;
+    }
+
+    public Object[] getKeyValues() {
+        return keyValues;
+    }
+
+    @Override
+    protected Traverser<Vertex> processNextStart() {
+        if (this.first) {
+            this.first = false;
+            return this.getTraversal().getTraverserGenerator().generate(this.getTraversal().getGraph().get().addVertex(this.keyValues), this, 1l);
+        } else
+            throw FastNoSuchElementException.instance();
+    }
+}

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/AddVertexStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStep.java
new file mode 100644
index 0000000..0632f87
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStep.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.step.Mutating;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class AddVertexStep<S> extends MapStep<S, Vertex> implements Mutating {
+
+    private final Object[] keyValues;
+    private final transient Graph graph;
+
+    public AddVertexStep(final Traversal.Admin traversal, final Object... keyValues) {
+        super(traversal);
+        this.keyValues = keyValues;
+        this.graph = this.getTraversal().getGraph().get();
+    }
+
+    public Object[] getKeyValues() {
+        return keyValues;
+    }
+
+    @Override
+    protected Vertex map(final Traverser.Admin<S> traverser) {
+        return this.graph.addVertex(this.keyValues);
+    }
+}

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/BackStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/BackStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/BackStep.java
new file mode 100644
index 0000000..9d683df
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/BackStep.java
@@ -0,0 +1,64 @@
+/*
+ * 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.TraversalEngine;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.EngineDependent;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+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 final class BackStep<S, E> extends MapStep<S, E> implements EngineDependent {
+
+    private final String stepLabel;
+    private boolean requiresPaths = false;
+
+    public BackStep(final Traversal.Admin traversal, final String stepLabel) {
+        super(traversal);
+        this.stepLabel = stepLabel;
+    }
+
+    @Override
+    protected E map(final Traverser.Admin<S> traverser) {
+        return traverser.path(this.stepLabel);
+    }
+
+    @Override
+    public void onEngine(final TraversalEngine traversalEngine) {
+        this.requiresPaths = traversalEngine.isComputer();
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        //return this.requiresPaths ? Collections.singleton(TraverserRequirement.PATH) : Collections.singleton(TraverserRequirement.PATH_ACCESS);
+        return Collections.singleton(TraverserRequirement.PATH); // TODO: if the traversal isn't nested, path access works
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.stepLabel);
+    }
+}

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/CoalesceStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CoalesceStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CoalesceStep.java
new file mode 100644
index 0000000..a0a8d7f
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CoalesceStep.java
@@ -0,0 +1,86 @@
+/*
+ * 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.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.util.iterator.EmptyIterator;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public final class CoalesceStep<S, E> extends FlatMapStep<S, E> implements TraversalParent {
+
+    private List<Traversal.Admin<S, E>> coalesceTraversals;
+
+    @SafeVarargs
+    public CoalesceStep(final Traversal.Admin traversal, final Traversal.Admin<S, E>... coalesceTraversals) {
+        super(traversal);
+        this.coalesceTraversals = Arrays.asList(coalesceTraversals);
+        for (final Traversal.Admin<S, ?> conjunctionTraversal : this.coalesceTraversals) {
+            this.integrateChild(conjunctionTraversal);
+        }
+    }
+
+    @Override
+    protected Iterator<E> flatMap(final Traverser.Admin<S> traverser) {
+        for (final Traversal.Admin<S, E> coalesceTraversal : this.coalesceTraversals) {
+            coalesceTraversal.reset();
+            coalesceTraversal.addStart(traverser.asAdmin().split());
+            if (coalesceTraversal.hasNext())
+                return coalesceTraversal;
+        }
+        return EmptyIterator.instance();
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return this.getSelfAndChildRequirements();
+    }
+
+    @Override
+    public List<Traversal.Admin<S, E>> getLocalChildren() {
+        return Collections.unmodifiableList(this.coalesceTraversals);
+    }
+
+    @Override
+    public CoalesceStep<S, E> clone() {
+        final CoalesceStep<S, E> clone = (CoalesceStep<S, E>) super.clone();
+        clone.coalesceTraversals = new ArrayList<>();
+        for (final Traversal.Admin<S, ?> conjunctionTraversal : this.coalesceTraversals) {
+            clone.coalesceTraversals.add(clone.integrateChild(conjunctionTraversal.clone()));
+        }
+        return clone;
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.coalesceTraversals);
+    }
+}

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/CountGlobalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CountGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CountGlobalStep.java
new file mode 100644
index 0000000..cb7ede4
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CountGlobalStep.java
@@ -0,0 +1,134 @@
+/*
+ * 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.EnumSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.function.BiFunction;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class CountGlobalStep<S> extends ReducingBarrierStep<S, Long> implements MapReducer {
+
+    private static final Set<TraverserRequirement> REQUIREMENTS = EnumSet.of(TraverserRequirement.BULK);
+
+    public CountGlobalStep(final Traversal.Admin traversal) {
+        super(traversal);
+        this.setSeedSupplier(new ConstantSupplier<>(0L));
+        this.setBiFunction(CountBiFunction.<S>instance());
+    }
+
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return REQUIREMENTS;
+    }
+
+    @Override
+    public MapReduce<MapReduce.NullObject, Long, MapReduce.NullObject, Long, Long> getMapReduce() {
+        return CountGlobalMapReduce.instance();
+    }
+
+    ///////////
+
+    private static class CountBiFunction<S> implements BiFunction<Long, Traverser<S>, Long>, Serializable {
+
+        private static final CountBiFunction INSTANCE = new CountBiFunction();
+
+        private CountBiFunction() {
+
+        }
+
+        @Override
+        public Long apply(final Long mutatingSeed, final Traverser<S> traverser) {
+            return mutatingSeed + traverser.bulk();
+        }
+
+        public final static <S> CountBiFunction<S> instance() {
+            return INSTANCE;
+        }
+    }
+
+    ///////////
+
+    private static class CountGlobalMapReduce extends StaticMapReduce<MapReduce.NullObject, Long, MapReduce.NullObject, Long, Long> {
+
+        private static CountGlobalMapReduce INSTANCE = new CountGlobalMapReduce();
+
+        private CountGlobalMapReduce() {
+
+        }
+
+        @Override
+        public boolean doStage(final MapReduce.Stage stage) {
+            return true;
+        }
+
+        @Override
+        public void map(final Vertex vertex, final MapEmitter<NullObject, Long> emitter) {
+            vertex.<TraverserSet<?>>property(TraversalVertexProgram.HALTED_TRAVERSERS).ifPresent(traverserSet -> traverserSet.forEach(traverser -> emitter.emit(traverser.bulk())));
+        }
+
+        @Override
+        public void combine(final NullObject key, final Iterator<Long> values, final ReduceEmitter<NullObject, Long> emitter) {
+            this.reduce(key, values, emitter);
+        }
+
+        @Override
+        public void reduce(final NullObject key, final Iterator<Long> values, final ReduceEmitter<NullObject, Long> emitter) {
+            long count = 0l;
+            while (values.hasNext()) {
+                count = count + values.next();
+            }
+            emitter.emit(count);
+        }
+
+        @Override
+        public String getMemoryKey() {
+            return REDUCING;
+        }
+
+        @Override
+        public Long generateFinalResult(final Iterator<KeyValue<NullObject, Long>> keyValues) {
+            return keyValues.hasNext() ? keyValues.next().getValue() : 0L;
+        }
+
+        public static final CountGlobalMapReduce instance() {
+            return INSTANCE;
+        }
+
+    }
+
+}

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/CountLocalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CountLocalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CountLocalStep.java
new file mode 100644
index 0000000..8c6dc9d
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CountLocalStep.java
@@ -0,0 +1,51 @@
+/*
+ * 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.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public final class CountLocalStep<S> extends MapStep<S, Long> {
+
+    public CountLocalStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected Long map(final Traverser.Admin<S> traverser) {
+        final S item = traverser.get();
+        return (item instanceof Collection) ? ((Collection) item).size()
+                : (item instanceof Map) ? ((Map) item).size() : 1L;
+    }
+
+    @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/DedupLocalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DedupLocalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DedupLocalStep.java
new file mode 100644
index 0000000..59c66c7
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DedupLocalStep.java
@@ -0,0 +1,51 @@
+/*
+ * 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.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public final class DedupLocalStep<E, S extends Iterable<E>> extends MapStep<S, Set<E>> {
+
+    public DedupLocalStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected Set<E> map(final Traverser.Admin<S> traverser) {
+        final Set<E> result = new LinkedHashSet<>();
+        for (final E item : traverser.get()) {
+            result.add(item);
+        }
+        return 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/EdgeOtherVertexStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/EdgeOtherVertexStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/EdgeOtherVertexStep.java
new file mode 100644
index 0000000..411737c
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/EdgeOtherVertexStep.java
@@ -0,0 +1,58 @@
+/*
+ * 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.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class EdgeOtherVertexStep extends MapStep<Edge, Vertex> {
+
+    public EdgeOtherVertexStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected Vertex map(final Traverser.Admin<Edge> traverser) {
+        final List<Object> objects = traverser.path().objects();
+        for (int i = objects.size() - 2; i >= 0; i--) {
+            if (objects.get(i) instanceof Vertex) {
+                return ElementHelper.areEqual((Vertex) objects.get(i), traverser.get().outVertex()) ?
+                        traverser.get().inVertex() :
+                        traverser.get().outVertex();
+            }
+        }
+        throw new IllegalStateException("The path history of the traverser does not contain a previous vertex: " + traverser.path());
+    }
+
+    @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/EdgeVertexStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/EdgeVertexStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/EdgeVertexStep.java
new file mode 100644
index 0000000..4783e25
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/EdgeVertexStep.java
@@ -0,0 +1,67 @@
+/*
+ * 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.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class EdgeVertexStep extends FlatMapStep<Edge, Vertex> {
+
+    private Direction direction;
+
+    public EdgeVertexStep(final Traversal.Admin traversal, final Direction direction) {
+        super(traversal);
+        this.direction = direction;
+    }
+
+    @Override
+    protected Iterator<Vertex> flatMap(final Traverser.Admin<Edge> traverser) {
+        return traverser.get().vertices(this.direction);
+    }
+
+    @Override
+    public String toString() {
+        return TraversalHelper.makeStepString(this, this.direction);
+    }
+
+    public Direction getDirection() {
+        return this.direction;
+    }
+
+    public void reverseDirection() {
+        this.direction = this.direction.opposite();
+    }
+
+    @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/FlatMapStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FlatMapStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FlatMapStep.java
new file mode 100644
index 0000000..eb111c8
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FlatMapStep.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.step.util.AbstractStep;
+import org.apache.tinkerpop.gremlin.util.iterator.EmptyIterator;
+
+import java.util.Iterator;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public abstract class FlatMapStep<S, E> extends AbstractStep<S, E> {
+
+    private Traverser.Admin<S> head = null;
+    private Iterator<E> iterator = EmptyIterator.instance();
+
+    public FlatMapStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected Traverser<E> processNextStart() {
+        while (true) {
+            if (this.iterator.hasNext()) {
+                return this.head.split(this.iterator.next(), this);
+            } else {
+                this.head = this.starts.next();
+                this.iterator = this.flatMap(this.head);
+            }
+        }
+    }
+
+    protected abstract Iterator<E> flatMap(final Traverser.Admin<S> traverser);
+
+    @Override
+    public void reset() {
+        super.reset();
+        this.iterator = EmptyIterator.instance();
+    }
+}

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/FoldStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FoldStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FoldStep.java
new file mode 100644
index 0000000..27580a9
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FoldStep.java
@@ -0,0 +1,93 @@
+/*
+ * 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.ReducingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.util.function.ArrayListSupplier;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.Supplier;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class FoldStep<S, E> extends ReducingBarrierStep<S, E> {
+
+    private static final Set<TraverserRequirement> REQUIREMENTS = EnumSet.of(TraverserRequirement.OBJECT);
+
+    public FoldStep(final Traversal.Admin traversal) {
+        this(traversal, (Supplier) ArrayListSupplier.instance(), (BiFunction) ArrayListBiFunction.instance());
+    }
+
+    public FoldStep(final Traversal.Admin traversal, final Supplier<E> seed, final BiFunction<E, S, E> foldFunction) {
+        super(traversal);
+        this.setSeedSupplier(seed);
+        this.setBiFunction(new FoldBiFunction<>(foldFunction));
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return REQUIREMENTS;
+    }
+
+    /////////
+
+    private static class ArrayListBiFunction<S> implements BiFunction<ArrayList<S>, S, ArrayList<S>>, Serializable {
+
+        private static final ArrayListBiFunction INSTANCE = new ArrayListBiFunction();
+
+        private ArrayListBiFunction() {
+
+        }
+
+        @Override
+        public ArrayList<S> apply(final ArrayList<S> mutatingSeed, final S traverser) {
+            mutatingSeed.add(traverser);
+            return mutatingSeed;
+        }
+
+        public final static <S> ArrayListBiFunction<S> instance() {
+            return INSTANCE;
+        }
+    }
+
+    ///////
+
+    public static class FoldBiFunction<S, E> implements BiFunction<E, Traverser<S>, E>, Serializable {
+
+        private final BiFunction<E, S, E> biFunction;
+
+        public FoldBiFunction(final BiFunction<E, S, E> biFunction) {
+            this.biFunction = biFunction;
+        }
+
+        @Override
+        public E apply(final E seed, final Traverser<S> traverser) {
+            return this.biFunction.apply(seed, traverser.get());
+        }
+
+    }
+}