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/06/23 19:47:51 UTC

incubator-tinkerpop git commit: Split WhereStep into WhereTraversalStep and WherePredicateStep to make the internals easier to understand. Added a not(pattern) example to MatchStep documentation. Updated the publish-docs.sh to build the docs first before

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/master b410bf718 -> d299f9491


Split WhereStep into WhereTraversalStep and WherePredicateStep to make the internals easier to understand. Added a not(pattern) example to MatchStep documentation. Updated the publish-docs.sh to build the docs first before svn co and deleting the historic docs. Thus, any errors in doc building will be less of a stress.


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

Branch: refs/heads/master
Commit: d299f949109e9a97e41d8c8d10c1968216319e62
Parents: b410bf7
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Jun 23 11:47:44 2015 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Jun 23 11:47:44 2015 -0600

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   3 +-
 bin/publish-docs.sh                             |   7 +-
 docs/src/the-traversal.asciidoc                 |  14 +-
 .../traversal/dsl/graph/GraphTraversal.java     |   9 +-
 .../step/filter/WherePredicateStep.java         | 147 +++++++++
 .../traversal/step/filter/WhereStep.java        | 318 -------------------
 .../step/filter/WhereTraversalStep.java         | 253 +++++++++++++++
 .../process/traversal/step/map/MatchStep.java   |  31 +-
 .../strategy/finalization/ScopingStrategy.java  |   1 -
 .../AdjacentToIncidentStrategy.java             |   4 +-
 .../optimization/MatchPredicateStrategy.java    |  12 +-
 .../ComputerVerificationStrategy.java           |   8 +-
 .../process/traversal/util/TraversalHelper.java |  19 +-
 .../traversal/step/filter/WhereStepTest.java    |  23 +-
 .../traversal/step/map/MatchStepTest.java       | 153 ++++++---
 .../SubgraphStrategyTraverseTest.java           |   1 -
 .../RangeByIsCountStrategyTest.java             |   1 -
 17 files changed, 577 insertions(+), 427 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index a20d8b1..307431f 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -25,9 +25,10 @@ image::http://www.tinkerpop.com/docs/current/images/gremlin-hindu.png[width=225]
 TinkerPop 3.0.0.GA (NOT OFFICIALLY RELEASED YET)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+* Split `WhereStep` into `WherePredicateStep` and `WhereTraversalStep` to simplify internals.
 * Added `Traversal.toStream()` to turn the `Traversal<S,E>` into a `Stream<E>`.
 * Added `Scoping.Variable` enum of `START` and `END` which allows the `Scoping` step to specify where its bindings are.
-* `ComputerVerificationStrategy` is smart about not allowing `WhereStep` with a start-variable to run in OLAP as it selects the value from the path.
+* `ComputerVerificationStrategy` is smart about not allowing `WhereXXXStep` with a start-variable to run in OLAP as it selects the value from the path.
 * Rewrote `MatchStep` where it now works on `GraphComputer`, solves more patterns, provides plugable execution plans, supports nested AND/OR, `not()`-patterns, etc.
 * Renamed `Graphs` in Gremlin Server to `GraphManager`.
 * Fixed bug in Gremlin Driver where client-side serialization errors would not bubble up properly.

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/bin/publish-docs.sh
----------------------------------------------------------------------
diff --git a/bin/publish-docs.sh b/bin/publish-docs.sh
index 59960f0..7b42893 100755
--- a/bin/publish-docs.sh
+++ b/bin/publish-docs.sh
@@ -31,6 +31,10 @@ SVN_CMD="svn --no-auth-cache --username=${USERNAME}"
 VERSION=$(cat pom.xml | grep -A1 '<artifactId>tinkerpop</artifactId>' | grep '<version>' | awk -F '>' '{print $2}' | awk -F '<' '{print $1}')
 
 rm -rf target
+
+bin/process-docs.sh
+mvn process-resources -Djavadoc
+
 mkdir -p target/svn
 ${SVN_CMD} co --depth immediates https://svn.apache.org/repos/asf/incubator/tinkerpop/site/ target/svn
 
@@ -42,9 +46,6 @@ ${SVN_CMD} rm "javadocs/${VERSION}"
 ${SVN_CMD} commit . -m "Docs for TinkerPop ${VERSION} are being replaced."
 popd
 
-bin/process-docs.sh
-mvn process-resources -Djavadoc
-
 mkdir -p "target/svn/docs/${VERSION}"
 mkdir -p "target/svn/javadocs/${VERSION}/core"
 mkdir -p "target/svn/javadocs/${VERSION}/full"

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/docs/src/the-traversal.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/the-traversal.asciidoc b/docs/src/the-traversal.asciidoc
index 17c91b3..007e9bf 100644
--- a/docs/src/the-traversal.asciidoc
+++ b/docs/src/the-traversal.asciidoc
@@ -804,19 +804,21 @@ If a variable is at the start of a traversal pattern it *must* exist as a label
 g.V().as('a').out().as('b'). <1>
     match( <2>
         __.as('a').out().count().as('c'), <3>
-        or( <4>
+        __.not(__.as('a').in().as('b')), <4>
+        or( <5>
           __.as('a').out('knows').as('b'),
-          __.as('b').in().count().as('c').and().as('c').is(gt(2))  <5>
+          __.as('b').in().count().as('c').and().as('c').is(gt(2))  <6>
         )
-    ).select('a','b','c').by('name').by('name').by() <6>
+    ).select('a','b','c').by('name').by('name').by() <7>
 ----
 
 <1> A standard, step-labeled traversal can come prior to `match()`.
 <2> If the traverser's path prior to entering `match()` has the requisite variables, then no "start variable" is needed.
 <3> It is possible to use <<a-note-on-barrier-steps,barrier steps>> though they are computed locally to the pattern (as one would expect).
-<4> It is possible to nest `and()`- and `or()`-steps for conjunction matching.
-<5> Both infix and prefix conjunction notation is supported.
-<6> The bound values are of different types -- vertex ("a"), vertex ("b"), long ("c").
+<4> It is possible to `not()` a pattern.
+<5> It is possible to nest `and()`- and `or()`-steps for conjunction matching.
+<6> Both infix and prefix conjunction notation is supported.
+<7> The bound values are of different types -- vertex ("a"), vertex ("b"), long ("c").
 
 [[using-where-with-match]]
 Using Where with Match

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
index 441884b..4e3416d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -58,7 +58,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.filter.SimplePathStep
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TailGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TimeLimitStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddEdgeStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CoalesceStep;
@@ -660,7 +661,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
     }
 
     public default GraphTraversal<S, E> where(final Scope scope, final String startKey, final P<String> predicate) {
-        return this.asAdmin().addStep(new WhereStep<>(this.asAdmin(), scope, Optional.ofNullable(startKey), predicate));
+        return this.asAdmin().addStep(new WherePredicateStep<>(this.asAdmin(), scope, Optional.ofNullable(startKey), predicate));
     }
 
     public default GraphTraversal<S, E> where(final Scope scope, final P<String> predicate) {
@@ -670,7 +671,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
     public default GraphTraversal<S, E> where(final Scope scope, final Traversal<?, ?> whereTraversal) {
         return TraversalHelper.getVariableLocations(whereTraversal.asAdmin()).isEmpty() ?
                 this.filter(whereTraversal) :
-                this.asAdmin().addStep(new WhereStep(this.asAdmin(), scope, whereTraversal));
+                this.asAdmin().addStep(new WhereTraversalStep<>(this.asAdmin(), scope, whereTraversal));
     }
 
     public default GraphTraversal<S, E> where(final String startKey, final P<String> predicate) {
@@ -752,7 +753,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
     }
 
     public default GraphTraversal<S, E> not(final Traversal<?, ?> notTraversal) {
-        return this.asAdmin().addStep(new NotStep<>(this.asAdmin(), (Traversal<E,?>)notTraversal));
+        return this.asAdmin().addStep(new NotStep<>(this.asAdmin(), (Traversal<E, ?>) notTraversal));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
new file mode 100644
index 0000000..75d654e
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
@@ -0,0 +1,147 @@
+/*
+ *
+ *  * Licensed to the Apache Software Foundation (ASF) under one
+ *  * or more contributor license agreements.  See the NOTICE file
+ *  * distributed with this work for additional information
+ *  * regarding copyright ownership.  The ASF licenses this file
+ *  * to you under the Apache License, Version 2.0 (the
+ *  * "License"); you may not use this file except in compliance
+ *  * with the License.  You may obtain a copy of the License at
+ *  *
+ *  * http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing,
+ *  * software distributed under the License is distributed on an
+ *  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  * KIND, either express or implied.  See the License for the
+ *  * specific language governing permissions and limitations
+ *  * under the License.
+ *
+ */
+
+package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+import org.apache.tinkerpop.gremlin.process.traversal.Scope;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Scoping;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ConjunctionP;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class WherePredicateStep<S> extends FilterStep<S> implements Scoping {
+
+    private static final Set<TraverserRequirement> LOCAL_REQUIREMENTS = EnumSet.of(TraverserRequirement.OBJECT, TraverserRequirement.SIDE_EFFECTS);
+    private static final Set<TraverserRequirement> GLOBAL_REQUIREMENTS = EnumSet.of(TraverserRequirement.PATH, TraverserRequirement.SIDE_EFFECTS);
+
+    protected String startKey;
+    protected List<String> selectKeys;
+    protected P<Object> predicate;
+    protected Scope scope;
+    protected final Set<String> scopeKeys = new HashSet<>();
+
+    public WherePredicateStep(final Traversal.Admin traversal, final Scope scope, final Optional<String> startKey, final P<String> predicate) {
+        super(traversal);
+        this.scope = scope;
+        this.startKey = startKey.orElse(null);
+        if (null != this.startKey)
+            this.scopeKeys.add(this.startKey);
+        this.predicate = (P) predicate;
+        this.selectKeys = new ArrayList<>();
+        this.configurePredicates(this.predicate);
+    }
+
+    private void configurePredicates(final P<Object> predicate) {
+        if (predicate instanceof ConjunctionP)
+            ((ConjunctionP<Object>) predicate).getPredicates().forEach(this::configurePredicates);
+        else {
+            final String selectKey = (String) (predicate.getValue() instanceof Collection ? ((Collection) predicate.getValue()).iterator().next() : predicate.getValue()); // hack for within("x"))
+            this.selectKeys.add(selectKey);
+            this.scopeKeys.add(selectKey);
+        }
+    }
+
+    private void setPredicateValues(final P<Object> predicate, final Traverser.Admin<S> traverser, final Iterator<String> selectKeysIterator) {
+        if (predicate instanceof ConjunctionP)
+            ((ConjunctionP<Object>) predicate).getPredicates().forEach(p -> this.setPredicateValues(p, traverser, selectKeysIterator));
+        else
+            predicate.setValue(this.getScopeValueByKey(Pop.last, selectKeysIterator.next(), traverser));
+    }
+
+    public Optional<P<?>> getPredicate() {
+        return Optional.ofNullable(this.predicate);
+    }
+
+    public Optional<String> getStartKey() {
+        return Optional.ofNullable(this.startKey);
+    }
+
+    public void removeStartKey() {
+        this.selectKeys.remove(this.startKey);
+        this.startKey = null;
+    }
+
+    @Override
+    protected boolean filter(final Traverser.Admin<S> traverser) {
+        this.setPredicateValues(this.predicate, traverser, this.selectKeys.iterator());
+        return this.predicate.test(null == this.startKey ? traverser.get() : this.getScopeValueByKey(Pop.last, this.startKey, traverser));
+    }
+
+    @Override
+    public String toString() {
+        // TODO: revert the predicates to their string form?
+        return StringFactory.stepString(this, this.scope, this.startKey, this.predicate);
+    }
+
+    @Override
+    public Set<String> getScopeKeys() {
+        return Collections.unmodifiableSet(this.scopeKeys);
+    }
+
+    @Override
+    public WherePredicateStep<S> clone() {
+        final WherePredicateStep<S> clone = (WherePredicateStep<S>) super.clone();
+        clone.predicate = this.predicate.clone();
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ this.scope.hashCode() ^ (null == this.startKey ? "null".hashCode() : this.startKey.hashCode()) ^ this.predicate.hashCode();
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Scope.local == this.scope ? LOCAL_REQUIREMENTS : GLOBAL_REQUIREMENTS;
+    }
+
+    @Override
+    public void setScope(final Scope scope) {
+        this.scope = scope;
+    }
+
+    @Override
+    public Scope getScope() {
+        return this.scope;
+    }
+
+    @Override
+    public Scope recommendNextScope() {
+        return this.scope;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/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
deleted file mode 100644
index 659bc2c..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
-
-import org.apache.tinkerpop.gremlin.process.traversal.P;
-import org.apache.tinkerpop.gremlin.process.traversal.Pop;
-import org.apache.tinkerpop.gremlin.process.traversal.Scope;
-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.Scoping;
-import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
-import org.apache.tinkerpop.gremlin.process.traversal.step.map.MapStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.StartStep;
-import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ConjunctionStrategy;
-import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
-import org.apache.tinkerpop.gremlin.process.traversal.util.ConjunctionP;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class WhereStep<S> extends FilterStep<S> implements TraversalParent, Scoping {
-
-    protected String startKey;
-    protected List<String> selectKeys;
-    protected P<Object> predicate;
-    protected Traversal.Admin<?, ?> whereTraversal;
-    protected Scope scope;
-    protected final Set<String> scopeKeys = new HashSet<>();
-
-    public WhereStep(final Traversal.Admin traversal, final Scope scope, final Optional<String> startKey, final P<String> predicate) {
-        super(traversal);
-        this.scope = scope;
-        this.startKey = startKey.orElse(null);
-        if (null != this.startKey)
-            this.scopeKeys.add(this.startKey);
-        this.predicate = (P) predicate;
-        this.selectKeys = new ArrayList<>();
-        this.whereTraversal = null;
-        this.configurePredicates(this.predicate);
-    }
-
-    public WhereStep(final Traversal.Admin traversal, final Scope scope, final Traversal<?, ?> whereTraversal) {
-        super(traversal);
-        this.scope = scope;
-        this.startKey = null;
-        this.predicate = null;
-        this.selectKeys = null;
-        this.whereTraversal = whereTraversal.asAdmin();
-        this.configureStartAndEndSteps(this.whereTraversal);
-        if (this.scopeKeys.isEmpty())
-            throw new IllegalArgumentException("A where()-traversal must have at least a start or end label (i.e. variable): " + whereTraversal);
-        this.whereTraversal = this.integrateChild(this.whereTraversal);
-    }
-
-    private void configureStartAndEndSteps(final Traversal.Admin<?, ?> whereTraversal) {
-        ConjunctionStrategy.instance().apply(whereTraversal);
-        //// START STEP to WhereStartStep
-        final Step<?, ?> startStep = whereTraversal.getStartStep();
-        if (startStep instanceof ConjunctionStep || startStep instanceof NotStep) {       // for conjunction- and not-steps
-            ((TraversalParent) startStep).getLocalChildren().forEach(this::configureStartAndEndSteps);
-        } else if (startStep instanceof StartStep && ((StartStep) startStep).isVariableStartStep()) {  // as("a").out()... traversals
-            final String label = startStep.getLabels().iterator().next();
-            this.scopeKeys.add(label);
-            TraversalHelper.replaceStep(startStep, new WhereStartStep(whereTraversal, label), whereTraversal);
-        } else if (!whereTraversal.getEndStep().getLabels().isEmpty()) {                    // ...out().as("a") traversals
-            TraversalHelper.insertBeforeStep(new WhereStartStep(whereTraversal, null), (Step) startStep, whereTraversal);
-        }
-        //// END STEP to WhereEndStep
-        final Step<?, ?> endStep = whereTraversal.getEndStep();
-        if (!endStep.getLabels().isEmpty()) {
-            if (endStep.getLabels().size() > 1)
-                throw new IllegalArgumentException("The end step of a where()-traversal can only have one label: " + endStep);
-            final String label = endStep.getLabels().iterator().next();
-            this.scopeKeys.add(label);
-            endStep.removeLabel(label);
-            whereTraversal.addStep(new WhereEndStep(whereTraversal, label));
-        }
-    }
-
-    private void configurePredicates(final P<Object> predicate) {
-        if (predicate instanceof ConjunctionP)
-            ((ConjunctionP<Object>) predicate).getPredicates().forEach(this::configurePredicates);
-        else {
-            final String selectKey = (String) (predicate.getValue() instanceof Collection ? ((Collection) predicate.getValue()).iterator().next() : predicate.getValue()); // hack for within("x"))
-            this.selectKeys.add(selectKey);
-            this.scopeKeys.add(selectKey);
-        }
-    }
-
-    private void setPredicateValues(final P<Object> predicate, final Traverser.Admin<S> traverser, final Iterator<String> selectKeysIterator) {
-        if (predicate instanceof ConjunctionP)
-            ((ConjunctionP<Object>) predicate).getPredicates().forEach(p -> this.setPredicateValues(p, traverser, selectKeysIterator));
-        else
-            predicate.setValue(this.getScopeValueByKey(Pop.last, selectKeysIterator.next(), traverser));
-    }
-
-    public Optional<P<?>> getPredicate() {
-        return Optional.ofNullable(this.predicate);
-    }
-
-    public Optional<String> getStartKey() {
-        return Optional.ofNullable(this.startKey);
-    }
-
-    public boolean isPredicateBased() {
-        return this.predicate != null;
-    }
-
-    public boolean isTraversalBased() {
-        return this.whereTraversal != null;
-    }
-
-    public void removeStartKey() {
-        this.selectKeys.remove(this.startKey);
-        this.startKey = null;
-    }
-
-    @Override
-    protected boolean filter(final Traverser.Admin<S> traverser) {
-        if (null != this.whereTraversal)
-            return TraversalUtil.test((Traverser.Admin) traverser, this.whereTraversal);
-        else {
-            this.setPredicateValues(this.predicate, traverser, this.selectKeys.iterator());
-            return this.predicate.test(null == this.startKey ? traverser.get() : this.getScopeValueByKey(Pop.last, this.startKey, traverser));
-        }
-    }
-
-    @Override
-    public List<Traversal.Admin<?, ?>> getLocalChildren() {
-        return null == this.whereTraversal ? Collections.emptyList() : Collections.singletonList(this.whereTraversal);
-    }
-
-    @Override
-    public String toString() {
-        // TODO: revert the predicates to their string form?
-        return StringFactory.stepString(this, this.scope, this.startKey, this.predicate, this.whereTraversal);
-    }
-
-    @Override
-    public Set<String> getScopeKeys() {
-        return Collections.unmodifiableSet(this.scopeKeys);
-    }
-
-    @Override
-    public WhereStep<S> clone() {
-        final WhereStep<S> clone = (WhereStep<S>) super.clone();
-        if (null != this.predicate)
-            clone.predicate = this.predicate.clone();
-        else
-            clone.whereTraversal = clone.integrateChild(this.whereTraversal.clone());
-        return clone;
-    }
-
-    @Override
-    public int hashCode() {
-        return super.hashCode() ^ this.scope.hashCode() ^ (null == this.startKey ? "null".hashCode() : this.startKey.hashCode()) ^ (null == this.predicate ? this.whereTraversal.hashCode() : this.predicate.hashCode());
-    }
-
-    @Override
-    public Set<TraverserRequirement> getRequirements() {
-        return this.getSelfAndChildRequirements(Scope.local == this.scope ?
-                new TraverserRequirement[]{TraverserRequirement.OBJECT, TraverserRequirement.SIDE_EFFECTS} :
-                new TraverserRequirement[]{TraverserRequirement.PATH, TraverserRequirement.SIDE_EFFECTS});
-    }
-
-    @Override
-    public void setScope(final Scope scope) {
-        this.scope = scope;
-    }
-
-    @Override
-    public Scope getScope() {
-        return this.scope;
-    }
-
-    @Override
-    public Scope recommendNextScope() {
-        return this.scope;
-    }
-
-    //////////////////////////////
-
-    public static class WhereStartStep<S> extends MapStep<S, Object> implements Scoping {
-
-        private String selectKey;
-        private Scope scope = Scope.global;
-
-        public WhereStartStep(final Traversal.Admin traversal, final String selectKey) {
-            super(traversal);
-            this.selectKey = selectKey;
-        }
-
-        @Override
-        protected Object map(final Traverser.Admin<S> traverser) {
-            if (this.getTraversal().getEndStep() instanceof WhereEndStep)
-                ((WhereEndStep) this.getTraversal().getEndStep()).processStartTraverser(traverser);
-            return null == this.selectKey ? traverser.get() : this.getScopeValueByKey(Pop.last, this.selectKey, traverser);
-        }
-
-        @Override
-        public String toString() {
-            return StringFactory.stepString(this, this.scope, this.selectKey);
-        }
-
-        @Override
-        public int hashCode() {
-            return super.hashCode() ^ this.scope.hashCode() ^ (null == this.selectKey ? "null".hashCode() : this.selectKey.hashCode());
-        }
-
-        @Override
-        public Scope getScope() {
-            return this.scope;
-        }
-
-        @Override
-        public Scope recommendNextScope() {
-            return this.scope;
-        }
-
-        @Override
-        public void setScope(Scope scope) {
-            this.scope = scope;
-        }
-
-        public void removeScopeKey() {
-            this.selectKey = null;
-        }
-
-        @Override
-        public Set<String> getScopeKeys() {
-            return null == this.selectKey ? Collections.emptySet() : Collections.singleton(this.selectKey);
-        }
-    }
-
-    public static class WhereEndStep extends FilterStep<Object> implements Scoping {
-
-        private final String matchKey;
-        private Object matchValue = null;
-        private Scope scope = Scope.global;
-
-        public WhereEndStep(final Traversal.Admin traversal, final String matchKey) {
-            super(traversal);
-            this.matchKey = matchKey;
-        }
-
-        public void processStartTraverser(final Traverser.Admin traverser) {
-            if (null != this.matchKey)
-                this.matchValue = this.getScopeValueByKey(Pop.last, this.matchKey, traverser);
-        }
-
-        @Override
-        protected boolean filter(final Traverser.Admin<Object> traverser) {
-            return null == this.matchKey || traverser.get().equals(this.matchValue);
-        }
-
-        @Override
-        public String toString() {
-            return StringFactory.stepString(this, this.scope, this.matchKey);
-        }
-
-        @Override
-        public int hashCode() {
-            return super.hashCode() ^ this.scope.hashCode() ^ (null == this.matchKey ? "null".hashCode() : this.matchKey.hashCode());
-        }
-
-        @Override
-        public Scope getScope() {
-            return this.scope;
-        }
-
-        @Override
-        public Scope recommendNextScope() {
-            return this.scope;
-        }
-
-        @Override
-        public void setScope(Scope scope) {
-            // this.scope = scope;
-        }
-
-        @Override
-        public Set<String> getScopeKeys() {
-            return null == this.matchKey ? Collections.emptySet() : Collections.singleton(this.matchKey);
-        }
-    }
-
-
-    //////////////////////////////
-}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java
new file mode 100644
index 0000000..d065610
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java
@@ -0,0 +1,253 @@
+/*
+ *
+ *  * 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.Pop;
+import org.apache.tinkerpop.gremlin.process.traversal.Scope;
+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.Scoping;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.MapStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.StartStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ConjunctionStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class WhereTraversalStep<S> extends FilterStep<S> implements TraversalParent, Scoping {
+
+    private static final Set<TraverserRequirement> LOCAL_REQUIREMENTS = EnumSet.of(TraverserRequirement.OBJECT, TraverserRequirement.SIDE_EFFECTS);
+    private static final Set<TraverserRequirement> GLOBAL_REQUIREMENTS = EnumSet.of(TraverserRequirement.PATH, TraverserRequirement.SIDE_EFFECTS);
+
+    protected Traversal.Admin<?, ?> whereTraversal;
+    protected Scope scope;
+    protected final Set<String> scopeKeys = new HashSet<>();
+
+    public WhereTraversalStep(final Traversal.Admin traversal, final Scope scope, final Traversal<?, ?> whereTraversal) {
+        super(traversal);
+        this.scope = scope;
+        this.whereTraversal = whereTraversal.asAdmin();
+        this.configureStartAndEndSteps(this.whereTraversal);
+        if (this.scopeKeys.isEmpty())
+            throw new IllegalArgumentException("A where()-traversal must have at least a start or end label (i.e. variable): " + whereTraversal);
+        this.whereTraversal = this.integrateChild(this.whereTraversal);
+    }
+
+    private void configureStartAndEndSteps(final Traversal.Admin<?, ?> whereTraversal) {
+        ConjunctionStrategy.instance().apply(whereTraversal);
+        //// START STEP to WhereStartStep
+        final Step<?, ?> startStep = whereTraversal.getStartStep();
+        if (startStep instanceof ConjunctionStep || startStep instanceof NotStep) {       // for conjunction- and not-steps
+            ((TraversalParent) startStep).getLocalChildren().forEach(this::configureStartAndEndSteps);
+        } else if (startStep instanceof StartStep && ((StartStep) startStep).isVariableStartStep()) {  // as("a").out()... traversals
+            final String label = startStep.getLabels().iterator().next();
+            this.scopeKeys.add(label);
+            TraversalHelper.replaceStep(startStep, new WhereStartStep(whereTraversal, label), whereTraversal);
+        } else if (!whereTraversal.getEndStep().getLabels().isEmpty()) {                    // ...out().as("a") traversals
+            TraversalHelper.insertBeforeStep(new WhereStartStep(whereTraversal, null), (Step) startStep, whereTraversal);
+        }
+        //// END STEP to WhereEndStep
+        final Step<?, ?> endStep = whereTraversal.getEndStep();
+        if (!endStep.getLabels().isEmpty()) {
+            if (endStep.getLabels().size() > 1)
+                throw new IllegalArgumentException("The end step of a where()-traversal can only have one label: " + endStep);
+            final String label = endStep.getLabels().iterator().next();
+            this.scopeKeys.add(label);
+            endStep.removeLabel(label);
+            whereTraversal.addStep(new WhereEndStep(whereTraversal, label));
+        }
+    }
+
+
+    @Override
+    protected boolean filter(final Traverser.Admin<S> traverser) {
+        return TraversalUtil.test((Traverser.Admin) traverser, this.whereTraversal);
+    }
+
+    @Override
+    public List<Traversal.Admin<?, ?>> getLocalChildren() {
+        return null == this.whereTraversal ? Collections.emptyList() : Collections.singletonList(this.whereTraversal);
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.stepString(this, this.scope, this.whereTraversal);
+    }
+
+    @Override
+    public Set<String> getScopeKeys() {
+        return Collections.unmodifiableSet(this.scopeKeys);
+    }
+
+    @Override
+    public WhereTraversalStep<S> clone() {
+        final WhereTraversalStep<S> clone = (WhereTraversalStep<S>) super.clone();
+        clone.whereTraversal = clone.integrateChild(this.whereTraversal.clone());
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ this.scope.hashCode() ^ this.whereTraversal.hashCode();
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Scope.local == this.scope ? LOCAL_REQUIREMENTS : GLOBAL_REQUIREMENTS;
+    }
+
+    @Override
+    public void setScope(final Scope scope) {
+        this.scope = scope;
+    }
+
+    @Override
+    public Scope getScope() {
+        return this.scope;
+    }
+
+    @Override
+    public Scope recommendNextScope() {
+        return this.scope;
+    }
+
+    //////////////////////////////
+
+    public static class WhereStartStep<S> extends MapStep<S, Object> implements Scoping {
+
+        private String selectKey;
+        private Scope scope = Scope.global;
+
+        public WhereStartStep(final Traversal.Admin traversal, final String selectKey) {
+            super(traversal);
+            this.selectKey = selectKey;
+        }
+
+        @Override
+        protected Object map(final Traverser.Admin<S> traverser) {
+            if (this.getTraversal().getEndStep() instanceof WhereEndStep)
+                ((WhereEndStep) this.getTraversal().getEndStep()).processStartTraverser(traverser);
+            return null == this.selectKey ? traverser.get() : this.getScopeValueByKey(Pop.last, this.selectKey, traverser);
+        }
+
+        @Override
+        public String toString() {
+            return StringFactory.stepString(this, this.scope, this.selectKey);
+        }
+
+        @Override
+        public int hashCode() {
+            return super.hashCode() ^ this.scope.hashCode() ^ (null == this.selectKey ? "null".hashCode() : this.selectKey.hashCode());
+        }
+
+        @Override
+        public Scope getScope() {
+            return this.scope;
+        }
+
+        @Override
+        public Scope recommendNextScope() {
+            return this.scope;
+        }
+
+        @Override
+        public void setScope(Scope scope) {
+            this.scope = scope;
+        }
+
+        public void removeScopeKey() {
+            this.selectKey = null;
+        }
+
+        @Override
+        public Set<String> getScopeKeys() {
+            return null == this.selectKey ? Collections.emptySet() : Collections.singleton(this.selectKey);
+        }
+    }
+
+    public static class WhereEndStep extends FilterStep<Object> implements Scoping {
+
+        private final String matchKey;
+        private Object matchValue = null;
+        private Scope scope = Scope.global;
+
+        public WhereEndStep(final Traversal.Admin traversal, final String matchKey) {
+            super(traversal);
+            this.matchKey = matchKey;
+        }
+
+        public void processStartTraverser(final Traverser.Admin traverser) {
+            if (null != this.matchKey)
+                this.matchValue = this.getScopeValueByKey(Pop.last, this.matchKey, traverser);
+        }
+
+        @Override
+        protected boolean filter(final Traverser.Admin<Object> traverser) {
+            return null == this.matchKey || traverser.get().equals(this.matchValue);
+        }
+
+        @Override
+        public String toString() {
+            return StringFactory.stepString(this, this.scope, this.matchKey);
+        }
+
+        @Override
+        public int hashCode() {
+            return super.hashCode() ^ this.scope.hashCode() ^ (null == this.matchKey ? "null".hashCode() : this.matchKey.hashCode());
+        }
+
+        @Override
+        public Scope getScope() {
+            return this.scope;
+        }
+
+        @Override
+        public Scope recommendNextScope() {
+            return this.scope;
+        }
+
+        @Override
+        public void setScope(Scope scope) {
+            // this.scope = scope;
+        }
+
+        @Override
+        public Set<String> getScopeKeys() {
+            return null == this.matchKey ? Collections.emptySet() : Collections.singleton(this.matchKey);
+        }
+    }
+
+
+    //////////////////////////////
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
index 2993040..f5b8216 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
@@ -32,7 +32,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.AndStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConjunctionStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.NotStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.IdentityStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.StartStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep;
@@ -91,15 +92,15 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
     }
 
     //////////////////
-    private String pullOutVariableStartStepToParent(final WhereStep<?> whereStep) {
+    private String pullOutVariableStartStepToParent(final WhereTraversalStep<?> whereStep) {
         return this.pullOutVariableStartStepToParent(new HashSet<>(), whereStep.getLocalChildren().get(0), true).size() != 1 ? null : pullOutVariableStartStepToParent(new HashSet<>(), whereStep.getLocalChildren().get(0), false).iterator().next();
     }
 
     private Set<String> pullOutVariableStartStepToParent(final Set<String> selectKeys, final Traversal.Admin<?, ?> traversal, boolean testRun) {
         final Step<?, ?> startStep = traversal.getStartStep();
-        if (startStep instanceof WhereStep.WhereStartStep && !((WhereStep.WhereStartStep) startStep).getScopeKeys().isEmpty()) {
-            selectKeys.addAll(((WhereStep.WhereStartStep<?>) startStep).getScopeKeys());
-            if (!testRun) ((WhereStep.WhereStartStep) startStep).removeScopeKey();
+        if (startStep instanceof WhereTraversalStep.WhereStartStep && !((WhereTraversalStep.WhereStartStep) startStep).getScopeKeys().isEmpty()) {
+            selectKeys.addAll(((WhereTraversalStep.WhereStartStep<?>) startStep).getScopeKeys());
+            if (!testRun) ((WhereTraversalStep.WhereStartStep) startStep).removeScopeKey();
         } else if (startStep instanceof ConjunctionStep || startStep instanceof NotStep) {
             ((TraversalParent) startStep).getLocalChildren().forEach(child -> this.pullOutVariableStartStepToParent(selectKeys, child, testRun));
         }
@@ -121,19 +122,19 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
         } else if (startStep instanceof NotStep) {
             final DefaultTraversal notTraversal = new DefaultTraversal<>();
             TraversalHelper.removeToTraversal(startStep, startStep.getNextStep(), notTraversal);
-            matchTraversal.addStep(0, new WhereStep<>(matchTraversal, Scope.global, notTraversal));
+            matchTraversal.addStep(0, new WhereTraversalStep<>(matchTraversal, Scope.global, notTraversal));
             this.configureStartAndEndSteps(matchTraversal);
         } else if (startStep instanceof StartStep && ((StartStep) startStep).isVariableStartStep()) {
             final String label = startStep.getLabels().iterator().next();
             this.matchStartLabels.add(label);
             TraversalHelper.replaceStep((Step) matchTraversal.getStartStep(), new MatchStartStep(matchTraversal, label), matchTraversal);
-        } else if (startStep instanceof WhereStep) {  // necessary for GraphComputer so the projection is not select'd from a path
-            final WhereStep<?> whereStep = (WhereStep<?>) startStep;
-            if (whereStep.isPredicateBased()) {           // where('a',eq('b')) --> as('a').where(eq('b'))
-                TraversalHelper.insertBeforeStep(new MatchStartStep(matchTraversal, whereStep.getStartKey().orElse(null)), (Step) whereStep, matchTraversal);
-                whereStep.removeStartKey();
-            } else  // where(as('a').out()) -> as('a').where(out())
-                TraversalHelper.insertBeforeStep(new MatchStartStep(matchTraversal, this.pullOutVariableStartStepToParent(whereStep)), (Step) whereStep, matchTraversal);
+        } else if (startStep instanceof WhereTraversalStep) {  // necessary for GraphComputer so the projection is not select'd from a path
+            final WhereTraversalStep<?> whereStep = (WhereTraversalStep<?>) startStep;
+            TraversalHelper.insertBeforeStep(new MatchStartStep(matchTraversal, this.pullOutVariableStartStepToParent(whereStep)), (Step) whereStep, matchTraversal);             // where(as('a').out()) -> as('a').where(out())
+        } else if (startStep instanceof WherePredicateStep) {  // necessary for GraphComputer so the projection is not select'd from a path
+            final WherePredicateStep<?> whereStep = (WherePredicateStep<?>) startStep;
+            TraversalHelper.insertBeforeStep(new MatchStartStep(matchTraversal, whereStep.getStartKey().orElse(null)), (Step) whereStep, matchTraversal);   // where('a',eq('b')) --> as('a').where(eq('b'))
+            whereStep.removeStartKey();
         } else {
             throw new IllegalArgumentException("All match()-traversals must have a single start label (i.e. variable): " + matchTraversal);
         }
@@ -393,7 +394,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
                 if (null != this.selectKey)
                     this.scopeKeys.add(this.selectKey);
                 this.getTraversal().getSteps().forEach(step -> {
-                    if (step instanceof MatchStep || step instanceof WhereStep)
+                    if (step instanceof MatchStep || step instanceof WhereTraversalStep || step instanceof WherePredicateStep)
                         this.scopeKeys.addAll(((Scoping) step).getScopeKeys());
                 });
             }
@@ -525,7 +526,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
                 this.traversalLabels.add(traversal.getStartStep().getId());
                 this.requiredLabels.add(MatchAlgorithm.getRequiredLabels(traversal));
                 this.counts.add(new Integer[]{i, 0});
-                this.whereTraversals.put(traversal, traversal.getStartStep().getNextStep() instanceof WhereStep);
+                this.whereTraversals.put(traversal, traversal.getStartStep().getNextStep() instanceof WhereTraversalStep || traversal.getStartStep().getNextStep() instanceof WherePredicateStep);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java
index efce9b8..e613058 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java
@@ -25,7 +25,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.Scope;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.step.Scoping;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
 

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategy.java
index 109f30c..a8b11c9 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategy.java
@@ -26,7 +26,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConjunctionSte
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.NotStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.VertexStep;
@@ -74,7 +74,7 @@ public final class AdjacentToIncidentStrategy extends AbstractTraversalStrategy<
             final Step curr = steps.get(i);
             if (i == size && isOptimizable(curr)) {
                 final TraversalParent parent = curr.getTraversal().getParent();
-                if (parent instanceof NotStep || parent instanceof TraversalFilterStep || parent instanceof WhereStep || parent instanceof ConjunctionStep) {
+                if (parent instanceof NotStep || parent instanceof TraversalFilterStep || parent instanceof WhereTraversalStep || parent instanceof ConjunctionStep) {
                     optimizeStep(traversal, curr);
                 }
             } else if (isOptimizable(prev)) {

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java
index 3cc9b64..e9beec4 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java
@@ -22,7 +22,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.Step;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.HasStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.MatchStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.SelectOneStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.SelectStep;
@@ -37,7 +38,7 @@ import java.util.stream.Collectors;
 
 /**
  * MatchWhereStrategy will fold any post-<code>where()</code> step that maintains a traversal constraint into <code>match()</code>.
- * {@link MatchStep} is intelligent with traversal constraint applications and thus, can more efficiently use the constraint of {@link WhereStep}.
+ * {@link MatchStep} is intelligent with traversal constraint applications and thus, can more efficiently use the constraint of {@link WhereTraversalStep} or {@link WherePredicateStep}.
  * <p/>
  * <p/>
  *
@@ -66,10 +67,11 @@ public final class MatchPredicateStrategy extends AbstractTraversalStrategy<Trav
 
         TraversalHelper.getStepsOfClass(MatchStep.class, traversal).forEach(matchStep -> {
             Step<?, ?> nextStep = matchStep.getNextStep();
-            while (nextStep instanceof WhereStep ||
+            while (nextStep instanceof WherePredicateStep ||
+                    nextStep instanceof WhereTraversalStep ||
                     (nextStep instanceof SelectStep && ((SelectStep) nextStep).getLocalChildren().isEmpty()) ||
-                    nextStep instanceof SelectOneStep && ((SelectOneStep) nextStep).getLocalChildren().isEmpty()) {   // match().select().where() --> match(where()).select()
-                if (nextStep instanceof WhereStep) {
+                    (nextStep instanceof SelectOneStep && ((SelectOneStep) nextStep).getLocalChildren().isEmpty())) {   // match().select().where() --> match(where()).select()
+                if (nextStep instanceof WherePredicateStep || nextStep instanceof WhereTraversalStep) {
                     traversal.removeStep(nextStep);
                     matchStep.addGlobalChild(new DefaultTraversal<>().addStep(nextStep));
                     nextStep = matchStep.getNextStep();

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
index 7885ab3..0fd0e82 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
@@ -33,7 +33,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.DedupGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TailGlobalStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GraphStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.InjectStep;
@@ -106,9 +107,8 @@ public final class ComputerVerificationStrategy extends AbstractTraversalStrateg
                     throw new ComputerVerificationException("Local traversals on GraphComputer may not traverse past the local star-graph: " + traversalOptional.get(), traversal);
             }
 
-            if (step instanceof WhereStep &&
-                    ((((WhereStep) step).isPredicateBased() && ((WhereStep) step).getStartKey().isPresent()) ||
-                            (((WhereStep) step).isTraversalBased() && TraversalHelper.getVariableLocations(((WhereStep<?>) step).getLocalChildren().get(0)).contains(Scoping.Variable.START))))
+            if ((step instanceof WherePredicateStep && ((WherePredicateStep) step).getStartKey().isPresent()) ||
+                    (step instanceof WhereTraversalStep && TraversalHelper.getVariableLocations(((WhereTraversalStep<?>) step).getLocalChildren().get(0)).contains(Scoping.Variable.START)))
                 throw new ComputerVerificationException("A where()-step that has a start variable is not allowed because the variable value is retrieved from the path: " + step, traversal);
 
             if (UNSUPPORTED_STEPS.stream().filter(c -> c.isAssignableFrom(step.getClass())).findFirst().isPresent())

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
index 7a1b5f0..7325b91 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
@@ -26,7 +26,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.RepeatStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConjunctionStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.NotStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeVertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.MatchStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesStep;
@@ -341,8 +342,11 @@ public final class TraversalHelper {
         final Step<?, ?> startStep = traversal.getStartStep();
         if (startStep instanceof StartStep && ((StartStep) startStep).isVariableStartStep())
             variables.add(Scoping.Variable.START);
-        else if (startStep instanceof WhereStep.WhereStartStep) {
-            if (!((WhereStep.WhereStartStep) startStep).getScopeKeys().isEmpty())
+        else if (startStep instanceof WherePredicateStep) {
+            if (((WherePredicateStep) startStep).getStartKey().isPresent())
+                variables.add(Scoping.Variable.START);
+        } else if (startStep instanceof WhereTraversalStep.WhereStartStep) {
+            if (!((WhereTraversalStep.WhereStartStep) startStep).getScopeKeys().isEmpty())
                 variables.add(Scoping.Variable.START);
         } else if (startStep instanceof MatchStep.MatchStartStep) {
             if (((MatchStep.MatchStartStep) startStep).getSelectKey().isPresent())
@@ -352,12 +356,15 @@ public final class TraversalHelper {
                 variables.add(Scoping.Variable.START);
             else
                 ((MatchStep<?, ?>) startStep).getGlobalChildren().forEach(child -> TraversalHelper.getVariableLocations(variables, child));
-        } else if (startStep instanceof ConjunctionStep || startStep instanceof NotStep || startStep instanceof WhereStep)
+        } else if (startStep instanceof ConjunctionStep || startStep instanceof NotStep || startStep instanceof WhereTraversalStep)
             ((TraversalParent) startStep).getLocalChildren().forEach(child -> TraversalHelper.getVariableLocations(variables, child));
         ///
         final Step<?, ?> endStep = traversal.getEndStep();
-        if (endStep instanceof WhereStep.WhereEndStep) {
-            if (!((WhereStep.WhereEndStep) endStep).getScopeKeys().isEmpty())
+        if (endStep instanceof WherePredicateStep) {
+            if (((WherePredicateStep) endStep).getStartKey().isPresent())
+                variables.add(Scoping.Variable.END);
+        } else if (endStep instanceof WhereTraversalStep.WhereEndStep) {
+            if (!((WhereTraversalStep.WhereEndStep) endStep).getScopeKeys().isEmpty())
                 variables.add(Scoping.Variable.END);
         } else if (endStep instanceof MatchStep.MatchEndStep) {
             if (((MatchStep.MatchEndStep) endStep).getMatchKey().isPresent())

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStepTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStepTest.java
index 8c34250..b044631 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStepTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStepTest.java
@@ -21,11 +21,9 @@
 
 package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
 
+import org.apache.tinkerpop.gremlin.process.traversal.P;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
-import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
 import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
-import org.apache.tinkerpop.gremlin.structure.Graph;
-import org.junit.Test;
 
 import java.util.Arrays;
 import java.util.List;
@@ -38,26 +36,13 @@ import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.as;
  */
 public class WhereStepTest extends StepTest {
 
-    @Test
-    public void shouldHaveProperPredicate() {
-        Traversal<?, ?> traversal = as("a").out().as("b").where(as("a").out());
-        WhereStep<?> whereStep = (WhereStep) traversal.asAdmin().getEndStep();
-        //assertEquals(TraversalP.class, whereStep.predicate.getClass());
-
-        traversal = as("a", "b").out().as("b", "c").where(as("a").out().as("b").and().as("c").out().as("d"));
-        traversal.asAdmin().setStrategies(TraversalStrategies.GlobalCache.getStrategies(Graph.class));
-        traversal.iterate();
-        whereStep = (WhereStep) traversal.asAdmin().getEndStep();
-        //System.out.println(traversal);
-        //System.out.println(whereStep.predicate);
-        // TODO: do something here
-    }
-
     @Override
     public List<Traversal> getTraversals() {
         return Arrays.asList(
                 as("a").out().as("b").where(as("a").out()),
-                as("a").out().as("b").where(as("a").out().as("b"))
+                as("a").out().as("b").where(as("a").out().as("b")),
+                as("a").out().as("b").where("a", P.neq("b")),
+                as("a").out().as("b").where("a", P.neq("c"))
         );
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
index 1e97462..fa06a74 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
@@ -27,11 +27,14 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.CoinStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConjunctionStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.NoOpBarrierStep;
 import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.EmptyTraverser;
 import org.junit.Test;
 
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.*;
@@ -57,9 +60,9 @@ public class MatchStepTest extends StepTest {
     }
 
     @Test
-    public void shouldDoPreCompilationCorrectly() {
-        Traversal.Admin<?, ?> traversal = __.match("a", as("a").out().as("b"), as("c").path().as("d")).asAdmin();
-        MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
+    public void testPreCompilationOfStartAndEnds() {
+        final Traversal.Admin<?, ?> traversal = __.match("a", as("a").out().as("b"), as("c").path().as("d")).asAdmin();
+        final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
         assertEquals(MatchStep.class, traversal.getStartStep().getClass());
         assertEquals("a", matchStep.getStartKey().get());
         assertEquals(2, matchStep.getGlobalChildren().size());
@@ -72,48 +75,116 @@ public class MatchStepTest extends StepTest {
         assertEquals("c", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
         assertEquals(PathStep.class, pattern.getStartStep().getNextStep().getClass());
         assertEquals("d", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
+    }
 
-        ///////////////////
+    @Test
+    public void testPreCompilationOfOr() {
+        final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
+                __.match("a", as("a").out().as("b"), or(as("c").path().as("d"), as("e").coin(0.5).as("f"))).asAdmin(),
+                __.match("a", as("a").out().as("b"), as("c").path().as("d").or().as("e").coin(0.5).as("f")).asAdmin());
+        assertEquals(1, new HashSet<>(traversals).size()); // the two patterns should pre-compile to the same traversal
+        traversals.forEach(traversal -> {
+            final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
+            assertEquals("a", matchStep.getStartKey().get());
+            assertEquals(2, matchStep.getGlobalChildren().size());
+            Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
+            assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
+            assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
+            assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
+            //
+            pattern = matchStep.getGlobalChildren().get(1);
+            assertEquals(MatchStep.class, pattern.getStartStep().getClass());
+            assertEquals(ConjunctionStep.Conjunction.OR, ((MatchStep<?, ?>) pattern.getStartStep()).getConjunction());
+            assertEquals("c", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep()).getSelectKey().get());
+            assertEquals(PathStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep().getNextStep().getClass());
+            assertEquals("d", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getEndStep()).getMatchKey().get());
+            assertEquals("e", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep()).getSelectKey().get());
+            assertEquals(CoinStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep().getNextStep().getClass());
+            assertEquals("f", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getEndStep()).getMatchKey().get());
+        });
+    }
 
-        traversal = __.match("a", as("a").out().as("b"), or(as("c").path().as("d"), as("e").coin(0.5).as("f"))).asAdmin();
-        matchStep = (MatchStep<?, ?>) traversal.getStartStep();
-        assertEquals("a", matchStep.getStartKey().get());
-        assertEquals(2, matchStep.getGlobalChildren().size());
-        pattern = matchStep.getGlobalChildren().get(0);
-        assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
-        assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
-        assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
-        //
-        pattern = matchStep.getGlobalChildren().get(1);
-        assertTrue(pattern.getStartStep() instanceof MatchStep);
-        assertEquals(ConjunctionStep.Conjunction.OR, ((MatchStep<?, ?>) pattern.getStartStep()).getConjunction());
-        assertEquals("c", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep()).getSelectKey().get());
-        assertEquals(PathStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep().getNextStep().getClass());
-        assertEquals("d", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getEndStep()).getMatchKey().get());
-        assertEquals("e", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep()).getSelectKey().get());
-        assertEquals(CoinStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep().getNextStep().getClass());
-        assertEquals("f", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getEndStep()).getMatchKey().get());
+    @Test
+    public void testPreCompilationOfAnd() {
+        final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
+                __.match("a", as("a").out().as("b"), and(as("c").path().as("d"), as("e").barrier())).asAdmin(),
+                __.match("a", as("a").out().as("b"), as("c").path().as("d").and().as("e").barrier()).asAdmin());
+        assertEquals(1, new HashSet<>(traversals).size());   // the two patterns should pre-compile to the same traversal
+        traversals.forEach(traversal -> {
+            MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
+            assertEquals("a", matchStep.getStartKey().get());
+            assertEquals(2, matchStep.getGlobalChildren().size());
+            Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
+            assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
+            assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
+            assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
+            //
+            pattern = matchStep.getGlobalChildren().get(1);
+            assertEquals(MatchStep.class, pattern.getStartStep().getClass());
+            assertEquals(ConjunctionStep.Conjunction.AND, ((MatchStep<?, ?>) pattern.getStartStep()).getConjunction());
+            assertEquals("c", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep()).getSelectKey().get());
+            assertEquals(PathStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep().getNextStep().getClass());
+            assertEquals("d", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getEndStep()).getMatchKey().get());
+            assertEquals("e", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep()).getSelectKey().get());
+            assertEquals(NoOpBarrierStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep().getNextStep().getClass());
+            assertFalse(((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getEndStep()).getMatchKey().isPresent());
+        });
+    }
 
-        ///////////////////
+    @Test
+    public void testPreCompilationOfWhereTraversal() {
+        final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
+                __.match(as("a").out().as("b"), as("c").where(in().as("d"))).asAdmin(),
+                __.match(as("a").out().as("b"), where(as("c").in().as("d"))).asAdmin());
+        assertEquals(1, new HashSet<>(traversals).size()); // the two patterns should pre-compile to the same traversal
+        traversals.forEach(traversal -> {
+            MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
+            assertFalse(matchStep.getStartKey().isPresent());
+            assertEquals(2, matchStep.getGlobalChildren().size());
+            Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
+            assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
+            assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
+            assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
+            //
+            pattern = matchStep.getGlobalChildren().get(1);
+            assertEquals(MatchStep.MatchStartStep.class, pattern.getStartStep().getClass());
+            assertEquals("c", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
+            assertEquals(WhereTraversalStep.class, pattern.getStartStep().getNextStep().getClass());
+            assertEquals(MatchStep.MatchEndStep.class, pattern.getStartStep().getNextStep().getNextStep().getClass());
+            assertEquals(1, ((WhereTraversalStep<?>) pattern.getStartStep().getNextStep()).getLocalChildren().size());
+            Traversal.Admin<?, ?> whereTraversal = ((WhereTraversalStep<?>) pattern.getStartStep().getNextStep()).getLocalChildren().get(0);
+            assertEquals(WhereTraversalStep.WhereStartStep.class, whereTraversal.getStartStep().getClass());
+            assertTrue(((WhereTraversalStep.WhereStartStep) whereTraversal.getStartStep()).getScopeKeys().isEmpty());
+            assertEquals(VertexStep.class, whereTraversal.getStartStep().getNextStep().getClass());
+            assertEquals(WhereTraversalStep.WhereEndStep.class, whereTraversal.getStartStep().getNextStep().getNextStep().getClass());
+            assertEquals(1, ((WhereTraversalStep.WhereEndStep) whereTraversal.getStartStep().getNextStep().getNextStep()).getScopeKeys().size());
+            assertEquals("d", ((WhereTraversalStep.WhereEndStep) whereTraversal.getStartStep().getNextStep().getNextStep()).getScopeKeys().iterator().next());
+        });
+    }
 
-        traversal = __.match("a", as("a").out().as("b"), as("c").path().as("d").and().as("e").barrier()).asAdmin();
-        matchStep = (MatchStep<?, ?>) traversal.getStartStep();
-        assertEquals("a", matchStep.getStartKey().get());
-        assertEquals(2, matchStep.getGlobalChildren().size());
-        pattern = matchStep.getGlobalChildren().get(0);
-        assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
-        assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
-        assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
-        //
-        pattern = matchStep.getGlobalChildren().get(1);
-        assertTrue(pattern.getStartStep() instanceof MatchStep);
-        assertEquals(ConjunctionStep.Conjunction.AND, ((MatchStep<?, ?>) pattern.getStartStep()).getConjunction());
-        assertEquals("c", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep()).getSelectKey().get());
-        assertEquals(PathStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep().getNextStep().getClass());
-        assertEquals("d", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getEndStep()).getMatchKey().get());
-        assertEquals("e", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep()).getSelectKey().get());
-        assertEquals(NoOpBarrierStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep().getNextStep().getClass());
-        assertFalse(((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getEndStep()).getMatchKey().isPresent());
+    @Test
+    public void testPreCompilationOfWherePredicate() {
+        final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
+                __.match(as("a").out().as("b"), as("c").where(P.neq("d"))).asAdmin(),
+                __.match(as("a").out().as("b"), where("c", P.neq("d"))).asAdmin());
+        assertEquals(1, new HashSet<>(traversals).size()); // the two patterns should pre-compile to the same traversal
+        traversals.forEach(traversal -> {
+            MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
+            assertFalse(matchStep.getStartKey().isPresent());
+            assertEquals(2, matchStep.getGlobalChildren().size());
+            Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
+            assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
+            assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
+            assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
+            //
+            pattern = matchStep.getGlobalChildren().get(1);
+            assertEquals(MatchStep.MatchStartStep.class, pattern.getStartStep().getClass());
+            assertEquals("c", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
+            assertEquals(WherePredicateStep.class, pattern.getStartStep().getNextStep().getClass());
+            assertEquals(MatchStep.MatchEndStep.class, pattern.getStartStep().getNextStep().getNextStep().getClass());
+            assertFalse(((WherePredicateStep<?>) pattern.getStartStep().getNextStep()).getStartKey().isPresent());
+            assertEquals("d", ((WherePredicateStep<?>) pattern.getStartStep().getNextStep()).getPredicate().get().getOriginalValue());
+        });
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTraverseTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTraverseTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTraverseTest.java
index a64ad77..8c668c8 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTraverseTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTraverseTest.java
@@ -22,7 +22,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GraphStep;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
 import org.apache.tinkerpop.gremlin.structure.Direction;

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/d299f949/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RangeByIsCountStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RangeByIsCountStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RangeByIsCountStrategyTest.java
index 4bc3866..1642b41 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RangeByIsCountStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RangeByIsCountStrategyTest.java
@@ -24,7 +24,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereStep;
 import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
 import org.junit.Before;