This is an automated email from the ASF dual-hosted git repository.

colegreer pushed a commit to branch 3.7-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/3.7-dev by this push:
     new 3a48401d83 getScopingInfo utility added (#3118)
3a48401d83 is described below

commit 3a48401d83656a31c459f541550b62be67084970
Author: Vaibhav Malhotra <[email protected]>
AuthorDate: Thu Jun 12 18:52:14 2025 -0700

    getScopingInfo utility added (#3118)
    
    Added PopContaining interface, and its implementation in Scoping.java
    and TraversalParent.java, and classes that use these interfaces.
    
    Co-authored-by: Vaibhav Malhotra <[email protected]>
---
 CHANGELOG.asciidoc                                 |   1 +
 .../process/traversal/step/PopContaining.java      | 103 +++++++++++++++++++++
 .../gremlin/process/traversal/step/Scoping.java    |  20 +++-
 .../process/traversal/step/TraversalParent.java    |  16 +++-
 .../traversal/step/filter/DedupGlobalStep.java     |   8 ++
 .../traversal/step/filter/WherePredicateStep.java  |   8 ++
 .../traversal/step/filter/WhereTraversalStep.java  |   8 ++
 .../traversal/step/map/AddEdgeStartStep.java       |   8 ++
 .../process/traversal/step/map/AddEdgeStep.java    |   8 ++
 .../traversal/step/map/AddVertexStartStep.java     |   8 ++
 .../process/traversal/step/map/AddVertexStep.java  |   8 ++
 .../process/traversal/step/map/FormatStep.java     |   9 ++
 .../process/traversal/step/map/MatchStep.java      |   8 ++
 .../process/traversal/step/map/MathStep.java       |   8 ++
 .../process/traversal/step/map/SelectOneStep.java  |  12 +++
 .../process/traversal/step/map/SelectStep.java     |  13 ++-
 .../traversal/step/map/TraversalSelectStep.java    |  12 +++
 .../traversal/step/sideEffect/AddPropertyStep.java |   9 ++
 .../process/traversal/util/TraversalHelper.java    |  20 +++-
 .../apache/tinkerpop/gremlin/TestDataBuilder.java  |  48 ++++++++++
 .../traversal/step/filter/DedupGlobalStepTest.java |  19 ++++
 .../traversal/step/filter/WhereStepTest.java       |  33 ++++++-
 .../traversal/step/map/AddEdgeStepTest.java        |  30 ++++++
 .../traversal/step/map/AddVertexStepTest.java      |  27 ++++++
 .../process/traversal/step/map/FormatStepTest.java |  17 ++++
 .../process/traversal/step/map/MatchStepTest.java  |  19 ++++
 .../process/traversal/step/map/MathStepTest.java   |  21 +++++
 .../traversal/step/map/SelectOneStepTest.java      |  48 ++++++++++
 .../process/traversal/step/map/SelectStepTest.java |  50 ++++++++++
 .../step/map/TraversalSelectStepTest.java          |  56 +++++++++++
 .../step/sideEffect/AddPropertyStepTest.java       |  10 ++
 .../traversal/util/TraversalHelperTest.java        |  93 +++++++++++++++++++
 32 files changed, 753 insertions(+), 5 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 97f29200ff..b3d893c178 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -46,6 +46,7 @@ 
image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 * Fixed bug in `IndexStep` which prevented Java serialization due to 
non-serializable lambda usage by creating serializable function classes.
 * Fixed bug in `Operator` which was caused only a single method parameter to 
be Collection type checked instead of all parameters.
 * Support hot reloading of SSL certificates.
+* Added the `PopContaining` interface designed to get label and `Pop` 
combinations held in a `PopInstruction` object.
 
 [[release-3-7-3]]
 === TinkerPop 3.7.3 (October 23, 2024)
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/PopContaining.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/PopContaining.java
new file mode 100644
index 0000000000..89fdf28e58
--- /dev/null
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/PopContaining.java
@@ -0,0 +1,103 @@
+/*
+ *  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;
+
+import java.util.Objects;
+import java.util.Set;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+
+/**
+ * The {@code PopContaining} interface is implemented by traversal steps that 
maintain Pop instructions
+ * for label access. It provides a mechanism to track and manage how labeled 
elements should
+ * be accessed using {@link Pop} semantics (first, last, all, or mixed).
+ *
+ * In Gremlin traversals, various elements can be labeled and later accessed 
via these labels.
+ * The {@link Pop} enum determines how to access these labeled elements when 
there are multiple
+ * values associated with the same label.
+ *
+ * <pre>
+ * {@code
+ * // Simple example with default Pop.last behavior
+ * gremlin> g.V().as("a").out().as("a").select("a")
+ * ==>[v[2]]  // returns the last element labeled "a"
+ *
+ * // Using Pop.first to get the first labeled element
+ * gremlin> g.V().as("a").out().as("a").select(first, "a")
+ * ==>[v[1]]  // returns the first element labeled "a"
+ *
+ * // Using Pop.all to get all labeled elements
+ * gremlin> g.V().as("a").out().as("a").select(all, "a")
+ * ==>[v[1], v[2]]  // returns all elements labeled "a"
+ * }
+ * </pre>
+ *
+ * Steps implementing this interface maintain a collection of {@link 
PopInstruction} objects, each containing
+ * a label and a {@link Pop} value that specifies how to access elements with 
that label.
+ *
+ */
+public interface PopContaining {
+    public Set<PopInstruction> getPopInstructions();
+    /**
+     * A class for storing the Scope Context. It has two elements:
+     * - label: String
+     * - pop: Pop value
+     */
+    class PopInstruction {
+        private final Pop pop;
+        private final String label;
+
+        public PopInstruction(String label, Pop pop) {
+            this.pop = pop;
+            this.label = label;
+        }
+
+        public PopInstruction(final Pop pop, final String label) {
+            this.pop = pop;
+            this.label = label;
+        }
+
+        public PopInstruction() {
+           this.pop = null;
+           this.label = "";
+        }
+
+    public String getLabel() {
+            return label;
+        }
+
+        public Pop getPop() {
+            return pop;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+            final PopInstruction that = (PopInstruction) o;
+            return getPop() == that.getPop() && Objects.equals(getLabel(), 
that.getLabel());
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(getPop(), getLabel());
+        }
+    }
+}
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java
index e2c0e17747..a765e77875 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java
@@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Pop;
 import org.apache.tinkerpop.gremlin.process.traversal.Step;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -105,7 +106,7 @@ import java.util.Set;
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
-public interface Scoping {
+public interface Scoping extends PopContaining {
 
     public enum Variable {START, END}
 
@@ -166,6 +167,23 @@ public interface Scoping {
      */
     public Set<String> getScopeKeys();
 
+    /**
+     * Used to get PopInstruction of a Step that implements Scoping. 
PopInstruction includes the labels it needs, and the
+     * pop type for each label.
+     *
+     * @return A Set of {@link PopInstruction} values which contain the label 
and Pop value
+     */
+    @Override
+    public default HashSet<PopInstruction> getPopInstructions() {
+        final Set<String> labels = this.getScopeKeys();
+        final HashSet<PopInstruction> scopingInfoSet = new HashSet<>();
+        for (final String label : labels) {
+            final PopInstruction scopingInfo = new PopInstruction(Pop.last, 
label);
+            scopingInfoSet.add(scopingInfo);
+        }
+        return scopingInfoSet;
+    }
+
     public static class KeyNotFoundException extends Exception {
 
         private final Object key;
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/TraversalParent.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/TraversalParent.java
index 695d2972fc..3a43f7b74c 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/TraversalParent.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/TraversalParent.java
@@ -21,16 +21,18 @@ package org.apache.tinkerpop.gremlin.process.traversal.step;
 import org.apache.tinkerpop.gremlin.process.traversal.Step;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
 
 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 interface TraversalParent extends AutoCloseable {
+public interface TraversalParent extends PopContaining, AutoCloseable {
 
     public default <S, E> List<Traversal.Admin<S, E>> getGlobalChildren() {
         return Collections.emptyList();
@@ -95,4 +97,16 @@ public interface TraversalParent extends AutoCloseable {
             traversal.close();
         }
     }
+
+    @Override
+    public default HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> scopingInfos = new HashSet<>();
+        for (final Traversal.Admin local: this.getLocalChildren()) {
+            scopingInfos.addAll(TraversalHelper.getPopInstructions(local));
+        }
+        for (final Traversal.Admin global: this.getGlobalChildren()) {
+            scopingInfos.addAll(TraversalHelper.getPopInstructions(global));
+        }
+        return scopingInfos;
+    }
 }
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java
index 9f5b0e5f5c..ed81ecf6bd 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java
@@ -186,6 +186,14 @@ public final class DedupGlobalStep<S> extends 
FilterStep<S> implements Traversal
         return null == this.dedupLabels ? Collections.emptySet() : 
this.dedupLabels;
     }
 
+    @Override
+    public HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> popInstructions = new HashSet<>();
+        popInstructions.addAll(Scoping.super.getPopInstructions());
+        popInstructions.addAll(TraversalParent.super.getPopInstructions());
+        return popInstructions;
+    }
+
     @Override
     public void processAllStarts() {
 
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
index cffe3ebc8c..69b054446a 100644
--- 
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
@@ -132,6 +132,14 @@ public final class WherePredicateStep<S> extends 
FilterStep<S> implements Scopin
         return Collections.unmodifiableSet(this.scopeKeys);
     }
 
+    @Override
+    public HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> popInstructions = new HashSet<>();
+        popInstructions.addAll(Scoping.super.getPopInstructions());
+        popInstructions.addAll(TraversalParent.super.getPopInstructions());
+        return popInstructions;
+    }
+
     @Override
     public WherePredicateStep<S> clone() {
         final WherePredicateStep<S> clone = (WherePredicateStep<S>) 
super.clone();
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
index dde900348a..1fa30b98b9 100644
--- 
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
@@ -147,6 +147,14 @@ public final class WhereTraversalStep<S> extends 
FilterStep<S> implements Traver
         return this.keepLabels;
     }
 
+    @Override
+    public HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> popInstructions = new HashSet<>();
+        popInstructions.addAll(Scoping.super.getPopInstructions());
+        popInstructions.addAll(TraversalParent.super.getPopInstructions());
+        return popInstructions;
+    }
+
     //////////////////////////////
 
     public static class WhereStartStep<S> extends ScalarMapStep<S, Object> 
implements Scoping {
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java
index 95907e9c7a..e661c67755 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java
@@ -42,6 +42,7 @@ import org.apache.tinkerpop.gremlin.structure.util.Attachable;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
 
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -83,6 +84,13 @@ public class AddEdgeStartStep extends AbstractStep<Edge, 
Edge>
         return this.parameters.getReferencedLabels();
     }
 
+    @Override
+    public HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> popInstructions = new HashSet<>();
+        popInstructions.addAll(TraversalParent.super.getPopInstructions());
+        return popInstructions;
+    }
+
     @Override
     public void configure(final Object... keyValues) {
         this.parameters.set(this, keyValues);
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
index f5f7280764..c0c5c8a1fe 100644
--- 
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
@@ -38,6 +38,7 @@ import org.apache.tinkerpop.gremlin.structure.util.Attachable;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
 
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -79,6 +80,13 @@ public class AddEdgeStep<S> extends ScalarMapStep<S, Edge>
         return this.parameters.getReferencedLabels();
     }
 
+    @Override
+    public HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> popInstructions = new HashSet<>();
+        popInstructions.addAll(TraversalParent.super.getPopInstructions());
+        return popInstructions;
+    }
+
     @Override
     public void configure(final Object... keyValues) {
         this.parameters.set(this, keyValues);
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
index fd52f445e8..95d0ab8e30 100644
--- 
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
@@ -37,6 +37,7 @@ import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -78,6 +79,13 @@ public class AddVertexStartStep extends AbstractStep<Vertex, 
Vertex>
         return this.parameters.getReferencedLabels();
     }
 
+    @Override
+    public HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> popInstructions = new HashSet<>();
+        popInstructions.addAll(TraversalParent.super.getPopInstructions());
+        return popInstructions;
+    }
+
     @Override
     public <S, E> List<Traversal.Admin<S, E>> getLocalChildren() {
         return this.parameters.getTraversals();
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
index 0dfb55c2a1..d7de87edfb 100644
--- 
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
@@ -33,6 +33,7 @@ import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -73,6 +74,13 @@ public class AddVertexStep<S> extends ScalarMapStep<S, 
Vertex>
         return this.parameters.getReferencedLabels();
     }
 
+    @Override
+    public HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> popInstructions = new HashSet<>();
+        popInstructions.addAll(TraversalParent.super.getPopInstructions());
+        return popInstructions;
+    }
+
     @Override
     public <S, E> List<Traversal.Admin<S, E>> getLocalChildren() {
         return this.parameters.getTraversals();
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStep.java
index c4b50958d9..39d7d00586 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStep.java
@@ -34,6 +34,7 @@ import org.apache.tinkerpop.gremlin.structure.Element;
 import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 
+import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Objects;
@@ -168,6 +169,14 @@ public final class FormatStep<S> extends MapStep<S, 
String> implements ByModulat
         return variables;
     }
 
+    @Override
+    public HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> popInstructions = new HashSet<>();
+        popInstructions.addAll(Scoping.super.getPopInstructions());
+        popInstructions.addAll(TraversalParent.super.getPopInstructions());
+        return popInstructions;
+    }
+
     @Override
     public void setKeepLabels(final Set<String> labels) {
         this.keepLabels = labels;
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 6de3970236..055f302996 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
@@ -218,6 +218,14 @@ public final class MatchStep<S, E> extends 
ComputerAwareStep<S, Map<String, E>>
         return this.scopeKeys;
     }
 
+    @Override
+    public HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> popInstructions = new HashSet<>();
+        popInstructions.addAll(Scoping.super.getPopInstructions());
+        popInstructions.addAll(TraversalParent.super.getPopInstructions());
+        return popInstructions;
+    }
+
     @Override
     public String toString() {
         return StringFactory.stepString(this, this.dedupLabels, 
this.connective, this.matchTraversals);
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStep.java
index e36a1311c8..2533070542 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStep.java
@@ -165,6 +165,14 @@ public final class MathStep<S> extends MapStep<S, Double> 
implements ByModulatin
             return this.expression.getVariables();
     }
 
+    @Override
+    public HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> popInstructions = new HashSet<>();
+        popInstructions.addAll(Scoping.super.getPopInstructions());
+        popInstructions.addAll(TraversalParent.super.getPopInstructions());
+        return popInstructions;
+    }
+
     @Override
     public void setKeepLabels(final Set<String> labels) {
         this.keepLabels = labels;
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStep.java
index b2de4b002c..dd6661eb77 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStep.java
@@ -134,6 +134,18 @@ public final class SelectOneStep<S, E> extends MapStep<S, 
E> implements Traversa
         return Collections.singleton(this.selectKey);
     }
 
+    @Override
+    public HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> popInstructions = new HashSet<>();
+        final Set<String> labels = this.getScopeKeys();
+        for (String label : labels) {
+            final PopInstruction scopingInfo = new 
PopInstruction(this.getPop(), label);
+            popInstructions.add(scopingInfo);
+        }
+        popInstructions.addAll(TraversalParent.super.getPopInstructions());
+        return popInstructions;
+    }
+
     public Pop getPop() {
         return this.pop;
     }
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java
index 24c9771ed2..d47c903739 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java
@@ -34,7 +34,6 @@ import 
org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -149,6 +148,18 @@ public final class SelectStep<S, E> extends MapStep<S, 
Map<String, E>> implement
         return this.selectKeysSet;
     }
 
+    @Override
+    public HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> popInstructions = new HashSet<>();
+        final Set<String> labels = this.getScopeKeys();
+        for (final String label : labels) {
+            final PopInstruction scopingInfo = new 
PopInstruction(this.getPop(), label);
+            popInstructions.add(scopingInfo);
+        }
+        popInstructions.addAll(TraversalParent.super.getPopInstructions());
+        return popInstructions;
+    }
+
     /**
      * Get the keys for this SelectStep. Unlike {@link 
SelectStep#getScopeKeys()}, this returns a list possibly with
      * a duplicate key. This guarantees to return the keys in the same order 
as passed in.
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalSelectStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalSelectStep.java
index ff9f0996f5..0eea87f36c 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalSelectStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalSelectStep.java
@@ -85,6 +85,18 @@ public final class TraversalSelectStep<S, E> extends 
MapStep<S, E> implements Tr
         return Collections.emptySet();
     }
 
+    @Override
+    public HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> popInstructions = new HashSet<>();
+        final Set<String> labels = this.getScopeKeys();
+        for (String label : labels) {
+            final PopInstruction scopingInfo = new 
PopInstruction(this.getPop(), label);
+            popInstructions.add(scopingInfo);
+        }
+        popInstructions.addAll(TraversalParent.super.getPopInstructions());
+        return popInstructions;
+    }
+
     @Override
     public String toString() {
         return StringFactory.stepString(this, this.pop, this.keyTraversal, 
this.selectTraversal);
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStep.java
index 7d155a40bd..c9b2acd86b 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStep.java
@@ -38,6 +38,7 @@ import 
org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.structure.util.keyed.KeyedProperty;
 import org.apache.tinkerpop.gremlin.structure.util.keyed.KeyedVertexProperty;
 
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
@@ -70,6 +71,14 @@ public class AddPropertyStep<S extends Element> extends 
SideEffectStep<S>
         return this.parameters.getReferencedLabels();
     }
 
+    @Override
+    public HashSet<PopInstruction> getPopInstructions() {
+        final HashSet<PopInstruction> popInstructions = new HashSet<>();
+        popInstructions.addAll(Scoping.super.getPopInstructions());
+        popInstructions.addAll(TraversalParent.super.getPopInstructions());
+        return popInstructions;
+    }
+
     @Override
     public <S, E> List<Traversal.Admin<S, E>> getLocalChildren() {
         return this.parameters.getTraversals();
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 19117d6e9a..44df37cfd0 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
@@ -28,6 +28,7 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.lambda.ValueTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.lambda.TokenTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
 import org.apache.tinkerpop.gremlin.process.traversal.step.HasContainerHolder;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
 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.branch.RepeatStep;
@@ -54,7 +55,6 @@ import 
org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Comparator;
 import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
@@ -788,4 +788,22 @@ public final class TraversalHelper {
         } else
             return (T) traversal.addStep(new HasStep<>(traversal, 
hasContainer));
     }
+
+    /**
+     * Used to get PopInstruction of a traversal. Pop Instruction includes the 
labels it needs, and the pop type for each label.
+     *
+     * @param traversal     the traversal to get Scope Context for
+     * @param <T>           the traversal type
+     * @return              A Set of {@link 
org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining.PopInstruction}
 values which contain the label and Pop value
+     */
+    public static <T extends  Traversal.Admin<?, ?>> 
Set<PopContaining.PopInstruction> getPopInstructions(final T traversal) {
+        final Set<PopContaining.PopInstruction> scopingInfos = new HashSet<>();
+        for (final Step step: traversal.getSteps()) {
+            if (step instanceof PopContaining) {
+                scopingInfos.addAll(((PopContaining) 
step).getPopInstructions());
+            }
+        }
+        return scopingInfos;
+    }
+
 }
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/TestDataBuilder.java 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/TestDataBuilder.java
new file mode 100644
index 0000000000..1f429659fa
--- /dev/null
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/TestDataBuilder.java
@@ -0,0 +1,48 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tinkerpop.gremlin;
+
+import java.util.HashSet;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
+
+/**
+ * This class is responsible for building test data for `PopInstruction` Unit 
tests.
+ * It provides methods to create a set of `PopInstruction` test data objects.
+ *
+ */
+public class TestDataBuilder {
+
+    // Helper function to create a Set of `PopInstruction` values
+    public static HashSet<PopContaining.PopInstruction> 
createPopInstructionSet(final Object[]... pairs) {
+        final HashSet<PopContaining.PopInstruction> popInstructions = new 
HashSet<>();
+
+        // Each pair should contain a name (String) and a Pop value
+        for (final Object[] pair : pairs) {
+            if (pair.length == 2 && pair[0] instanceof String && pair[1] 
instanceof Pop) {
+                popInstructions.add(new 
PopContaining.PopInstruction((String)pair[0], (Pop)pair[1]));
+            } else {
+                throw new IllegalArgumentException("Invalid pair: " + pair);
+            }
+        }
+
+        return popInstructions;
+    }
+}
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStepTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStepTest.java
index 67331c2a88..911fd72f4d 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStepTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStepTest.java
@@ -18,13 +18,20 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
 
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
 import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
+import org.junit.Test;
 
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 
+import static org.junit.Assert.assertEquals;
+
 /**
  * @author Daniel Kuppitz (http://gremlin.guru)
  */
@@ -37,4 +44,16 @@ public class DedupGlobalStepTest extends StepTest {
                 __.dedup().by("name")
         );
     }
+
+    @Test
+    public void shouldObtainPopInstructions() {
+        final DedupGlobalStep dedupGlobalStep = new 
DedupGlobalStep(__.identity().asAdmin(), "label1", "label2", "label1");
+
+        final HashSet<PopContaining.PopInstruction> popInstructionSet = 
TestDataBuilder.createPopInstructionSet(
+                new Object[]{"label1", Pop.last},
+                new Object[]{"label2", Pop.last}
+        );
+
+        assertEquals(dedupGlobalStep.getPopInstructions(), popInstructionSet);
+    }
 }
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 fa9adeb1f7..24700083f5 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
@@ -18,15 +18,20 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
 
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
 import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
 import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
 import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversal;
 import org.junit.Test;
-
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Optional;
 
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.as;
 import static org.junit.Assert.assertEquals;
@@ -65,4 +70,30 @@ public class WhereStepTest extends StepTest {
             assertEquals(traversalPath[0], ((Traversal.Admin<?, ?>) 
traversalPath[1]).getTraverserRequirements().contains(TraverserRequirement.LABELED_PATH));
         }
     }
+
+    @Test
+    public void shouldObtainPopInstructions() {
+
+        // Testing WherePredicate Step
+        final WherePredicateStep wherePredicateStep = new 
WherePredicateStep(__.identity().asAdmin(), Optional.of("key1"), 
P.neq("label1"));
+
+        HashSet<PopContaining.PopInstruction> popInstructionSet = 
TestDataBuilder.createPopInstructionSet(
+                new Object[]{"key1", Pop.last},
+                new Object[]{"label1", Pop.last}
+        );
+
+        assertEquals(wherePredicateStep.getPopInstructions(), 
popInstructionSet);
+
+        // Testing WhereTraversal Test
+        final WhereTraversalStep whereTraversalStep = new 
WhereTraversalStep<>(new DefaultTraversal(), __.as("x").select(Pop.first, "a", 
"b").asAdmin());
+
+        popInstructionSet = TestDataBuilder.createPopInstructionSet(
+                new Object[]{"x", Pop.last},
+                new Object[]{"a", Pop.first},
+                new Object[]{"b", Pop.first}
+        );
+
+        assertEquals(whereTraversalStep.getPopInstructions(), 
popInstructionSet);
+
+    }
 }
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStepTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStepTest.java
index f4282aec69..d5742ba1f0 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStepTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStepTest.java
@@ -18,13 +18,23 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
+import org.junit.Test;
 
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 
+import static org.junit.Assert.assertEquals;
+
+
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
+
+
 /**
  * @author Daniel Kuppitz (http://gremlin.guru)
  */
@@ -39,4 +49,24 @@ public class AddEdgeStepTest extends StepTest {
                 __.addE("knows").property("c", "d")
         );
     }
+
+    @Test
+    public void shouldObtainPopInstructions() {
+        // Edge Step Test
+        final AddEdgeStep<Object> addEdgeStep = new 
AddEdgeStep<>(__.identity().asAdmin(),
+                (Traversal.Admin) __.select(Pop.first, "b").select("a"));
+
+        final HashSet<PopContaining.PopInstruction> expectedOutput = 
TestDataBuilder.createPopInstructionSet(
+                new Object[]{"b", Pop.first},
+                new Object[]{"a", Pop.last}
+        );
+
+        assertEquals(addEdgeStep.getPopInstructions(), expectedOutput);
+
+        // Edge Step Start test
+        final AddEdgeStartStep addEdgeStartStep = new 
AddEdgeStartStep(__.identity().asAdmin(),
+                __.select(Pop.first, "b").select("a"));
+
+        assertEquals(addEdgeStartStep.getPopInstructions(), expectedOutput);
+    }
 }
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStepTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStepTest.java
index d5ae0ec900..bda33a2507 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStepTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStepTest.java
@@ -18,7 +18,13 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
+import java.util.HashSet;
+
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.util.function.TraverserSetSupplier;
@@ -49,4 +55,25 @@ public class AddVertexStepTest {
         final AddVertexStep step = new AddVertexStep(t, (String) null);
         assertEquals(Vertex.DEFAULT_LABEL, 
starStep.getParameters().getRaw().get(T.label).get(0));
     }
+
+    @Test
+    public void shouldObtainPopInstructions() {
+        // Vertex Step Test
+        final AddVertexStep addVertexStep = new 
AddVertexStep(__.identity().asAdmin(),
+                (Traversal.Admin) __.select(Pop.first, 
"b").select("a").select(Pop.last, "c"));
+
+        final HashSet<PopContaining.PopInstruction> expectedOutput = 
TestDataBuilder.createPopInstructionSet(
+                new Object[]{"b", Pop.first},
+                new Object[]{"a", Pop.last},
+                new Object[]{"c", Pop.last}
+        );
+
+        assertEquals(addVertexStep.getPopInstructions(), expectedOutput);
+
+        // Vertex Start Step Test
+        final AddVertexStartStep addVertexStartStep = new 
AddVertexStartStep(__.identity().asAdmin(),
+                __.select(Pop.first, "b").select("a").select(Pop.last, "c"));
+
+        assertEquals(addVertexStartStep.getPopInstructions(), expectedOutput);
+    }
 }
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStepTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStepTest.java
index cf66458f45..977afa37f2 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStepTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStepTest.java
@@ -18,8 +18,11 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
 import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
@@ -29,6 +32,7 @@ import org.junit.Test;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 
 import static org.apache.tinkerpop.gremlin.util.CollectionUtil.asMap;
@@ -180,4 +184,17 @@ public class FormatStepTest extends StepTest {
                 __.__("Marko").as("name").
                         constant(vertex).format("Hello %{name}").next());
     }
+
+    @Test
+    public void shouldObtainPopInstructions() {
+        final FormatStep formatStep = new FormatStep(__.identity().asAdmin(), 
"%{Hello} %{world}");
+
+        final HashSet<PopContaining.PopInstruction> popInstructionSet = 
TestDataBuilder.createPopInstructionSet(
+                new Object[]{"Hello", Pop.last},
+                new Object[]{"world", Pop.last}
+        );
+
+        assertEquals(formatStep.getPopInstructions(), popInstructionSet);
+
+    }
 }
\ No newline at end of file
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 9b204cf285..f2dd400494 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
@@ -18,10 +18,13 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
 import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
 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.ConnectiveStep;
@@ -418,4 +421,20 @@ public class MatchStepTest extends StepTest {
         assertEquals("a", MatchStep.Helper.computeStartLabel(((MatchStep<?, 
?>) traversal.getStartStep()).getGlobalChildren()));
     }
 
+    @Test
+    public void shouldObtainPopInstructions() {
+        final Traversal.Admin<?, ?> traversal = 
__.match(as("a").out().as("b"), as("c").path().as("d")).asAdmin();
+        final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) 
traversal.getStartStep();
+
+        final HashSet<PopContaining.PopInstruction> popInstructionSet = 
TestDataBuilder.createPopInstructionSet(
+                new Object[]{"a", Pop.last},
+                new Object[]{"b", Pop.last},
+                new Object[]{"c", Pop.last},
+                new Object[]{"d", Pop.last}
+        );
+
+
+        assertEquals(matchStep.getPopInstructions(), popInstructionSet);
+    }
+
 }
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStepTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStepTest.java
index 0a9141c335..6dd0a147cc 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStepTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStepTest.java
@@ -19,14 +19,19 @@
 
 package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
 import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
 import org.junit.Test;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.both;
@@ -71,4 +76,20 @@ public class MathStepTest extends StepTest {
         assertEquals(Arrays.asList("number1", "expected_value"), new 
ArrayList<>(MathStep.getVariables("number1-expected_value")));
     }
 
+    @Test
+    public void shouldObtainPopInstructions() {
+        final GraphTraversal<Object, Object> traversal = __.identity();
+
+        final MathStep mathStep = new MathStep<>((Traversal.Admin) traversal, 
"a + b - c");
+
+        // Expected Output
+        final HashSet<PopContaining.PopInstruction> popInstructionSet = 
TestDataBuilder.createPopInstructionSet(
+                new Object[]{"a", Pop.last},
+                new Object[]{"b", Pop.last},
+                new Object[]{"c", Pop.last}
+        );
+
+        assertEquals(popInstructionSet, mathStep.getPopInstructions());
+    }
+
 }
\ No newline at end of file
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStepTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStepTest.java
index 480c0b1f09..1ce46d47d2 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStepTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStepTest.java
@@ -18,14 +18,18 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
 import org.apache.tinkerpop.gremlin.process.traversal.Pop;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
 import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
 import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
 import org.junit.Test;
 
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 
 import static org.junit.Assert.assertEquals;
@@ -61,4 +65,48 @@ public class SelectOneStepTest extends StepTest {
             assertEquals(traversalPath[0], ((Traversal.Admin<?, ?>) 
traversalPath[1]).getTraverserRequirements().contains(TraverserRequirement.LABELED_PATH));
         }
     }
+
+    @Test
+    public void shouldObtainPopInstructions() {
+        final GraphTraversal<Object, Object> traversal = __.identity();
+
+        // Expected Output
+        HashSet<PopContaining.PopInstruction> popInstructionSet = 
TestDataBuilder.createPopInstructionSet(
+            new Object[]{"x", Pop.all}
+        );
+
+        // Pop.all
+        final SelectOneStep selectOneStepAll = new 
SelectOneStep((Traversal.Admin) traversal, Pop.all, "x");
+
+        assertEquals(selectOneStepAll.getPopInstructions(), popInstructionSet);
+
+
+        // Pop.last
+        final SelectOneStep selectOneStepLast = new 
SelectOneStep<>((Traversal.Admin) traversal, Pop.last, "x");
+        popInstructionSet = TestDataBuilder.createPopInstructionSet(
+            new Object[]{"x", Pop.last}
+        );
+
+        assertEquals(selectOneStepLast.getPopInstructions(), 
popInstructionSet);
+
+
+        // Pop.first
+        final SelectOneStep selectOneStepFirst = new 
SelectOneStep<>((Traversal.Admin) traversal, Pop.first, "x");
+        popInstructionSet = popInstructionSet = 
TestDataBuilder.createPopInstructionSet(
+            new Object[]{"x", Pop.first}
+        );
+
+        assertEquals(selectOneStepFirst.getPopInstructions(), 
popInstructionSet);
+
+
+        // Pop.mixed
+        final SelectOneStep selectOneStepMixed = new 
SelectOneStep<>((Traversal.Admin) traversal, Pop.mixed, "x");
+        popInstructionSet = popInstructionSet = 
TestDataBuilder.createPopInstructionSet(
+            new Object[]{"x", Pop.mixed}
+        );
+
+
+        assertEquals(selectOneStepMixed.getPopInstructions(), 
popInstructionSet);
+
+    }
 }
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStepTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStepTest.java
index 5393403d81..4d39cdd239 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStepTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStepTest.java
@@ -18,14 +18,18 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.map;
 
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
 import org.apache.tinkerpop.gremlin.process.traversal.Pop;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
 import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
 import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
 import org.junit.Test;
 
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 
 import static org.junit.Assert.assertEquals;
@@ -63,4 +67,50 @@ public class SelectStepTest extends StepTest {
             assertEquals(traversalPath[0], ((Traversal.Admin<?, ?>) 
traversalPath[1]).getTraverserRequirements().contains(TraverserRequirement.LABELED_PATH));
         }
     }
+
+    @Test
+    public void shouldObtainPopInstructions() {
+        final GraphTraversal<Object, Object> traversal = __.identity();
+
+        // 2 keys, and Pop.all
+        final SelectStep selectStepAll = new SelectStep<>((Traversal.Admin) 
traversal, Pop.all, "x", "y");
+        HashSet<PopContaining.PopInstruction> popInstructionSet = 
TestDataBuilder.createPopInstructionSet(
+                new Object[]{"x", Pop.all},
+                new Object[]{"y", Pop.all}
+        );
+
+        assertEquals(selectStepAll.getPopInstructions(), popInstructionSet);
+
+
+        // 3 keys, and Pop.last
+        final SelectStep selectStepLast = new SelectStep<>((Traversal.Admin) 
traversal, Pop.last, "x", "y", "z");
+        popInstructionSet = TestDataBuilder.createPopInstructionSet(
+                new Object[]{"x", Pop.last},
+                new Object[]{"y", Pop.last},
+                new Object[]{"z", Pop.last}
+        );
+
+        assertEquals(selectStepLast.getPopInstructions(), popInstructionSet);
+
+
+        // 2 keys, and Pop.first
+        final SelectStep selectStepFirst = new SelectStep<>((Traversal.Admin) 
traversal, Pop.first, "x", "y");
+        popInstructionSet = TestDataBuilder.createPopInstructionSet(
+                new Object[]{"x", Pop.first},
+                new Object[]{"y", Pop.first}
+        );
+
+        assertEquals(selectStepFirst.getPopInstructions(), popInstructionSet);
+
+
+        // 2 keys, and Pop.mixed
+        final SelectStep selectStepMixed = new SelectStep<>((Traversal.Admin) 
traversal, Pop.mixed, "x", "y");
+        popInstructionSet = TestDataBuilder.createPopInstructionSet(
+                new Object[]{"x", Pop.mixed},
+                new Object[]{"y", Pop.mixed}
+        );
+
+        assertEquals(selectStepMixed.getPopInstructions(), popInstructionSet);
+
+    }
 }
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalSelectStepTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalSelectStepTest.java
new file mode 100644
index 0000000000..1e0198ba57
--- /dev/null
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TraversalSelectStepTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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 anmvn  limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.HashSet;
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
+import org.junit.Test;
+
+public class TraversalSelectStepTest {
+    
+    @Test
+    public void shouldObtainPopInstructions() {
+        TraversalSelectStep step = new 
TraversalSelectStep(__.select("a").asAdmin(), Pop.first, __.select(Pop.first, 
"b").select("c"));
+
+        HashSet<PopContaining.PopInstruction> expectedOutput = 
TestDataBuilder.createPopInstructionSet(
+                new Object[]{"b", Pop.first},
+                new Object[]{"c", Pop.last}
+        );
+
+        assertEquals(step.getPopInstructions(), expectedOutput);
+
+        step = new TraversalSelectStep(__.identity().asAdmin(), Pop.first, 
__.select(Pop.first, "a", "b", "c"));
+
+        // 3 keys, and Pop.first
+        expectedOutput = TestDataBuilder.createPopInstructionSet(
+                new Object[]{"a", Pop.first},
+                new Object[]{"c", Pop.first},
+                new Object[]{"b", Pop.first}
+        );
+
+        assertEquals(step.getPopInstructions(), expectedOutput);
+    
+
+}
+}
\ No newline at end of file
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStepTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStepTest.java
index 26d145aa05..d14e0b8ad3 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStepTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStepTest.java
@@ -21,10 +21,13 @@ package 
org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
+import org.junit.Test;
 
 import java.util.Arrays;
 import java.util.List;
 
+import static org.junit.Assert.assertEquals;
+
 /**
  * @author Daniel Kuppitz (http://gremlin.guru)
  */
@@ -38,4 +41,11 @@ public class AddPropertyStepTest extends StepTest {
                // __.property("y", 0)
         );
     }
+
+    @Test
+    public void testGetPopInstructions() {
+        final AddPropertyStep step = new 
AddPropertyStep(__.identity().select("s").asAdmin(), null, "x", 0);
+
+        assertEquals(0, step.getPopInstructions().size());
+    }
 }
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelperTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelperTest.java
index c7884451ac..aa86a0d913 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelperTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelperTest.java
@@ -18,10 +18,14 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.util;
 
+import org.apache.tinkerpop.gremlin.TestDataBuilder;
 import 
org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.TraversalVertexProgramStep;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
 import org.apache.tinkerpop.gremlin.process.traversal.Step;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PopContaining;
 import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.LocalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.RepeatStep;
@@ -47,14 +51,22 @@ import 
org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
 import org.junit.Test;
 import org.mockito.Mockito;
 
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.has;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.in;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.outE;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.path;
+import static 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.repeat;
+import static 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.select;
+import static 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.union;
+import static 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.valueMap;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -485,4 +497,85 @@ public class TraversalHelperTest {
         assertEquals("e", ((PropertiesStep) 
steps.get(4)).getPropertyKeys()[0]);
         assertEquals("f", ((PropertiesStep) 
steps.get(5)).getPropertyKeys()[0]);
     }
+
+    @Test
+    public void shouldGetPopInstructions() {
+        final List<Traversal.Admin<?,?>> traversals = new ArrayList<>();
+        final List<Set<PopContaining.PopInstruction>> expectedResults = new 
ArrayList<>();
+
+        ///
+        traversals.add(__.V().has("person", "name", 
"marko").as("start").repeat(out().as("reached").select("start")).times(2).select("reached").asAdmin());
+        expectedResults.add(TestDataBuilder.createPopInstructionSet(
+                new Object[]{"start", Pop.last},
+                new Object[]{"reached", Pop.last}
+        ));
+        ///
+        traversals.add(__.V().select("vertex").asAdmin());
+        expectedResults.add(TestDataBuilder.createPopInstructionSet(
+                new Object[]{"vertex", Pop.last}
+        ));
+        ///
+        traversals.add(__.V().out().as("a").repeat(union(out().select("a"), 
path().select(Pop.mixed, "b"))).select(Pop.first,"c").asAdmin());
+        expectedResults.add(TestDataBuilder.createPopInstructionSet(
+                new Object[]{"a", Pop.last},
+                new Object[]{"b", Pop.mixed},
+                new Object[]{"c", Pop.first}
+        ));
+        ///
+        
traversals.add(__.V().as("b").repeat(select("b").out().as("a")).times(2).select(Pop.first,
 "a").select(Pop.last, "a").project("bb").by(__.select(Pop.all, 
"a")).asAdmin());
+        expectedResults.add(TestDataBuilder.createPopInstructionSet(
+                new Object[]{"b", Pop.last},
+                new Object[]{"a", Pop.first},
+                new Object[]{"a", Pop.all},
+                new Object[]{"a", Pop.last}
+        ));
+        ///
+        
traversals.add(__.V("1").as("b").repeat(select("b").out().as("a")).times(2).path().as("c").by("name").asAdmin());
+        expectedResults.add(TestDataBuilder.createPopInstructionSet(
+                new Object[]{"b", Pop.last}
+        ));
+        ///
+        traversals.add(__.V().union(out().as("a"), 
repeat(out().as("a")).emit()).select(Pop.last, "a").asAdmin());
+        expectedResults.add(TestDataBuilder.createPopInstructionSet(
+                new Object[]{"a", Pop.last}
+        ));
+        ///
+        traversals.add(__.V().has("person", "name", 
"marko").as("start").repeat(out()).times(2).where(P.neq("start")).values("name").asAdmin());
+        expectedResults.add(TestDataBuilder.createPopInstructionSet(
+                new Object[]{"start", Pop.last}
+        ));
+        ///
+        traversals.add(__.V().union(out(), 
repeat(out().as("a")).emit()).select(Pop.last, "a").asAdmin());
+        expectedResults.add(TestDataBuilder.createPopInstructionSet(
+                new Object[]{"a", Pop.last}
+        ));
+        ///
+        traversals.add(__.V().as("a").union(path(), 
repeat(out().select(Pop.last, "a"))).asAdmin());
+        expectedResults.add(TestDataBuilder.createPopInstructionSet(
+                new Object[]{"a", Pop.last}
+        ));
+        ///
+        
traversals.add(__.V().hasLabel("person").repeat(out("created")).emit().as("software").select("software").values("name",
 "lang").asAdmin());
+        expectedResults.add(TestDataBuilder.createPopInstructionSet(
+                new Object[]{"software", Pop.last}
+        ));
+        ///
+        
traversals.add(__.V().hasLabel("person").repeat(out("created").as("created_thing")).emit().as("final").select(Pop.mixed,
 "created_thing", "final"). by("name").by("lang").asAdmin());
+        expectedResults.add(TestDataBuilder.createPopInstructionSet(
+                new Object[]{"created_thing", Pop.mixed},
+                new Object[]{"final", Pop.mixed}
+        ));
+        ///
+        traversals.add(__.V().has("person", "name", 
"marko").as("start").repeat(out().as("path_element")).until(has("lang")).as("software").select("start",
 "path_element", "software").by("name").by("name").by(valueMap("name", 
"lang")).asAdmin());
+        expectedResults.add(TestDataBuilder.createPopInstructionSet(
+                new Object[]{"start", Pop.last},
+                new Object[]{"path_element", Pop.last},
+                new Object[]{"software", Pop.last}
+        ));
+
+        // Run all the tests
+        for (int i = 0; i < traversals.size(); i++) {
+            
assertEquals(TraversalHelper.getPopInstructions(traversals.get(i)), 
expectedResults.get(i));
+        }
+    }
 }

Reply via email to