@Test
 public void testPreCompilationOfStartAndEnds() {
   final Traversal.Admin<?, ?> traversal =
       __.match(as("a").out().as("b"), as("c").path().as("d")).asAdmin();
   final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
   assertEquals(MatchStep.class, traversal.getStartStep().getClass());
   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("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 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.getStartLabel().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());
       });
 }
 private static Set<Scoping.Variable> getVariableLocations(
     final Set<Scoping.Variable> variables, final Traversal.Admin<?, ?> traversal) {
   if (variables.size() == 2)
     return variables; // has both START and END so no need to compute further
   final Step<?, ?> startStep = traversal.getStartStep();
   if (StartStep.isVariableStartStep(startStep)) variables.add(Scoping.Variable.START);
   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())
       variables.add(Scoping.Variable.START);
   } else if (startStep instanceof MatchStep) {
     ((MatchStep<?, ?>) startStep)
         .getGlobalChildren()
         .forEach(child -> TraversalHelper.getVariableLocations(variables, child));
   } else if (startStep instanceof ConnectiveStep
       || startStep instanceof NotStep
       || startStep instanceof WhereTraversalStep)
     ((TraversalParent) startStep)
         .getLocalChildren()
         .forEach(child -> TraversalHelper.getVariableLocations(variables, child));
   ///
   final Step<?, ?> endStep = traversal.getEndStep();
   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())
       variables.add(Scoping.Variable.END);
   } else if (!endStep.getLabels().isEmpty()) variables.add(Scoping.Variable.END);
   ///
   return variables;
 }
 @Test
 public void testPreCompilationOfOr() {
   final List<Traversal.Admin<?, ?>> traversals =
       Arrays.asList(
           __.match(as("a").out().as("b"), or(as("c").path().as("d"), as("e").coin(0.5).as("f")))
               .asAdmin(),
           __.match(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(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(
             ConnectiveStep.Connective.OR,
             ((MatchStep<?, ?>) pattern.getStartStep()).getConnective());
         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());
       });
 }