You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2022/01/18 14:01:31 UTC

[tinkerpop] branch master updated: Orderability Semantics

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

spmallette pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/master by this push:
     new 9f58ec5  Orderability Semantics
     new fe74928  Merge pull request #1545 from mikepersonick/TINKERPOP-2641
9f58ec5 is described below

commit 9f58ec53973d7a1814e1d269a854392be3df78e9
Author: mikepersonick <mi...@supersonick.io>
AuthorDate: Wed Dec 22 14:32:43 2021 -0800

    Orderability Semantics
    
      https://github.com/apache/tinkerpop/pull/1545
    
      https://issues.apache.org/jira/browse/TINKERPOP-2604
      https://issues.apache.org/jira/browse/TINKERPOP-2606
      https://issues.apache.org/jira/browse/TINKERPOP-2641
---
 CHANGELOG.asciidoc                                 |   1 +
 docs/src/dev/developer/for-committers.asciidoc     |   4 +
 docs/src/upgrade/release-3.6.x.asciidoc            |  68 ++-
 .../tinkerpop/gremlin/process/traversal/Order.java |  22 +-
 .../apache/tinkerpop/gremlin/structure/Graph.java  | 342 ++++++-------
 .../gremlin/util/OrderabilityComparator.java       | 189 ++++++++
 gremlin-dotnet/build/generate.groovy               |  34 +-
 .../Gherkin/CommonSteps.cs                         |   4 +-
 .../Gherkin/GherkinTestRunner.cs                   |   2 +
 .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs |  19 +
 .../Gherkin/IgnoreException.cs                     |   7 +-
 .../groovy/jsr223/GroovyTranslatorProvider.java    |   4 +
 .../ParameterizedGroovyTranslatorProvider.java     |   4 +
 .../test/cucumber/feature-steps.js                 |  19 +-
 .../gremlin-javascript/test/cucumber/gremlin.js    |  19 +
 .../gremlin/language/corpus/FeatureReader.java     |  12 +-
 .../language/grammar/ReferenceGrammarTest.java     |   4 +
 .../src/main/python/radish/feature_steps.py        |   6 +-
 gremlin-python/src/main/python/radish/gremlin.py   |  19 +
 .../driver/remote/AbstractRemoteGraphProvider.java |   4 +
 .../features/semantics/Orderability.feature        | 355 ++++++++++++++
 .../tinkerpop/gremlin/AbstractGremlinTest.java     |   8 +
 .../tinkerpop/gremlin/features/StepDefinition.java |  28 +-
 .../process/ProcessLimitedStandardSuite.java       |   8 +-
 .../gremlin/process/ProcessStandardSuite.java      |   6 +-
 .../process/traversal/step/OrderabilityTest.java   | 536 +++++++++++++++++++++
 .../gremlin/neo4j/Neo4jGraphFeatureTest.java       |   2 +-
 .../tinkergraph/structure/TinkerFactory.java       |  25 +-
 ...tractTinkerGraphGraphSONTranslatorProvider.java |  12 +
 .../io/gryo/TinkerGraphGryoTranslatorProvider.java |   4 +
 30 files changed, 1536 insertions(+), 231 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 2256c34..824cfeb 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -23,6 +23,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 [[release-3-6-0]]
 === TinkerPop 3.6.0 (Release Date: NOT OFFICIALLY RELEASED YET)
 
+* Implemented total orderability across types per the Gremlin semantics for comparability/orderability defined in the Graph Provider documentation.
 * Changed TinkerGraph to allow identifiers to be heterogeneous when filtering.
 * Prevented values of `T` to `property()` from being `null`.
 * Added `fail()` step.
diff --git a/docs/src/dev/developer/for-committers.asciidoc b/docs/src/dev/developer/for-committers.asciidoc
index 056f9a8..20486b0 100644
--- a/docs/src/dev/developer/for-committers.asciidoc
+++ b/docs/src/dev/developer/for-committers.asciidoc
@@ -502,6 +502,7 @@ are two types of tags:
 * `@StepClass*` - Marks the step grouping and is a prefix that precedes and either refers to one of the following:
 ** One of the four types of steps: `Branch`, `Filter`, `Map`, and `SideEffect` (e.g. `@StepClassBranch`)
 ** `Semantics` which maps to elements of the link:https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#gremlin-semantics[Gremlin Semantics] specification.
+** `Orderability` which maps to the total orderability semantics defined in the link:https://tinkerpop.apache.org/docs/x.y.z/dev/provider/#gremlin-semantics[Gremlin Semantics] specification.
 ** An `Integrated` grouping that does not fit those individual classifications well.
 * `@Step*` - Marks testing for a particular step. While this tag is generally unique to the feature
 file itself and test filtering could be accomplished at that level by way of the file, the use of the tag is a
@@ -532,6 +533,9 @@ the traversal does not mind the star graph limitation.
 or meta-properties for creating or querying data.
 * `@RemoteOnly` - The scenario uses some Gremlin syntax that cannot be supported outside of remote test executions. The
 best example of this sort of test would be one that uses the remote `Lambda` syntax.
+* `@UserSuppliedVertexIds` - The scenario relies on the vertex IDs specified in the dataset used by the scenario.
+* `@UserSuppliedEdgeIds` - The scenario relies on the edge IDs specified in the dataset used by the scenario.
+* `@UserSuppliedVertexPropertyIds` - The scenario relies on the vertex property IDs specified in the dataset used by the scenario.
 
 Tag filters can be applied to Intellij at execution time by adding a system properties of
 `-Dcucumber.filter.tags=<step-filter>`.
diff --git a/docs/src/upgrade/release-3.6.x.asciidoc b/docs/src/upgrade/release-3.6.x.asciidoc
index 8d8c990..6166865 100644
--- a/docs/src/upgrade/release-3.6.x.asciidoc
+++ b/docs/src/upgrade/release-3.6.x.asciidoc
@@ -599,4 +599,70 @@ with TinkerGraph operations where mixed `T.id` types is a feature. Graph provide
 requirement if they wish, but it is no longer enforced by TinkerPop and the `Graph.idArgsMustBeEitherIdOrElement` has
 been removed so providers will need to construct their own exception.
 
-See: link:https://issues.apache.org/jira/browse/TINKERPOP-2507[TINKERPOP-2507]
\ No newline at end of file
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-2507[TINKERPOP-2507]
+
+===== Orderability Semantics
+
+Prior to 3.6, orderability (OrderGlobalStep) only applied to a single typespace and only to certain types. Attempts to
+order across types resulted in an exception. The 3.6 release introduces total orderability semantics, defined in the
+Graph Provider Documentation. Order now works on all types in the Gremlin language, including collections, structure
+elements (Vertex, Edge, VertexProperty, Property), paths, and all the allowed property value types. Additionally,
+ordering is possible across types, with the type priority defined in the orderability semantics section of the Provider
+Documentation.
+
+[source,text]
+----
+gremlin> g = traversal().withEmbedded(TinkerFactory.createModern())
+==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
+
+// Order across types
+gremlin> g.V().values().order()     // 3.5.x
+java.lang.String cannot be cast to java.lang.Integer
+Type ':help' or ':h' for help.
+gremlin> g.V().values().order()     // 3.6.0
+==>27
+==>29
+==>32
+==>35
+==>java
+==>java
+==>josh
+==>lop
+==>marko
+==>peter
+==>ripple
+==>vadas
+
+// Order by Vertex
+gremlin> g.V().order()      // 3.5.x
+org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertex cannot be cast to java.lang.Comparable
+Type ':help' or ':h' for help.
+Display stack trace? [yN]
+gremlin> g.V().order()      // 3.6.0
+==>v[1]
+==>v[2]
+==>v[3]
+==>v[4]
+==>v[5]
+==>v[6]
+
+// Order by Map / Map.Entry
+gremlin> g.V().valueMap().order()   // 3,5,x
+java.util.LinkedHashMap cannot be cast to java.lang.Comparable
+Type ':help' or ':h' for help.
+Display stack trace? [yN]
+gremlin> g.V().valueMap().order()   // 3.6.0
+==>[name:[josh],age:[32]]
+==>[name:[lop],lang:[java]]
+==>[name:[marko],age:[29]]
+==>[name:[peter],age:[35]]
+==>[name:[ripple],lang:[java]]
+==>[name:[vadas],age:[27]]
+----
+
+Feature tags have been introduced for feature tests that stress these new semantics (see Committer Documentation).
+A new GraphFeature has been added "OrderabilitySemantics" to signify compliance with the new cross type orderability
+semantics.
+
+See: link:https://tinkerpop.apache.org/docs/3.6.0/dev/provider/#_orderability[Provider Documentation]
+See: link:https://tinkerpop.apache.org/docs/3.6.0/dev/developer/#_for_committers[Developer Documentation]
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Order.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Order.java
index d4d55b0..4bdb850 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Order.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Order.java
@@ -21,7 +21,7 @@ package org.apache.tinkerpop.gremlin.process.traversal;
 import java.util.Comparator;
 import java.util.Random;
 
-import org.apache.tinkerpop.gremlin.util.NumberHelper;
+import org.apache.tinkerpop.gremlin.util.OrderabilityComparator;
 
 /**
  * Provides {@code Comparator} instances for ordering traversers.
@@ -56,17 +56,9 @@ public enum Order implements Comparator<Object> {
      * @since 3.3.4
      */
     asc {
-        private final Comparator<Comparable> ascendingComparator = Comparator.nullsFirst(Comparator.<Comparable>naturalOrder());
-
         @Override
         public int compare(final Object first, final Object second) {
-            // need to convert enum to string representations for comparison or else you can get cast exceptions.
-            // this typically happens when sorting local on the keys of maps that contain T
-            final Object f = first instanceof Enum<?> ? ((Enum<?>) first).name() : first;
-            final Object s = second instanceof Enum<?> ? ((Enum<?>) second).name() : second;
-            return f instanceof Number && s instanceof Number
-                    ? NumberHelper.compare((Number) f, (Number) s)
-                    : ascendingComparator.compare((Comparable) f, (Comparable) s);
+            return OrderabilityComparator.INSTANCE.compare(first, second);
         }
 
         @Override
@@ -81,17 +73,9 @@ public enum Order implements Comparator<Object> {
      * @since 3.3.4
      */
     desc {
-        private final Comparator<Comparable> descendingComparator = Comparator.nullsLast(Comparator.<Comparable>reverseOrder());
-
         @Override
         public int compare(final Object first, final Object second) {
-            // need to convert enum to string representations for comparison or else you can get cast exceptions.
-            // this typically happens when sorting local on the keys of maps that contain T
-            final Object f = first instanceof Enum<?> ? ((Enum<?>) first).name() : first;
-            final Object s = second instanceof Enum<?> ? ((Enum<?>) second).name() : second;
-            return f instanceof Number && s instanceof Number
-                    ? NumberHelper.compare((Number) s, (Number) f)
-                    : descendingComparator.compare((Comparable) f, (Comparable) s);
+            return OrderabilityComparator.INSTANCE.compare(second, first);
         }
 
         @Override
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
index 42af032..0266198 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
@@ -61,13 +61,13 @@ public interface Graph extends AutoCloseable, Host {
     /**
      * Configuration key used by {@link GraphFactory}} to determine which graph to instantiate.
      */
-    public static final String GRAPH = "gremlin.graph";
+    String GRAPH = "gremlin.graph";
 
     /**
      * This should only be used by providers to create keys, labels, etc. in a namespace safe from users.
      * Users are not allowed to generate property keys, step labels, etc. that are key'd "hidden".
      */
-    public static class Hidden {
+    class Hidden {
 
         /**
          * The prefix to denote that a key is a hidden key.
@@ -114,7 +114,7 @@ public interface Graph extends AutoCloseable, Host {
      * @param keyValues The key/value pairs to turn into vertex properties
      * @return The newly created vertex
      */
-    public Vertex addVertex(final Object... keyValues);
+    Vertex addVertex(final Object... keyValues);
 
     /**
      * Add a {@link Vertex} to the graph with provided vertex label.
@@ -122,7 +122,7 @@ public interface Graph extends AutoCloseable, Host {
      * @param label the label of the vertex
      * @return The newly created labeled vertex
      */
-    public default Vertex addVertex(final String label) {
+    default Vertex addVertex(final String label) {
         return this.addVertex(T.label, label);
     }
 
@@ -134,7 +134,7 @@ public interface Graph extends AutoCloseable, Host {
      * @return A graph computer for processing this graph
      * @throws IllegalArgumentException if the provided {@link GraphComputer} class is not supported.
      */
-    public <C extends GraphComputer> C compute(final Class<C> graphComputerClass) throws IllegalArgumentException;
+    <C extends GraphComputer> C compute(final Class<C> graphComputerClass) throws IllegalArgumentException;
 
     /**
      * Generate a {@link GraphComputer} using the default engine of the underlying graph system.
@@ -143,7 +143,7 @@ public interface Graph extends AutoCloseable, Host {
      * @return A default graph computer
      * @throws IllegalArgumentException if there is no default graph computer
      */
-    public GraphComputer compute() throws IllegalArgumentException;
+    GraphComputer compute() throws IllegalArgumentException;
 
     /**
      * Generate a {@link TraversalSource} using the specified {@code TraversalSource} class.
@@ -152,7 +152,7 @@ public interface Graph extends AutoCloseable, Host {
      * @param traversalSourceClass The traversal source class
      * @param <C>                  The traversal source class
      */
-    public default <C extends TraversalSource> C traversal(final Class<C> traversalSourceClass) {
+    default <C extends TraversalSource> C traversal(final Class<C> traversalSourceClass) {
         try {
             return traversalSourceClass.getConstructor(Graph.class).newInstance(this);
         } catch (final Exception e) {
@@ -166,7 +166,7 @@ public interface Graph extends AutoCloseable, Host {
      *
      * @return A graph traversal source
      */
-    public default GraphTraversalSource traversal() {
+    default GraphTraversalSource traversal() {
         return new GraphTraversalSource(this);
     }
 
@@ -222,7 +222,7 @@ public interface Graph extends AutoCloseable, Host {
      * @param vertexIds the ids of the vertices to get
      * @return an {@link Iterator} of vertices that match the provided vertex ids
      */
-    public Iterator<Vertex> vertices(final Object... vertexIds);
+    Iterator<Vertex> vertices(final Object... vertexIds);
 
     /**
      * Get the {@link Edge} objects in this graph with the provided edge ids or {@link Edge} objects. If no ids are
@@ -268,18 +268,18 @@ public interface Graph extends AutoCloseable, Host {
      * @param edgeIds the ids of the edges to get
      * @return an {@link Iterator} of edges that match the provided edge ids
      */
-    public Iterator<Edge> edges(final Object... edgeIds);
+    Iterator<Edge> edges(final Object... edgeIds);
 
     /**
      * Configure and control the transactions for those graphs that support this feature.
      */
-    public Transaction tx();
+    Transaction tx();
 
     /**
      * Configure and control the transactions for those graphs that support this feature. Graphs that support multiple
      * transaction models can use this method expose different sorts of {@link Transaction} implementations.
      */
-    public default <Tx extends Transaction> Tx tx(final Class<Tx> txClass) {
+    default <Tx extends Transaction> Tx tx(final Class<Tx> txClass) {
         throw new UnsupportedOperationException("This Graph does not support multiple transaction types - use tx() instead");
     }
 
@@ -316,7 +316,7 @@ public interface Graph extends AutoCloseable, Host {
      * functionality is replaced by the `io` step of {@link GraphTraversalSource}.
      */
     @Deprecated
-    public default <I extends Io> I io(final Io.Builder<I> builder) {
+    default <I extends Io> I io(final Io.Builder<I> builder) {
         return (I) builder.graph(this).create();
     }
 
@@ -326,7 +326,7 @@ public interface Graph extends AutoCloseable, Host {
      *
      * @return The variables associated with this graph
      */
-    public Variables variables();
+    Variables variables();
 
     /**
      * Get the {@code Configuration} associated with the construction of this graph. Whatever configuration was passed
@@ -334,45 +334,45 @@ public interface Graph extends AutoCloseable, Host {
      *
      * @return the configuration used during graph construction.
      */
-    public Configuration configuration();
+    Configuration configuration();
 
     /**
      * Graph variables are a set of key/value pairs associated with the graph. The keys are String and the values
      * are Objects.
      */
-    public interface Variables {
+    interface Variables {
 
         /**
          * Keys set for the available variables.
          */
-        public Set<String> keys();
+        Set<String> keys();
 
         /**
          * Gets a variable.
          */
-        public <R> Optional<R> get(final String key);
+        <R> Optional<R> get(final String key);
 
         /**
          * Sets a variable.
          */
-        public void set(final String key, Object value);
+        void set(final String key, Object value);
 
         /**
          * Removes a variable.
          */
-        public void remove(final String key);
+        void remove(final String key);
 
         /**
          * Gets the variables of the {@link Graph} as a {@code Map}.
          */
-        public default Map<String, Object> asMap() {
+        default Map<String, Object> asMap() {
             final Map<String, Object> map = keys().stream()
                     .map(key -> Pair.with(key, get(key).get()))
                     .collect(Collectors.toMap(Pair::getValue0, Pair::getValue1));
             return Collections.unmodifiableMap(map);
         }
 
-        public static class Exceptions {
+        class Exceptions {
 
             private Exceptions() {
             }
@@ -403,7 +403,7 @@ public interface Graph extends AutoCloseable, Host {
     /**
      * Gets the {@link Features} exposed by the underlying {@code Graph} implementation.
      */
-    public default Features features() {
+    default Features features() {
         return new Features() {
         };
     }
@@ -421,12 +421,12 @@ public interface Graph extends AutoCloseable, Host {
      * TinkerPop core code to determine what operations may be appropriately executed which will have impact on
      * features utilized by users.
      */
-    public interface Features {
+    interface Features {
 
         /**
          * Gets the features related to "graph" operation.
          */
-        public default GraphFeatures graph() {
+        default GraphFeatures graph() {
             return new GraphFeatures() {
             };
         }
@@ -434,7 +434,7 @@ public interface Graph extends AutoCloseable, Host {
         /**
          * Gets the features related to "vertex" operation.
          */
-        public default VertexFeatures vertex() {
+        default VertexFeatures vertex() {
             return new VertexFeatures() {
             };
         }
@@ -442,7 +442,7 @@ public interface Graph extends AutoCloseable, Host {
         /**
          * Gets the features related to "edge" operation.
          */
-        public default EdgeFeatures edge() {
+        default EdgeFeatures edge() {
             return new EdgeFeatures() {
             };
         }
@@ -450,20 +450,21 @@ public interface Graph extends AutoCloseable, Host {
         /**
          * Features specific to a operations of a "graph".
          */
-        public interface GraphFeatures extends FeatureSet {
-            public static final String FEATURE_COMPUTER = "Computer";
-            public static final String FEATURE_TRANSACTIONS = "Transactions";
-            public static final String FEATURE_PERSISTENCE = "Persistence";
-            public static final String FEATURE_THREADED_TRANSACTIONS = "ThreadedTransactions";
-            public static final String FEATURE_CONCURRENT_ACCESS = "ConcurrentAccess";
-            public static final String FEATURE_IO_READ = "IoRead";
-            public static final String FEATURE_IO_WRITE = "IoWrite";
+        interface GraphFeatures extends FeatureSet {
+            String FEATURE_COMPUTER = "Computer";
+            String FEATURE_TRANSACTIONS = "Transactions";
+            String FEATURE_PERSISTENCE = "Persistence";
+            String FEATURE_THREADED_TRANSACTIONS = "ThreadedTransactions";
+            String FEATURE_CONCURRENT_ACCESS = "ConcurrentAccess";
+            String FEATURE_IO_READ = "IoRead";
+            String FEATURE_IO_WRITE = "IoWrite";
+            String FEATURE_ORDERABILITY_SEMANTICS = "OrderabilitySemantics";
 
             /**
              * Determines if the {@code Graph} implementation supports {@link GraphComputer} based processing.
              */
             @FeatureDescriptor(name = FEATURE_COMPUTER)
-            public default boolean supportsComputer() {
+            default boolean supportsComputer() {
                 return true;
             }
 
@@ -474,7 +475,7 @@ public interface Graph extends AutoCloseable, Host {
              * TinkerGraph does not support this feature as it is a pure in-sideEffects graph.
              */
             @FeatureDescriptor(name = FEATURE_PERSISTENCE)
-            public default boolean supportsPersistence() {
+            default boolean supportsPersistence() {
                 return true;
             }
 
@@ -486,7 +487,7 @@ public interface Graph extends AutoCloseable, Host {
              * multiple instances to operate on the same database.
              */
             @FeatureDescriptor(name = FEATURE_CONCURRENT_ACCESS)
-            public default boolean supportsConcurrentAccess() {
+            default boolean supportsConcurrentAccess() {
                 return true;
             }
 
@@ -494,7 +495,7 @@ public interface Graph extends AutoCloseable, Host {
              * Determines if the {@code Graph} implementations supports transactions.
              */
             @FeatureDescriptor(name = FEATURE_TRANSACTIONS)
-            public default boolean supportsTransactions() {
+            default boolean supportsTransactions() {
                 return true;
             }
 
@@ -503,7 +504,7 @@ public interface Graph extends AutoCloseable, Host {
              * to be executed across multiple threads via {@link Transaction#createThreadedTx()}.
              */
             @FeatureDescriptor(name = FEATURE_THREADED_TRANSACTIONS)
-            public default boolean supportsThreadedTransactions() {
+            default boolean supportsThreadedTransactions() {
                 return true;
             }
 
@@ -515,7 +516,7 @@ public interface Graph extends AutoCloseable, Host {
              * {@code HadoopGraph} don't accept direct mutations but can still do reads from that {@code io()} step.
              */
             @FeatureDescriptor(name = FEATURE_IO_READ)
-            public default boolean supportsIoRead() {
+            default boolean supportsIoRead() {
                 return true;
             }
 
@@ -526,14 +527,23 @@ public interface Graph extends AutoCloseable, Host {
              * {@code HadoopGraph} will use a different approach to handle writes.
              */
             @FeatureDescriptor(name = FEATURE_IO_WRITE)
-            public default boolean supportsIoWrite() {
+            default boolean supportsIoWrite() {
+                return true;
+            }
+
+            /**
+             * Determines if the {@code Graph} implementation supports total universal orderability per the Gremlin
+             * orderability semantics.
+             */
+            @FeatureDescriptor(name = FEATURE_ORDERABILITY_SEMANTICS)
+            default boolean supportsOrderabilitySemantics() {
                 return true;
             }
 
             /**
              * Gets the features related to "graph sideEffects" operation.
              */
-            public default VariableFeatures variables() {
+            default VariableFeatures variables() {
                 return new VariableFeatures() {
                 };
             }
@@ -542,13 +552,13 @@ public interface Graph extends AutoCloseable, Host {
         /**
          * Features that are related to {@link Vertex} operations.
          */
-        public interface VertexFeatures extends ElementFeatures {
-            public static final String FEATURE_ADD_VERTICES = "AddVertices";
-            public static final String FEATURE_MULTI_PROPERTIES = "MultiProperties";
-            public static final String FEATURE_DUPLICATE_MULTI_PROPERTIES = "DuplicateMultiProperties";
-            public static final String FEATURE_META_PROPERTIES = "MetaProperties";
-            public static final String FEATURE_REMOVE_VERTICES = "RemoveVertices";
-            public static final String FEATURE_UPSERT = "Upsert";
+        interface VertexFeatures extends ElementFeatures {
+            String FEATURE_ADD_VERTICES = "AddVertices";
+            String FEATURE_MULTI_PROPERTIES = "MultiProperties";
+            String FEATURE_DUPLICATE_MULTI_PROPERTIES = "DuplicateMultiProperties";
+            String FEATURE_META_PROPERTIES = "MetaProperties";
+            String FEATURE_REMOVE_VERTICES = "RemoveVertices";
+            String FEATURE_UPSERT = "Upsert";
 
             /**
              * Gets the {@link VertexProperty.Cardinality} for a key.  By default, this method will return
@@ -561,7 +571,7 @@ public interface Graph extends AutoCloseable, Host {
              * hint on the actual cardinality. Generally speaking it is likely best to drop down to the API of the
              * {@link Graph} implementation for any schema related queries.
              */
-            public default VertexProperty.Cardinality getCardinality(final String key) {
+            default VertexProperty.Cardinality getCardinality(final String key) {
                 return VertexProperty.Cardinality.list;
             }
 
@@ -569,7 +579,7 @@ public interface Graph extends AutoCloseable, Host {
              * Determines if a {@link Vertex} can be added to the {@code Graph}.
              */
             @FeatureDescriptor(name = FEATURE_ADD_VERTICES)
-            public default boolean supportsAddVertices() {
+            default boolean supportsAddVertices() {
                 return true;
             }
 
@@ -577,7 +587,7 @@ public interface Graph extends AutoCloseable, Host {
              * Determines if a {@link Vertex} can be removed from the {@code Graph}.
              */
             @FeatureDescriptor(name = FEATURE_REMOVE_VERTICES)
-            public default boolean supportsRemoveVertices() {
+            default boolean supportsRemoveVertices() {
                 return true;
             }
 
@@ -585,7 +595,7 @@ public interface Graph extends AutoCloseable, Host {
              * Determines if a {@link Vertex} can support multiple properties with the same key.
              */
             @FeatureDescriptor(name = FEATURE_MULTI_PROPERTIES)
-            public default boolean supportsMultiProperties() {
+            default boolean supportsMultiProperties() {
                 return true;
             }
 
@@ -595,7 +605,7 @@ public interface Graph extends AutoCloseable, Host {
              * just returns what {@link #supportsMultiProperties()} returns.
              */
             @FeatureDescriptor(name = FEATURE_DUPLICATE_MULTI_PROPERTIES)
-            public default boolean supportsDuplicateMultiProperties() {
+            default boolean supportsDuplicateMultiProperties() {
                 return supportsMultiProperties();
             }
 
@@ -605,7 +615,7 @@ public interface Graph extends AutoCloseable, Host {
              * properties.
              */
             @FeatureDescriptor(name = FEATURE_META_PROPERTIES)
-            public default boolean supportsMetaProperties() {
+            default boolean supportsMetaProperties() {
                 return true;
             }
 
@@ -619,14 +629,14 @@ public interface Graph extends AutoCloseable, Host {
              * a vertex and should therefore resort to their own body of tests to validate this feature.
              */
             @FeatureDescriptor(name = FEATURE_UPSERT)
-            public default boolean supportsUpsert() {
+            default boolean supportsUpsert() {
                 return false;
             }
 
             /**
              * Gets features related to "properties" on a {@link Vertex}.
              */
-            public default VertexPropertyFeatures properties() {
+            default VertexPropertyFeatures properties() {
                 return new VertexPropertyFeatures() {
                 };
             }
@@ -635,16 +645,16 @@ public interface Graph extends AutoCloseable, Host {
         /**
          * Features that are related to {@link Edge} operations.
          */
-        public interface EdgeFeatures extends ElementFeatures {
-            public static final String FEATURE_ADD_EDGES = "AddEdges";
-            public static final String FEATURE_REMOVE_EDGES = "RemoveEdges";
-            public static final String FEATURE_UPSERT = "Upsert";
+        interface EdgeFeatures extends ElementFeatures {
+            String FEATURE_ADD_EDGES = "AddEdges";
+            String FEATURE_REMOVE_EDGES = "RemoveEdges";
+            String FEATURE_UPSERT = "Upsert";
 
             /**
              * Determines if an {@link Edge} can be added to a {@code Vertex}.
              */
             @FeatureDescriptor(name = FEATURE_ADD_EDGES)
-            public default boolean supportsAddEdges() {
+            default boolean supportsAddEdges() {
                 return true;
             }
 
@@ -652,7 +662,7 @@ public interface Graph extends AutoCloseable, Host {
              * Determines if an {@link Edge} can be removed from a {@code Vertex}.
              */
             @FeatureDescriptor(name = FEATURE_REMOVE_EDGES)
-            public default boolean supportsRemoveEdges() {
+            default boolean supportsRemoveEdges() {
                 return true;
             }
 
@@ -667,14 +677,14 @@ public interface Graph extends AutoCloseable, Host {
              * feature.
              */
             @FeatureDescriptor(name = FEATURE_UPSERT)
-            public default boolean supportsUpsert() {
+            default boolean supportsUpsert() {
                 return false;
             }
 
             /**
              * Gets features related to "properties" on an {@link Edge}.
              */
-            public default EdgePropertyFeatures properties() {
+            default EdgePropertyFeatures properties() {
                 return new EdgePropertyFeatures() {
                 };
             }
@@ -683,16 +693,16 @@ public interface Graph extends AutoCloseable, Host {
         /**
          * Features that are related to {@link Element} objects.  This is a base interface.
          */
-        public interface ElementFeatures extends FeatureSet {
-            public static final String FEATURE_USER_SUPPLIED_IDS = "UserSuppliedIds";
-            public static final String FEATURE_NUMERIC_IDS = "NumericIds";
-            public static final String FEATURE_STRING_IDS = "StringIds";
-            public static final String FEATURE_UUID_IDS = "UuidIds";
-            public static final String FEATURE_CUSTOM_IDS = "CustomIds";
-            public static final String FEATURE_ANY_IDS = "AnyIds";
-            public static final String FEATURE_ADD_PROPERTY = "AddProperty";
-            public static final String FEATURE_REMOVE_PROPERTY = "RemoveProperty";
-            public static final String FEATURE_NULL_PROPERTY_VALUES = "NullPropertyValues";
+        interface ElementFeatures extends FeatureSet {
+            String FEATURE_USER_SUPPLIED_IDS = "UserSuppliedIds";
+            String FEATURE_NUMERIC_IDS = "NumericIds";
+            String FEATURE_STRING_IDS = "StringIds";
+            String FEATURE_UUID_IDS = "UuidIds";
+            String FEATURE_CUSTOM_IDS = "CustomIds";
+            String FEATURE_ANY_IDS = "AnyIds";
+            String FEATURE_ADD_PROPERTY = "AddProperty";
+            String FEATURE_REMOVE_PROPERTY = "RemoveProperty";
+            String FEATURE_NULL_PROPERTY_VALUES = "NullPropertyValues";
 
             /**
              * Determines if an {@link Element} allows properties with {@code null} property values. In the event that
@@ -700,7 +710,7 @@ public interface Graph extends AutoCloseable, Host {
              * the property.
              */
             @FeatureDescriptor(name = FEATURE_NULL_PROPERTY_VALUES)
-            public default boolean supportsNullPropertyValues() {
+            default boolean supportsNullPropertyValues() {
                 return true;
             }
 
@@ -709,7 +719,7 @@ public interface Graph extends AutoCloseable, Host {
              * supporting "data types" and refers to support of calls to {@link Element#property(String, Object)}.
              */
             @FeatureDescriptor(name = FEATURE_ADD_PROPERTY)
-            public default boolean supportsAddProperty() {
+            default boolean supportsAddProperty() {
                 return true;
             }
 
@@ -717,7 +727,7 @@ public interface Graph extends AutoCloseable, Host {
              * Determines if an {@link Element} allows properties to be removed.
              */
             @FeatureDescriptor(name = FEATURE_REMOVE_PROPERTY)
-            public default boolean supportsRemoveProperty() {
+            default boolean supportsRemoveProperty() {
                 return true;
             }
 
@@ -729,7 +739,7 @@ public interface Graph extends AutoCloseable, Host {
              * is assumed to be an identifier data type that the {@link Graph} will accept.
              */
             @FeatureDescriptor(name = FEATURE_USER_SUPPLIED_IDS)
-            public default boolean supportsUserSuppliedIds() {
+            default boolean supportsUserSuppliedIds() {
                 return true;
             }
 
@@ -742,7 +752,7 @@ public interface Graph extends AutoCloseable, Host {
              * Gremlin Test Suite.
              */
             @FeatureDescriptor(name = FEATURE_NUMERIC_IDS)
-            public default boolean supportsNumericIds() {
+            default boolean supportsNumericIds() {
                 return true;
             }
 
@@ -755,7 +765,7 @@ public interface Graph extends AutoCloseable, Host {
              * Gremlin Test Suite.
              */
             @FeatureDescriptor(name = FEATURE_STRING_IDS)
-            public default boolean supportsStringIds() {
+            default boolean supportsStringIds() {
                 return true;
             }
 
@@ -768,7 +778,7 @@ public interface Graph extends AutoCloseable, Host {
              * Gremlin Test Suite.
              */
             @FeatureDescriptor(name = FEATURE_UUID_IDS)
-            public default boolean supportsUuidIds() {
+            default boolean supportsUuidIds() {
                 return true;
             }
 
@@ -781,7 +791,7 @@ public interface Graph extends AutoCloseable, Host {
              * Gremlin Test Suite.
              */
             @FeatureDescriptor(name = FEATURE_CUSTOM_IDS)
-            public default boolean supportsCustomIds() {
+            default boolean supportsCustomIds() {
                 return true;
             }
 
@@ -795,7 +805,7 @@ public interface Graph extends AutoCloseable, Host {
              * is {@code true}.
              */
             @FeatureDescriptor(name = FEATURE_ANY_IDS)
-            public default boolean supportsAnyIds() {
+            default boolean supportsAnyIds() {
                 return true;
             }
 
@@ -816,7 +826,7 @@ public interface Graph extends AutoCloseable, Host {
              * if any of the other types are supported, they will be typed checked against the class of the supplied
              * identifier.
              */
-            public default boolean willAllowId(final Object id) {
+            default boolean willAllowId(final Object id) {
                 if (!supportsUserSuppliedIds()) return false;
                 if (supportsCustomIds())
                     throw new UnsupportedOperationException("The default implementation is not capable of validating custom ids - please override");
@@ -829,21 +839,21 @@ public interface Graph extends AutoCloseable, Host {
         /**
          * Features that are related to {@link Vertex} {@link Property} objects.
          */
-        public interface VertexPropertyFeatures extends PropertyFeatures {
-            public static final String FEATURE_REMOVE_PROPERTY = "RemoveProperty";
-            public static final String FEATURE_USER_SUPPLIED_IDS = "UserSuppliedIds";
-            public static final String FEATURE_NUMERIC_IDS = "NumericIds";
-            public static final String FEATURE_STRING_IDS = "StringIds";
-            public static final String FEATURE_UUID_IDS = "UuidIds";
-            public static final String FEATURE_CUSTOM_IDS = "CustomIds";
-            public static final String FEATURE_ANY_IDS = "AnyIds";
-            public static final String FEATURE_NULL_PROPERTY_VALUES = "NullPropertyValues";
+        interface VertexPropertyFeatures extends PropertyFeatures {
+            String FEATURE_REMOVE_PROPERTY = "RemoveProperty";
+            String FEATURE_USER_SUPPLIED_IDS = "UserSuppliedIds";
+            String FEATURE_NUMERIC_IDS = "NumericIds";
+            String FEATURE_STRING_IDS = "StringIds";
+            String FEATURE_UUID_IDS = "UuidIds";
+            String FEATURE_CUSTOM_IDS = "CustomIds";
+            String FEATURE_ANY_IDS = "AnyIds";
+            String FEATURE_NULL_PROPERTY_VALUES = "NullPropertyValues";
 
             /**
              * Determines if meta-properties allow for {@code null} property values.
              */
             @FeatureDescriptor(name = FEATURE_NULL_PROPERTY_VALUES)
-            public default boolean supportsNullPropertyValues() {
+            default boolean supportsNullPropertyValues() {
                 return true;
             }
 
@@ -851,7 +861,7 @@ public interface Graph extends AutoCloseable, Host {
              * Determines if a {@link VertexProperty} allows properties to be removed.
              */
             @FeatureDescriptor(name = FEATURE_REMOVE_PROPERTY)
-            public default boolean supportsRemoveProperty() {
+            default boolean supportsRemoveProperty() {
                 return true;
             }
 
@@ -859,7 +869,7 @@ public interface Graph extends AutoCloseable, Host {
              * Determines if a {@link VertexProperty} allows an identifier to be assigned to it.
              */
             @FeatureDescriptor(name = FEATURE_USER_SUPPLIED_IDS)
-            public default boolean supportsUserSuppliedIds() {
+            default boolean supportsUserSuppliedIds() {
                 return true;
             }
 
@@ -867,7 +877,7 @@ public interface Graph extends AutoCloseable, Host {
              * Determines if an {@link VertexProperty} has numeric identifiers as their internal representation.
              */
             @FeatureDescriptor(name = FEATURE_NUMERIC_IDS)
-            public default boolean supportsNumericIds() {
+            default boolean supportsNumericIds() {
                 return true;
             }
 
@@ -875,7 +885,7 @@ public interface Graph extends AutoCloseable, Host {
              * Determines if an {@link VertexProperty} has string identifiers as their internal representation.
              */
             @FeatureDescriptor(name = FEATURE_STRING_IDS)
-            public default boolean supportsStringIds() {
+            default boolean supportsStringIds() {
                 return true;
             }
 
@@ -883,7 +893,7 @@ public interface Graph extends AutoCloseable, Host {
              * Determines if an {@link VertexProperty} has UUID identifiers as their internal representation.
              */
             @FeatureDescriptor(name = FEATURE_UUID_IDS)
-            public default boolean supportsUuidIds() {
+            default boolean supportsUuidIds() {
                 return true;
             }
 
@@ -891,7 +901,7 @@ public interface Graph extends AutoCloseable, Host {
              * Determines if an {@link VertexProperty} has a specific custom object as their internal representation.
              */
             @FeatureDescriptor(name = FEATURE_CUSTOM_IDS)
-            public default boolean supportsCustomIds() {
+            default boolean supportsCustomIds() {
                 return true;
             }
 
@@ -900,7 +910,7 @@ public interface Graph extends AutoCloseable, Host {
              * setting can only return true if {@link #supportsUserSuppliedIds()} is true.
              */
             @FeatureDescriptor(name = FEATURE_ANY_IDS)
-            public default boolean supportsAnyIds() {
+            default boolean supportsAnyIds() {
                 return true;
             }
 
@@ -921,7 +931,7 @@ public interface Graph extends AutoCloseable, Host {
              * if any of the other types are supported, they will be typed checked against the class of the supplied
              * identifier.
              */
-            public default boolean willAllowId(final Object id) {
+            default boolean willAllowId(final Object id) {
                 if (!supportsUserSuppliedIds()) return false;
                 if (supportsCustomIds())
                     throw new UnsupportedOperationException("The default implementation is not capable of validating custom ids - please override");
@@ -934,14 +944,14 @@ public interface Graph extends AutoCloseable, Host {
         /**
          * Features that are related to {@link Edge} {@link Property} objects.
          */
-        public interface EdgePropertyFeatures extends PropertyFeatures {
+        interface EdgePropertyFeatures extends PropertyFeatures {
         }
 
         /**
          * A base interface for {@link Edge} or {@link Vertex} {@link Property} features.
          */
-        public interface PropertyFeatures extends DataTypeFeatures {
-            public static final String FEATURE_PROPERTIES = "Properties";
+        interface PropertyFeatures extends DataTypeFeatures {
+            String FEATURE_PROPERTIES = "Properties";
 
             /**
              * Determines if an {@link Element} allows for the processing of at least one data type defined by the
@@ -949,7 +959,7 @@ public interface Graph extends AutoCloseable, Host {
              * features on {@link PropertyFeatures} is true then this value must be true.
              */
             @FeatureDescriptor(name = FEATURE_PROPERTIES)
-            public default boolean supportsProperties() {
+            default boolean supportsProperties() {
                 return supportsBooleanValues() || supportsByteValues() || supportsDoubleValues() || supportsFloatValues()
                         || supportsIntegerValues() || supportsLongValues() || supportsMapValues()
                         || supportsMixedListValues() || supportsSerializableValues()
@@ -962,14 +972,14 @@ public interface Graph extends AutoCloseable, Host {
         /**
          * Features for {@link Graph.Variables}.
          */
-        public interface VariableFeatures extends DataTypeFeatures {
-            public static final String FEATURE_VARIABLES = "Variables";
+        interface VariableFeatures extends DataTypeFeatures {
+            String FEATURE_VARIABLES = "Variables";
 
             /**
              * If any of the features on {@link VariableFeatures} is {@code true} then this value must be {@code true}.
              */
             @FeatureDescriptor(name = FEATURE_VARIABLES)
-            public default boolean supportsVariables() {
+            default boolean supportsVariables() {
                 return supportsBooleanValues() || supportsByteValues() || supportsDoubleValues() || supportsFloatValues()
                         || supportsIntegerValues() || supportsLongValues() || supportsMapValues()
                         || supportsMixedListValues() || supportsSerializableValues()
@@ -982,31 +992,31 @@ public interface Graph extends AutoCloseable, Host {
         /**
          * Base interface for features that relate to supporting different data types.
          */
-        public interface DataTypeFeatures extends FeatureSet {
-            public static final String FEATURE_BOOLEAN_VALUES = "BooleanValues";
-            public static final String FEATURE_BYTE_VALUES = "ByteValues";
-            public static final String FEATURE_DOUBLE_VALUES = "DoubleValues";
-            public static final String FEATURE_FLOAT_VALUES = "FloatValues";
-            public static final String FEATURE_INTEGER_VALUES = "IntegerValues";
-            public static final String FEATURE_LONG_VALUES = "LongValues";
-            public static final String FEATURE_MAP_VALUES = "MapValues";
-            public static final String FEATURE_MIXED_LIST_VALUES = "MixedListValues";
-            public static final String FEATURE_BOOLEAN_ARRAY_VALUES = "BooleanArrayValues";
-            public static final String FEATURE_BYTE_ARRAY_VALUES = "ByteArrayValues";
-            public static final String FEATURE_DOUBLE_ARRAY_VALUES = "DoubleArrayValues";
-            public static final String FEATURE_FLOAT_ARRAY_VALUES = "FloatArrayValues";
-            public static final String FEATURE_INTEGER_ARRAY_VALUES = "IntegerArrayValues";
-            public static final String FEATURE_LONG_ARRAY_VALUES = "LongArrayValues";
-            public static final String FEATURE_SERIALIZABLE_VALUES = "SerializableValues";
-            public static final String FEATURE_STRING_ARRAY_VALUES = "StringArrayValues";
-            public static final String FEATURE_STRING_VALUES = "StringValues";
-            public static final String FEATURE_UNIFORM_LIST_VALUES = "UniformListValues";
+        interface DataTypeFeatures extends FeatureSet {
+            String FEATURE_BOOLEAN_VALUES = "BooleanValues";
+            String FEATURE_BYTE_VALUES = "ByteValues";
+            String FEATURE_DOUBLE_VALUES = "DoubleValues";
+            String FEATURE_FLOAT_VALUES = "FloatValues";
+            String FEATURE_INTEGER_VALUES = "IntegerValues";
+            String FEATURE_LONG_VALUES = "LongValues";
+            String FEATURE_MAP_VALUES = "MapValues";
+            String FEATURE_MIXED_LIST_VALUES = "MixedListValues";
+            String FEATURE_BOOLEAN_ARRAY_VALUES = "BooleanArrayValues";
+            String FEATURE_BYTE_ARRAY_VALUES = "ByteArrayValues";
+            String FEATURE_DOUBLE_ARRAY_VALUES = "DoubleArrayValues";
+            String FEATURE_FLOAT_ARRAY_VALUES = "FloatArrayValues";
+            String FEATURE_INTEGER_ARRAY_VALUES = "IntegerArrayValues";
+            String FEATURE_LONG_ARRAY_VALUES = "LongArrayValues";
+            String FEATURE_SERIALIZABLE_VALUES = "SerializableValues";
+            String FEATURE_STRING_ARRAY_VALUES = "StringArrayValues";
+            String FEATURE_STRING_VALUES = "StringValues";
+            String FEATURE_UNIFORM_LIST_VALUES = "UniformListValues";
 
             /**
              * Supports setting of a boolean value.
              */
             @FeatureDescriptor(name = FEATURE_BOOLEAN_VALUES)
-            public default boolean supportsBooleanValues() {
+            default boolean supportsBooleanValues() {
                 return true;
             }
 
@@ -1014,7 +1024,7 @@ public interface Graph extends AutoCloseable, Host {
              * Supports setting of a byte value.
              */
             @FeatureDescriptor(name = FEATURE_BYTE_VALUES)
-            public default boolean supportsByteValues() {
+            default boolean supportsByteValues() {
                 return true;
             }
 
@@ -1022,7 +1032,7 @@ public interface Graph extends AutoCloseable, Host {
              * Supports setting of a double value.
              */
             @FeatureDescriptor(name = FEATURE_DOUBLE_VALUES)
-            public default boolean supportsDoubleValues() {
+            default boolean supportsDoubleValues() {
                 return true;
             }
 
@@ -1030,7 +1040,7 @@ public interface Graph extends AutoCloseable, Host {
              * Supports setting of a float value.
              */
             @FeatureDescriptor(name = FEATURE_FLOAT_VALUES)
-            public default boolean supportsFloatValues() {
+            default boolean supportsFloatValues() {
                 return true;
             }
 
@@ -1038,7 +1048,7 @@ public interface Graph extends AutoCloseable, Host {
              * Supports setting of a integer value.
              */
             @FeatureDescriptor(name = FEATURE_INTEGER_VALUES)
-            public default boolean supportsIntegerValues() {
+            default boolean supportsIntegerValues() {
                 return true;
             }
 
@@ -1046,7 +1056,7 @@ public interface Graph extends AutoCloseable, Host {
              * Supports setting of a long value.
              */
             @FeatureDescriptor(name = FEATURE_LONG_VALUES)
-            public default boolean supportsLongValues() {
+            default boolean supportsLongValues() {
                 return true;
             }
 
@@ -1055,7 +1065,7 @@ public interface Graph extends AutoCloseable, Host {
              * arbitrary serializable values that may or may not be defined as a feature itself.
              */
             @FeatureDescriptor(name = FEATURE_MAP_VALUES)
-            public default boolean supportsMapValues() {
+            default boolean supportsMapValues() {
                 return true;
             }
 
@@ -1067,7 +1077,7 @@ public interface Graph extends AutoCloseable, Host {
              * @see #supportsMixedListValues()
              */
             @FeatureDescriptor(name = FEATURE_MIXED_LIST_VALUES)
-            public default boolean supportsMixedListValues() {
+            default boolean supportsMixedListValues() {
                 return true;
             }
 
@@ -1075,7 +1085,7 @@ public interface Graph extends AutoCloseable, Host {
              * Supports setting of an array of boolean values.
              */
             @FeatureDescriptor(name = FEATURE_BOOLEAN_ARRAY_VALUES)
-            public default boolean supportsBooleanArrayValues() {
+            default boolean supportsBooleanArrayValues() {
                 return true;
             }
 
@@ -1083,7 +1093,7 @@ public interface Graph extends AutoCloseable, Host {
              * Supports setting of an array of byte values.
              */
             @FeatureDescriptor(name = FEATURE_BYTE_ARRAY_VALUES)
-            public default boolean supportsByteArrayValues() {
+            default boolean supportsByteArrayValues() {
                 return true;
             }
 
@@ -1091,7 +1101,7 @@ public interface Graph extends AutoCloseable, Host {
              * Supports setting of an array of double values.
              */
             @FeatureDescriptor(name = FEATURE_DOUBLE_ARRAY_VALUES)
-            public default boolean supportsDoubleArrayValues() {
+            default boolean supportsDoubleArrayValues() {
                 return true;
             }
 
@@ -1099,7 +1109,7 @@ public interface Graph extends AutoCloseable, Host {
              * Supports setting of an array of float values.
              */
             @FeatureDescriptor(name = FEATURE_FLOAT_ARRAY_VALUES)
-            public default boolean supportsFloatArrayValues() {
+            default boolean supportsFloatArrayValues() {
                 return true;
             }
 
@@ -1107,7 +1117,7 @@ public interface Graph extends AutoCloseable, Host {
              * Supports setting of an array of integer values.
              */
             @FeatureDescriptor(name = FEATURE_INTEGER_ARRAY_VALUES)
-            public default boolean supportsIntegerArrayValues() {
+            default boolean supportsIntegerArrayValues() {
                 return true;
             }
 
@@ -1115,7 +1125,7 @@ public interface Graph extends AutoCloseable, Host {
              * Supports setting of an array of string values.
              */
             @FeatureDescriptor(name = FEATURE_STRING_ARRAY_VALUES)
-            public default boolean supportsStringArrayValues() {
+            default boolean supportsStringArrayValues() {
                 return true;
             }
 
@@ -1123,7 +1133,7 @@ public interface Graph extends AutoCloseable, Host {
              * Supports setting of an array of long values.
              */
             @FeatureDescriptor(name = FEATURE_LONG_ARRAY_VALUES)
-            public default boolean supportsLongArrayValues() {
+            default boolean supportsLongArrayValues() {
                 return true;
             }
 
@@ -1131,7 +1141,7 @@ public interface Graph extends AutoCloseable, Host {
              * Supports setting of a Java serializable value.
              */
             @FeatureDescriptor(name = FEATURE_SERIALIZABLE_VALUES)
-            public default boolean supportsSerializableValues() {
+            default boolean supportsSerializableValues() {
                 return true;
             }
 
@@ -1139,7 +1149,7 @@ public interface Graph extends AutoCloseable, Host {
              * Supports setting of a string value.
              */
             @FeatureDescriptor(name = FEATURE_STRING_VALUES)
-            public default boolean supportsStringValues() {
+            default boolean supportsStringValues() {
                 return true;
             }
 
@@ -1151,7 +1161,7 @@ public interface Graph extends AutoCloseable, Host {
              * @see #supportsMixedListValues()
              */
             @FeatureDescriptor(name = FEATURE_UNIFORM_LIST_VALUES)
-            public default boolean supportsUniformListValues() {
+            default boolean supportsUniformListValues() {
                 return true;
             }
         }
@@ -1159,7 +1169,7 @@ public interface Graph extends AutoCloseable, Host {
         /**
          * A marker interface to identify any set of Features. There is no need to implement this interface.
          */
-        public interface FeatureSet {
+        interface FeatureSet {
         }
 
         /**
@@ -1196,7 +1206,7 @@ public interface Graph extends AutoCloseable, Host {
     /**
      * Common exceptions to use with a graph.
      */
-    public static class Exceptions {
+    class Exceptions {
 
         private static final boolean debug = Boolean.parseBoolean(java.lang.System.getenv().getOrDefault("gremlin.structure.debug", "false"));
 
@@ -1241,18 +1251,18 @@ public interface Graph extends AutoCloseable, Host {
     @Target(ElementType.TYPE)
     @Repeatable(OptIns.class)
     @Inherited
-    public @interface OptIn {
-        public static String SUITE_STRUCTURE_STANDARD = "org.apache.tinkerpop.gremlin.structure.StructureStandardSuite";
-        public static String SUITE_STRUCTURE_INTEGRATE = "org.apache.tinkerpop.gremlin.structure.StructureIntegrateSuite";
-        public static String SUITE_PROCESS_COMPUTER = "org.apache.tinkerpop.gremlin.process.ProcessComputerSuite";
-        public static String SUITE_PROCESS_STANDARD = "org.apache.tinkerpop.gremlin.process.ProcessStandardSuite";
-        public static String SUITE_PROCESS_LIMITED_COMPUTER = "org.apache.tinkerpop.gremlin.process.ProcessLimitedComputerSuite";
-        public static String SUITE_PROCESS_LIMITED_STANDARD = "org.apache.tinkerpop.gremlin.process.ProcessLimitedStandardSuite";
+    @interface OptIn {
+        String SUITE_STRUCTURE_STANDARD = "org.apache.tinkerpop.gremlin.structure.StructureStandardSuite";
+        String SUITE_STRUCTURE_INTEGRATE = "org.apache.tinkerpop.gremlin.structure.StructureIntegrateSuite";
+        String SUITE_PROCESS_COMPUTER = "org.apache.tinkerpop.gremlin.process.ProcessComputerSuite";
+        String SUITE_PROCESS_STANDARD = "org.apache.tinkerpop.gremlin.process.ProcessStandardSuite";
+        String SUITE_PROCESS_LIMITED_COMPUTER = "org.apache.tinkerpop.gremlin.process.ProcessLimitedComputerSuite";
+        String SUITE_PROCESS_LIMITED_STANDARD = "org.apache.tinkerpop.gremlin.process.ProcessLimitedStandardSuite";
 
         /**
          * The test suite class to opt in to.
          */
-        public String value();
+        String value();
     }
 
     /**
@@ -1262,7 +1272,7 @@ public interface Graph extends AutoCloseable, Host {
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.TYPE)
     @Inherited
-    public @interface OptIns {
+    @interface OptIns {
         OptIn[] value();
     }
 
@@ -1273,29 +1283,29 @@ public interface Graph extends AutoCloseable, Host {
     @Target(ElementType.TYPE)
     @Repeatable(OptOuts.class)
     @Inherited
-    public @interface OptOut {
+    @interface OptOut {
         /**
          * The test class to opt out of. This may be set to a base class of a test as in the case of the Gremlin
          * process class of tests from which Gremlin flavors extend.  If the actual test class is an inner class
          * of then use a "$" as a separator between the outer class and inner class.
          */
-        public String test();
+        String test();
 
         /**
          * The specific name of the test method to opt out of or asterisk to opt out of all methods in a
          * {@link #test}.
          */
-        public String method();
+        String method();
 
         /**
          * The reason the implementation is opting out of this test.
          */
-        public String reason();
+        String reason();
 
         /**
          * For parameterized tests specify the name of the test itself without its "square brackets".
          */
-        public String specific() default "";
+        String specific() default "";
 
         /**
          * The list of {@link GraphComputer} implementations by class name that a test should opt-out from using (i.e. other
@@ -1304,7 +1314,7 @@ public interface Graph extends AutoCloseable, Host {
          * default, an empty array is assigned and it is thus assumed that all computers are excluded when an
          * {@code OptOut} annotation is used, therefore this value must be overridden to be more specific.
          */
-        public String[] computers() default {};
+        String[] computers() default {};
 
     }
 
@@ -1315,7 +1325,7 @@ public interface Graph extends AutoCloseable, Host {
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.TYPE)
     @Inherited
-    public @interface OptOuts {
+    @interface OptOuts {
         OptOut[] value();
     }
 }
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/OrderabilityComparator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/OrderabilityComparator.java
new file mode 100644
index 0000000..e1e3d07
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/OrderabilityComparator.java
@@ -0,0 +1,189 @@
+/*
+ * 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.util;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Element;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * An implementation of the Comparability/Orderability semantics as defined in the Apache TinkerPop Provider
+ * documentation.
+ *
+ * @author Mike Personick
+ */
+public class OrderabilityComparator implements Comparator<Object> {
+
+    public static final Comparator<Object> INSTANCE = Comparator.comparing(
+            // first transform (strip Traverser layer)
+            OrderabilityComparator::transform,
+                    // then handle nulls
+                    Comparator.nullsFirst(
+                            // then consider orderability
+                            new OrderabilityComparator()));
+
+    /**
+     * Boolean, Date, String, UUID.
+     */
+    private static final Comparator<Comparable> naturalOrderComparator = Comparator.naturalOrder();
+
+    /**
+     * This comparator does not provide a stable order for numerics because of type promotion equivalence semantics.
+     */
+    private static final Comparator<Number> numberComparator = (f,s) -> NumberHelper.compare(f, s);
+
+    /**
+     * Sort Vertex, Edge, VertexProperty by id.
+     */
+    private static final Comparator<Element> elementComparator =
+            Comparator.comparing(Element::id, INSTANCE);
+
+    /**
+     * Sort Property first by key, then by value.
+     */
+    private static final Comparator<Property> propertyComparator =
+            Comparator.<Property,Object>comparing(Property::key, INSTANCE).thenComparing(Property::value, INSTANCE);
+
+    /**
+     * Sort List, Set, Path, and Map element-by-element in the order presented by their natural iterator.
+     */
+    private static final Comparator<Iterable> iteratableComparator = (f, s) -> {
+        final Iterator fi = f.iterator();
+        final Iterator si = s.iterator();
+
+        while (fi.hasNext() && si.hasNext()) {
+            final int i = INSTANCE.compare(fi.next(), si.next());
+            if (i != 0) {
+                return i;
+            }
+        }
+
+        return fi.hasNext() ? 1 : si.hasNext() ? -1 : 0;
+    };
+
+    /**
+     * Sort Map by entry-set.
+     */
+    private static final Comparator<Map> mapComparator =
+            Comparator.comparing(Map::entrySet, iteratableComparator);
+
+    /**
+     * Sort Map.Entry first by key, then by value.
+     */
+    private static final Comparator<Map.Entry> entryComparator =
+            Comparator.<Map.Entry,Object>comparing(Map.Entry::getKey, INSTANCE).thenComparing(Map.Entry::getValue, INSTANCE);
+
+    /**
+     * Sort unknown types first by classname, then by natural toString().
+     */
+    private static final Comparator<Object> unknownTypeComparator =
+            Comparator.comparing(f -> f.getClass().getName()).thenComparing(Object::toString);
+
+    /**
+     * The typespace, along with their priorities and the comparators used to compare within each type.
+     */
+    private enum Type {
+        Boolean         (Boolean.class,        0,  naturalOrderComparator),
+        Number          (Number.class,         1,  numberComparator),
+        Date            (Date.class,           2,  naturalOrderComparator),
+        String          (String.class,         3,  naturalOrderComparator),
+        UUID            (UUID.class,           4,  naturalOrderComparator),
+        Vertex          (Vertex.class,         5,  elementComparator),
+        Edge            (Edge.class,           6,  elementComparator),
+        VertexProperty  (VertexProperty.class, 7,  elementComparator),
+        Property        (Property.class,       8,  propertyComparator),
+        Path            (Path.class,           9,  iteratableComparator),
+        Set             (Set.class,            10, iteratableComparator),
+        List            (List.class,           11, iteratableComparator),
+        Map             (Map.class,            12, mapComparator),
+        MapEntry        (Map.Entry.class,      13, entryComparator),
+        Unknown         (Object.class,         14, unknownTypeComparator);
+
+        /**
+         * Lookup by instanceof semantics (not class equality). Current implementation will return first enum value
+         * that matches the object's type.
+         */
+        public static Type type(final Object o) {
+            final Type[] types = Type.values();
+            for (int i = 0; i < types.length; i++) {
+                if (types[i].type.isInstance(o)) {
+                    return types[i];
+                }
+            }
+            return Unknown;
+        }
+
+        Type(Class type, int priority, Comparator comparator) {
+            this.type = type;
+            this.priority = priority;
+            this.comparator = comparator;
+        }
+        private final Class type;
+        private final int priority;
+        private final Comparator comparator;
+    }
+
+    /**
+     * Strip the Traverser layer and convert Enum to string.
+     */
+    private static Object transform(Object o) {
+        // we want to sort the underlying object contained by the traverser
+        if (o instanceof Traverser)
+            o = ((Traverser) o).get();
+        // need to convert enum to string representations for comparison or else you can get cast exceptions.
+        // this typically happens when sorting local on the keys of maps that contain T
+        if (o instanceof Enum)
+            o = ((Enum) o).name();
+        return o;
+    }
+
+    private OrderabilityComparator() {}
+
+    /**
+     * Compare two non-null Gremlin value objects per the Comparability/Orderability semantics.
+     */
+    @Override
+    public int compare(final Object f, final Object s) {
+        final Type ft = Type.type(f);
+        /*
+         * Do a quick check to catch very common cases - class equality or both numerics. Even if these are false we
+         * could still be dealing with the same type (e.g. different implementation of Vertex), but let the type lookup
+         * method handle that.
+         */
+        final Type st = f.getClass().equals(s.getClass()) || (f instanceof Number && s instanceof Number) ?
+                        ft : Type.type(s);
+
+        return ft != st ? ft.priority - st.priority : ft.comparator.compare(f, s);
+    }
+
+}
diff --git a/gremlin-dotnet/build/generate.groovy b/gremlin-dotnet/build/generate.groovy
index d6f8c60..0d6e8ba 100644
--- a/gremlin-dotnet/build/generate.groovy
+++ b/gremlin-dotnet/build/generate.groovy
@@ -134,32 +134,14 @@ radishGremlinFile.withWriter('UTF-8') { Writer writer ->
                 def t = gremlinItty.next()[0]
                 writer.write("(g,p) =>")
                 writer.write(translator.translate(t.bytecode).script.
-                        replace("xx1", "p[\"xx1\"]").
-                        replace("xx2", "p[\"xx2\"]").
-                        replace("xx3", "p[\"xx3\"]").
-                        replace("v1", "(Vertex) p[\"v1\"]").
-                        replace("v2", "(Vertex) p[\"v2\"]").
-                        replace("v3", "(Vertex) p[\"v3\"]").
-                        replace("v4", "(Vertex) p[\"v4\"]").
-                        replace("v5", "(Vertex) p[\"v5\"]").
-                        replace("v6", "(Vertex) p[\"v6\"]").
-                        replace("vid1", "p[\"vid1\"]").
-                        replace("vid2", "p[\"vid2\"]").
-                        replace("vid3", "p[\"vid3\"]").
-                        replace("vid4", "p[\"vid4\"]").
-                        replace("vid5", "p[\"vid5\"]").
-                        replace("vid6", "p[\"vid6\"]").
-                        replace("e7", "p[\"e7\"]").
-                        replace("e10", "p[\"e10\"]").
-                        replace("e11", "p[\"e11\"]").
-                        replace("eid7", "p[\"eid7\"]").
-                        replace("eid10", "p[\"eid10\"]").
-                        replace("eid11", "p[\"eid11\"]").
-                        replace("l1", "(IFunction) p[\"l1\"]").
-                        replace("l2", "(IFunction) p[\"l2\"]").
-                        replace("pred1", "(IPredicate) p[\"pred1\"]").
-                        replace("c1", "(IComparator) p[\"c1\"]").
-                        replace("c2", "(IComparator) p[\"c2\"]"))
+                        replaceAll("xx([0-9]+)", "p[\"xx\$1\"]").
+                        replaceAll("v([0-9]+)", "(Vertex) p[\"v\$1\"]").
+                        replaceAll("vid([0-9]+)", "p[\"vid\$1\"]").
+                        replaceAll("e([0-9]+)", "p[\"e\$1\"]").
+                        replaceAll("eid([0-9]+)", "p[\"eid\$1\"]").
+                        replaceAll("l([0-9]+)", "(IFunction) p[\"l\$1\"]").
+                        replaceAll("pred([0-9]+)", "(IPredicate) p[\"pred\$1\"]").
+                        replaceAll("c([0-9]+)", "(IComparator) p[\"c\$1\"]"))
                 if (gremlinItty.hasNext())
                     writer.write(', ')
                 else
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
index be8973c..03b429a 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
@@ -70,7 +70,9 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                 {@"m\[(.+)\]", ToMap},
                 {@"c\[(.+)\]", ToLambda},
                 {@"t\[(.+)\]", ToT},
-                {"null", (_, __) => null}
+                {"null", (_, __) => null},
+                {"true", (_, __) => true},
+                {"false", (_, __) => false}
             }.ToDictionary(kv => new Regex("^" + kv.Key + "$", RegexOptions.Compiled), kv => kv.Value);
 
         private static readonly IDictionary<char, Func<string, object>> NumericParsers =
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
index f7c03d8..a8d8fe0 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/GherkinTestRunner.cs
@@ -85,6 +85,8 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                     "g_V_hasXperson_name_markoX_bothXknowsX_groupCount_byXvaluesXnameX_foldX",
                     IgnoreReason.ArrayKeysInMapNotAssertingInGherkin
                 },
+                {"g_V_properties_order", IgnoreReason.VertexPropertyNotSupportedInGherkin},
+                {"g_V_properties_order_id", IgnoreReason.VertexPropertyNotSupportedInGherkin},
             };
 
         private static class Keywords
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
index 332bbe4..021f484 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -748,6 +748,25 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"Primitives_Number_eqXfloatX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Unfold<object>().Where(__.Is(p["xx2"]))}}, 
                {"Primitives_Number_eqXdoubleX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Unfold<object>().Where(__.Is(p["xx2"]))}}, 
                {"Primitives_Number_eqXbigdecimalX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx1"]).Unfold<object>().Where(__.Is(p["xx2"]))}}, 
+               {"g_V_values_order", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>().Order()}}, 
+               {"g_V_properties_order", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Properties<object>().Order()}}, 
+               {"g_V_properties_order_id", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Properties<object>().Order().Id()}}, 
+               {"g_E_properties_order_value", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E().Properties<object>().Order().Value<object>()}}, 
+               {"g_E_properties_order_byXdescX_value", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.E().Properties<object>().Order().By(Order.Desc).Value<object>()}}, 
+               {"g_inject_order", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx8"],p["xx7"],p["xx10"],p["xx4"],p["xx9"],p["xx12"],p["xx1"],p["xx5"],p["xx11"],p["xx6"],p["xx3"],p["xx2"]).Order()}}, 
+               {"g_inject_order_byXdescX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject(p["xx8"],p["xx7"],p["xx10"],p["xx4"],p["xx9"],p["xx12"],p["xx1"],p["xx5"],p["xx11"],p["xx6"],p["xx3"],p["xx2"]).Order().By(Order.Desc)}}, 
+               {"g_V_out_out_order_byXascX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Order().By(Order.Asc)}}, 
+               {"g_V_out_out_order_byXdescX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Order().By(Order.Desc)}}, 
+               {"g_V_out_out_asXheadX_path_order_byXascX_selectXheadX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().As("head").Path().Order().By(Order.Asc).Select<object>("head")}}, 
+               {"g_V_out_out_asXheadX_path_order_byXdescX_selectXheadX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().As("head").Path().Order().By(Order.Desc).Select<object>("head")}}, 
+               {"g_V_out_outE_order_byXascX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().OutE().Order().By(Order.Asc)}}, 
+               {"g_V_out_outE_order_byXdescX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().OutE().Order().By(Order.Desc)}}, 
+               {"g_V_out_outE_asXheadX_path_order_byXascX_selectXheadX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().OutE().As("head").Path().Order().By(Order.Asc).Select<object>("head")}}, 
+               {"g_V_out_outE_asXheadX_path_order_byXdescX_selectXheadX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().OutE().As("head").Path().Order().By(Order.Desc).Select<object>("head")}}, 
+               {"g_V_out_out_properties_asXheadX_path_order_byXascX_selectXheadX_value", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Properties<object>().As("head").Path().Order().By(Order.Asc).Select<object>("head").Value<object>()}}, 
+               {"g_V_out_out_properties_asXheadX_path_order_byXdescX_selectXheadX_value", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Properties<object>().As("head").Path().Order().By(Order.Desc).Select<object>("head").Value<object>()}}, 
+               {"g_V_out_out_values_asXheadX_path_order_byXascX_selectXheadX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Values<object>().As("head").Path().Order().By(Order.Asc).Select<object>("head")}}, 
+               {"g_V_out_out_values_asXheadX_path_order_byXdescX_selectXheadX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Out().Out().Values<object>().As("head").Path().Order().By(Order.Desc).Select<object>("head")}}, 
                {"g_V_valueXnameX_aggregateXxX_capXxX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Aggregate("x").Cap<object>("x")}}, 
                {"g_V_valueXnameX_aggregateXglobal_xX_capXxX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Values<object>("name").Aggregate(Scope.Global,"x").Cap<object>("x")}}, 
                {"g_V_aggregateXxX_byXnameX_capXxX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.V().Aggregate("x").By("name").Cap<object>("x")}}, 
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs
index e025e2f..2fa881b 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/IgnoreException.cs
@@ -65,6 +65,11 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
         /// <summary>
         /// The GLV suite does not test against a graph that has null property values enabled.
         /// </summary>
-        NullPropertyValuesNotSupportedOnTestGraph
+        NullPropertyValuesNotSupportedOnTestGraph,
+
+        /// <summary>
+        /// Need a Gherkin parser for VertexProperty results: https://issues.apache.org/jira/browse/TINKERPOP-2686
+        /// </summary>
+        VertexPropertyNotSupportedInGherkin
     }
 }
\ No newline at end of file
diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslatorProvider.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslatorProvider.java
index c44f35c..de9e1ee 100644
--- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslatorProvider.java
+++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslatorProvider.java
@@ -215,6 +215,10 @@ import org.apache.tinkerpop.gremlin.util.TinkerGraphProvider;
         test = "org.apache.tinkerpop.gremlin.process.traversal.step.map.WriteTest",
         method = "*",
         reason = "read and write tests don't translate locally well because of calling iterate() inside read()/write() add a none()")
+@Graph.OptOut(
+        test = "org.apache.tinkerpop.gremlin.process.traversal.step.OrderabilityTest",
+        method = "g_inject_order_with_unknown_type",
+        reason = "GroovyTranslator only supports known Gremlin types")
 public class GroovyTranslatorProvider extends TinkerGraphProvider {
     @Override
     public GraphTraversalSource traversal(final Graph graph) {
diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/ParameterizedGroovyTranslatorProvider.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/ParameterizedGroovyTranslatorProvider.java
index 9cc0d84..fb4ef31 100644
--- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/ParameterizedGroovyTranslatorProvider.java
+++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/ParameterizedGroovyTranslatorProvider.java
@@ -215,6 +215,10 @@ import org.apache.tinkerpop.gremlin.util.TinkerGraphProvider;
         test = "org.apache.tinkerpop.gremlin.process.traversal.step.map.WriteTest",
         method = "*",
         reason = "read and write tests don't translate locally well because of calling iterate() inside read()/write() add a none()")
+@Graph.OptOut(
+        test = "org.apache.tinkerpop.gremlin.process.traversal.step.OrderabilityTest",
+        method = "g_inject_order_with_unknown_type",
+        reason = "GroovyTranslator only supports known Gremlin types")
 public class ParameterizedGroovyTranslatorProvider extends TinkerGraphProvider {
     @Override
     public GraphTraversalSource traversal(final Graph graph) {
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
index 90f63ff..d500feb 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/feature-steps.js
@@ -42,6 +42,7 @@ const direction = traversalModule.direction;
 const mapAsObject = false;
 
 const parsers = [
+  [ 'vp\\[(.+)\\]', toVertexProperty ],
   [ 'd\\[(.*)\\]\\.[bsilfdmn]', toNumeric ],
   [ 'v\\[(.+)\\]', toVertex ],
   [ 'v\\[(.+)\\]\\.id', toVertexId ],
@@ -62,6 +63,7 @@ const ignoreReason = {
   nullKeysInMapNotSupportedWell: "Javascript does not nicely support 'null' as a key in Map instances",
   setNotSupported: "There is no Set support in gremlin-javascript",
   needsFurtherInvestigation: '',
+  vertexPropertyNotSupported: "Need a parser for vertex properties",
 };
 
 const ignoredScenarios = {
@@ -71,7 +73,8 @@ const ignoredScenarios = {
   'g_withStrategiesXProductiveByStrategyX_V_groupCount_byXageX': new IgnoreError(ignoreReason.nullKeysInMapNotSupportedWell),
   'g_V_shortestPath_edgesIncluded': new IgnoreError(ignoreReason.needsFurtherInvestigation),
   'g_V_shortestPath_edgesIncluded_edgesXoutEX': new IgnoreError(ignoreReason.needsFurtherInvestigation),
-  'g_V_shortestpath': new IgnoreError(ignoreReason.needsFurtherInvestigation)
+  'g_V_shortestpath': new IgnoreError(ignoreReason.needsFurtherInvestigation),
+  'g_V_properties_order': new IgnoreError(ignoreReason.vertexPropertyNotSupported)
 };
 
 Given(/^the (.+) graph$/, function (graphName) {
@@ -241,6 +244,10 @@ function parseValue(stringValue) {
 
   if(stringValue === "null")
     return null;
+  if(stringValue === "true")
+    return true;
+  if(stringValue === "false")
+    return false;
 
   let extractedValue = null;
   let parser = null;
@@ -298,6 +305,16 @@ function toPath(value) {
   return new Path(new Array(0), parts.map(x => parseValue.call(this, x)));
 }
 
+/*
+ * TODO Implement me.
+ *   vp[vertexName-propkey->propVal]
+ *   vertexName and propKey are simple strings, propVal must be parsed (e.g. numeric property values)
+ *   https://issues.apache.org/jira/browse/TINKERPOP-2686
+ */
+function toVertexProperty(triplet) {
+  return null;
+}
+
 function toT(value) {
   return t[value];
 }
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
index 3557f44..0a452a6 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
@@ -736,6 +736,25 @@ const gremlins = {
     Primitives_Number_eqXfloatX: [function({g, xx1, xx2}) { return g.inject(xx1).unfold().where(__.is(xx2)) }], 
     Primitives_Number_eqXdoubleX: [function({g, xx1, xx2}) { return g.inject(xx1).unfold().where(__.is(xx2)) }], 
     Primitives_Number_eqXbigdecimalX: [function({g, xx1, xx2}) { return g.inject(xx1).unfold().where(__.is(xx2)) }], 
+    g_V_values_order: [function({g}) { return g.V().values().order() }], 
+    g_V_properties_order: [function({g}) { return g.V().properties().order() }], 
+    g_V_properties_order_id: [function({g}) { return g.V().properties().order().id() }], 
+    g_E_properties_order_value: [function({g}) { return g.E().properties().order().value() }], 
+    g_E_properties_order_byXdescX_value: [function({g}) { return g.E().properties().order().by(Order.desc).value() }], 
+    g_inject_order: [function({g, xx1, xx3, xx2, xx5, xx4, xx7, xx10, xx6, xx9, xx11, xx8, xx12}) { return g.inject(xx8,xx7,xx10,xx4,xx9,xx12,xx1,xx5,xx11,xx6,xx3,xx2).order() }], 
+    g_inject_order_byXdescX: [function({g, xx1, xx3, xx2, xx5, xx4, xx7, xx10, xx6, xx9, xx11, xx8, xx12}) { return g.inject(xx8,xx7,xx10,xx4,xx9,xx12,xx1,xx5,xx11,xx6,xx3,xx2).order().by(Order.desc) }], 
+    g_V_out_out_order_byXascX: [function({g}) { return g.V().out().out().order().by(Order.asc) }], 
+    g_V_out_out_order_byXdescX: [function({g}) { return g.V().out().out().order().by(Order.desc) }], 
+    g_V_out_out_asXheadX_path_order_byXascX_selectXheadX: [function({g}) { return g.V().out().out().as("head").path().order().by(Order.asc).select("head") }], 
+    g_V_out_out_asXheadX_path_order_byXdescX_selectXheadX: [function({g}) { return g.V().out().out().as("head").path().order().by(Order.desc).select("head") }], 
+    g_V_out_outE_order_byXascX: [function({g}) { return g.V().out().outE().order().by(Order.asc) }], 
+    g_V_out_outE_order_byXdescX: [function({g}) { return g.V().out().outE().order().by(Order.desc) }], 
+    g_V_out_outE_asXheadX_path_order_byXascX_selectXheadX: [function({g}) { return g.V().out().outE().as("head").path().order().by(Order.asc).select("head") }], 
+    g_V_out_outE_asXheadX_path_order_byXdescX_selectXheadX: [function({g}) { return g.V().out().outE().as("head").path().order().by(Order.desc).select("head") }], 
+    g_V_out_out_properties_asXheadX_path_order_byXascX_selectXheadX_value: [function({g}) { return g.V().out().out().properties().as("head").path().order().by(Order.asc).select("head").value() }], 
+    g_V_out_out_properties_asXheadX_path_order_byXdescX_selectXheadX_value: [function({g}) { return g.V().out().out().properties().as("head").path().order().by(Order.desc).select("head").value() }], 
+    g_V_out_out_values_asXheadX_path_order_byXascX_selectXheadX: [function({g}) { return g.V().out().out().values().as("head").path().order().by(Order.asc).select("head") }], 
+    g_V_out_out_values_asXheadX_path_order_byXdescX_selectXheadX: [function({g}) { return g.V().out().out().values().as("head").path().order().by(Order.desc).select("head") }], 
     g_V_valueXnameX_aggregateXxX_capXxX: [function({g}) { return g.V().values("name").aggregate("x").cap("x") }], 
     g_V_valueXnameX_aggregateXglobal_xX_capXxX: [function({g}) { return g.V().values("name").aggregate(Scope.global,"x").cap("x") }], 
     g_V_aggregateXxX_byXnameX_capXxX: [function({g}) { return g.V().aggregate("x").by("name").cap("x") }], 
diff --git a/gremlin-language/src/main/java/org/apache/tinkerpop/gremlin/language/corpus/FeatureReader.java b/gremlin-language/src/main/java/org/apache/tinkerpop/gremlin/language/corpus/FeatureReader.java
index f97bc27..abd11e4 100644
--- a/gremlin-language/src/main/java/org/apache/tinkerpop/gremlin/language/corpus/FeatureReader.java
+++ b/gremlin-language/src/main/java/org/apache/tinkerpop/gremlin/language/corpus/FeatureReader.java
@@ -137,8 +137,11 @@ public class FeatureReader {
     }
 
     private static String applyParametersToGremlin(String currentGremlin, Map<String, String> parameters) {
-        for (Map.Entry<String,String> kv : parameters.entrySet()) {
-            currentGremlin = currentGremlin.replace(kv.getKey(), kv.getValue());
+        // sort from longest to shortest so that xx1 does not replace xx10
+        final List<String> paramNames = new ArrayList<>(parameters.keySet());
+        paramNames.sort((a,b) -> b.length() - a.length());
+        for (String k : paramNames) {
+            currentGremlin = currentGremlin.replace(k, parameters.get(k));
         }
         return currentGremlin;
     }
@@ -155,6 +158,9 @@ public class FeatureReader {
             }
         }
 
-        throw new IllegalStateException(String.format("Could not match the parameter [%s] pattern of %s", k, v));
+        // this should be a raw string if it didn't match anything - suppose it could be a syntax error in the
+        // test too, but i guess the test would fail so perhaps ok to just assume it's raw string value that
+        // didn't need a transform by default
+        return v;
     }
 }
diff --git a/gremlin-language/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/ReferenceGrammarTest.java b/gremlin-language/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/ReferenceGrammarTest.java
index 46e0467..b3d3f29 100644
--- a/gremlin-language/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/ReferenceGrammarTest.java
+++ b/gremlin-language/src/test/java/org/apache/tinkerpop/gremlin/language/grammar/ReferenceGrammarTest.java
@@ -71,6 +71,10 @@ public class ReferenceGrammarTest extends AbstractGrammarTest {
         add(Pair.with(Pattern.compile("c\\[(.*)\\]"), (k,v) -> k.equals("c1") || k.equals("c2") ? "Order.desc" : "__.identity()"));  // closure -> Comparator || Traversal
         add(Pair.with(Pattern.compile("s\\[\\]"), (k,v) -> "[]"));  // set -> list
         add(Pair.with(Pattern.compile("s\\[(.*)\\]"), (k,v) -> "[]"));  // set -> list
+        add(Pair.with(Pattern.compile("(null)"), (k,v) -> "null"));
+        add(Pair.with(Pattern.compile("(true)"), (k,v) -> "true"));
+        add(Pair.with(Pattern.compile("(false)"), (k,v) -> "false"));
+
     }};
 
     @Parameterized.Parameters(name = "{0}")
diff --git a/gremlin-python/src/main/python/radish/feature_steps.py b/gremlin-python/src/main/python/radish/feature_steps.py
index a1f76ba..66bfc45 100644
--- a/gremlin-python/src/main/python/radish/feature_steps.py
+++ b/gremlin-python/src/main/python/radish/feature_steps.py
@@ -33,7 +33,7 @@ inV = __.inV
 project = __.project
 tail = __.tail
 
-ignores = []
+ignores = ["g.V().properties().order()"] # need a vertex property parser for result set: https://issues.apache.org/jira/browse/TINKERPOP-2686
 
 
 @given("the {graph_name:w} graph")
@@ -207,6 +207,10 @@ def _convert(val, ctx):
         return Direction[val[2:-1]]
     elif isinstance(val, str) and re.match(r"^null$", val):              # parse null to None
         return None
+    elif isinstance(val, str) and re.match(r"^true$", val):              # parse to boolean
+        return True
+    elif isinstance(val, str) and re.match(r"^false$", val):             # parse to boolean
+        return False
     else:
         return val
 
diff --git a/gremlin-python/src/main/python/radish/gremlin.py b/gremlin-python/src/main/python/radish/gremlin.py
index 4c3d27c..5ec3509 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -721,6 +721,25 @@ world.gremlins = {
     'Primitives_Number_eqXfloatX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).unfold().where(__.is_(xx2)))], 
     'Primitives_Number_eqXdoubleX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).unfold().where(__.is_(xx2)))], 
     'Primitives_Number_eqXbigdecimalX': [(lambda g, xx1=None,xx2=None:g.inject(xx1).unfold().where(__.is_(xx2)))], 
+    'g_V_values_order': [(lambda g:g.V().values().order())], 
+    'g_V_properties_order': [(lambda g:g.V().properties().order())], 
+    'g_V_properties_order_id': [(lambda g:g.V().properties().order().id_())], 
+    'g_E_properties_order_value': [(lambda g:g.E().properties().order().value())], 
+    'g_E_properties_order_byXdescX_value': [(lambda g:g.E().properties().order().by(Order.desc).value())], 
+    'g_inject_order': [(lambda g, xx1=None,xx3=None,xx2=None,xx5=None,xx4=None,xx7=None,xx10=None,xx6=None,xx9=None,xx11=None,xx8=None,xx12=None:g.inject(xx8,xx7,xx10,xx4,xx9,xx12,xx1,xx5,xx11,xx6,xx3,xx2).order())], 
+    'g_inject_order_byXdescX': [(lambda g, xx1=None,xx3=None,xx2=None,xx5=None,xx4=None,xx7=None,xx10=None,xx6=None,xx9=None,xx11=None,xx8=None,xx12=None:g.inject(xx8,xx7,xx10,xx4,xx9,xx12,xx1,xx5,xx11,xx6,xx3,xx2).order().by(Order.desc))], 
+    'g_V_out_out_order_byXascX': [(lambda g:g.V().out().out().order().by(Order.asc))], 
+    'g_V_out_out_order_byXdescX': [(lambda g:g.V().out().out().order().by(Order.desc))], 
+    'g_V_out_out_asXheadX_path_order_byXascX_selectXheadX': [(lambda g:g.V().out().out().as_('head').path().order().by(Order.asc).select('head'))], 
+    'g_V_out_out_asXheadX_path_order_byXdescX_selectXheadX': [(lambda g:g.V().out().out().as_('head').path().order().by(Order.desc).select('head'))], 
+    'g_V_out_outE_order_byXascX': [(lambda g:g.V().out().outE().order().by(Order.asc))], 
+    'g_V_out_outE_order_byXdescX': [(lambda g:g.V().out().outE().order().by(Order.desc))], 
+    'g_V_out_outE_asXheadX_path_order_byXascX_selectXheadX': [(lambda g:g.V().out().outE().as_('head').path().order().by(Order.asc).select('head'))], 
+    'g_V_out_outE_asXheadX_path_order_byXdescX_selectXheadX': [(lambda g:g.V().out().outE().as_('head').path().order().by(Order.desc).select('head'))], 
+    'g_V_out_out_properties_asXheadX_path_order_byXascX_selectXheadX_value': [(lambda g:g.V().out().out().properties().as_('head').path().order().by(Order.asc).select('head').value())], 
+    'g_V_out_out_properties_asXheadX_path_order_byXdescX_selectXheadX_value': [(lambda g:g.V().out().out().properties().as_('head').path().order().by(Order.desc).select('head').value())], 
+    'g_V_out_out_values_asXheadX_path_order_byXascX_selectXheadX': [(lambda g:g.V().out().out().values().as_('head').path().order().by(Order.asc).select('head'))], 
+    'g_V_out_out_values_asXheadX_path_order_byXdescX_selectXheadX': [(lambda g:g.V().out().out().values().as_('head').path().order().by(Order.desc).select('head'))], 
     'g_V_valueXnameX_aggregateXxX_capXxX': [(lambda g:g.V().name.aggregate('x').cap('x'))], 
     'g_V_valueXnameX_aggregateXglobal_xX_capXxX': [(lambda g:g.V().name.aggregate(Scope.global_,'x').cap('x'))], 
     'g_V_aggregateXxX_byXnameX_capXxX': [(lambda g:g.V().aggregate('x').by('name').cap('x'))], 
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/AbstractRemoteGraphProvider.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/AbstractRemoteGraphProvider.java
index 833ddd0..89bb7a0 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/AbstractRemoteGraphProvider.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/AbstractRemoteGraphProvider.java
@@ -206,6 +206,10 @@ import static org.apache.tinkerpop.gremlin.process.remote.RemoteConnection.GREML
         test = "org.apache.tinkerpop.gremlin.process.traversal.step.map.UnfoldTest",
         method = "g_V_valueMap_unfold_mapXkeyX",
         reason = "Tests that include lambdas are not supported by the test suite for remotes")
+@Graph.OptOut(
+        test = "org.apache.tinkerpop.gremlin.process.traversal.step.OrderabilityTest",
+        method = "g_inject_order_with_unknown_type",
+        reason = "Tests that inject a generic Java Object are not supported by the test suite for remotes")
 public abstract class AbstractRemoteGraphProvider extends AbstractGraphProvider implements AutoCloseable {
     private final int AVAILABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();
     private static final Set<Class> IMPLEMENTATION = new HashSet<Class>() {{
diff --git a/gremlin-test/features/semantics/Orderability.feature b/gremlin-test/features/semantics/Orderability.feature
new file mode 100644
index 0000000..f132a3e
--- /dev/null
+++ b/gremlin-test/features/semantics/Orderability.feature
@@ -0,0 +1,355 @@
+# 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.
+
+@StepClassOrderability
+Feature: Orderability
+
+  Scenario: g_V_values_order
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().values().order()
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | d[27].i |
+      | d[29].i |
+      | d[32].i |
+      | d[35].i |
+      | java |
+      | java |
+      | josh |
+      | lop  |
+      | marko |
+      | peter |
+      | ripple |
+      | vadas  |
+
+  @UserSuppliedVertexPropertyIds
+  Scenario: g_V_properties_order
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().properties().order()
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | vp[marko-name->marko] |
+      | vp[marko-age->d[29].i] |
+      | vp[vadas-name->vadas]  |
+      | vp[vadas-age->d[27].i] |
+      | vp[lop-name->lop]  |
+      | vp[lop-lang->java]  |
+      | vp[josh-name->josh]  |
+      | vp[josh-age->d[32].i] |
+      | vp[ripple-name->ripple]  |
+      | vp[ripple-lang->java]  |
+      | vp[peter-name->peter]  |
+      | vp[peter-age->d[35].i] |
+
+  @UserSuppliedVertexPropertyIds
+  Scenario: g_V_properties_order_id
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().properties().order().id()
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | d[0].l |
+      | d[1].l |
+      | d[2].l |
+      | d[3].l |
+      | d[4].l |
+      | d[5].l |
+      | d[6].l |
+      | d[7].l |
+      | d[8].l |
+      | d[9].l |
+      | d[10].l |
+      | d[11].l |
+
+  Scenario: g_E_properties_order_value
+    Given the modern graph
+    And the traversal of
+      """
+      g.E().properties().order().value()
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | d[0.2].d |
+      | d[0.4].d |
+      | d[0.4].d |
+      | d[0.5].d |
+      | d[1.0].d |
+      | d[1.0].d |
+
+  Scenario: g_E_properties_order_byXdescX_value
+    Given the modern graph
+    And the traversal of
+      """
+      g.E().properties().order().by(desc).value()
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | d[1.0].d |
+      | d[1.0].d |
+      | d[0.5].d |
+      | d[0.4].d |
+      | d[0.4].d |
+      | d[0.2].d |
+
+  Scenario: g_inject_order
+    Given the empty graph
+    And using the parameter xx1 defined as "null"
+    And using the parameter xx2 defined as "false"
+    And using the parameter xx3 defined as "true"
+    And using the parameter xx4 defined as "d[1].i"
+    And using the parameter xx5 defined as "d[2.0].d"
+    And using the parameter xx6 defined as "bar"
+    And using the parameter xx7 defined as "foo"
+    And using the parameter xx8 defined as "zzz"
+    And using the parameter xx9 defined as "l[a,b,c]"
+    And using the parameter xx10 defined as "l[a,b,c,d]"
+    And using the parameter xx11 defined as "m[{\"a\":\"a\", \"b\":false, \"c\":\"c\"}]"
+    And using the parameter xx12 defined as "m[{\"a\":\"a\", \"b\":\"b\"}]"
+    # TODO add support for Set, UUID, Date once the framework supports it
+    And the traversal of
+      """
+      g.inject(xx8,xx7,xx10,xx4,xx9,xx12,xx1,xx5,xx11,xx6,xx3,xx2).order()
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | null |
+      | false |
+      | true |
+      | d[1].i |
+      | d[2.0].d |
+      | bar |
+      | foo |
+      | zzz |
+      | l[a,b,c] |
+      | l[a,b,c,d] |
+      | m[{"a":"a", "b":false, "c":"c"}] |
+      | m[{"a":"a", "b":"b"}] |
+
+  Scenario: g_inject_order_byXdescX
+    Given the empty graph
+    And using the parameter xx1 defined as "null"
+    And using the parameter xx2 defined as "false"
+    And using the parameter xx3 defined as "true"
+    And using the parameter xx4 defined as "d[1].i"
+    And using the parameter xx5 defined as "d[2.0].d"
+    And using the parameter xx6 defined as "bar"
+    And using the parameter xx7 defined as "foo"
+    And using the parameter xx8 defined as "zzz"
+    And using the parameter xx9 defined as "l[a,b,c]"
+    And using the parameter xx10 defined as "l[a,b,c,d]"
+    And using the parameter xx11 defined as "m[{\"a\":\"a\", \"b\":false, \"c\":\"c\"}]"
+    And using the parameter xx12 defined as "m[{\"a\":\"a\", \"b\":\"b\"}]"
+    # TODO add support for Set, UUID, Date once the framework supports it
+    And the traversal of
+      """
+      g.inject(xx8,xx7,xx10,xx4,xx9,xx12,xx1,xx5,xx11,xx6,xx3,xx2).order().by(desc)
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | m[{"a":"a", "b":"b"}] |
+      | m[{"a":"a", "b":false, "c":"c"}] |
+      | l[a,b,c,d] |
+      | l[a,b,c] |
+      | zzz |
+      | foo |
+      | bar |
+      | d[2.0].d |
+      | d[1].i |
+      | true |
+      | false |
+      | null |
+
+  @UserSuppliedVertexIds
+  Scenario: g_V_out_out_order_byXascX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().out().order().by(asc)
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | v[lop] |
+      | v[ripple] |
+
+  @UserSuppliedVertexIds
+  Scenario: g_V_out_out_order_byXdescX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().out().order().by(desc)
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | v[ripple] |
+      | v[lop] |
+
+  @UserSuppliedVertexIds
+  Scenario: g_V_out_out_asXheadX_path_order_byXascX_selectXheadX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().out().as("head").path().order().by(asc).select("head")
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | v[lop] |
+      | v[ripple] |
+
+  @UserSuppliedVertexIds
+  Scenario: g_V_out_out_asXheadX_path_order_byXdescX_selectXheadX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().out().as("head").path().order().by(desc).select("head")
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | v[ripple] |
+      | v[lop] |
+
+  @UserSuppliedEdgeIds
+  Scenario: g_V_out_outE_order_byXascX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().outE().order().by(asc)
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | e[josh-created->ripple] |
+      | e[josh-created->lop] |
+
+  @UserSuppliedEdgeIds
+  Scenario: g_V_out_outE_order_byXdescX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().outE().order().by(desc)
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | e[josh-created->lop] |
+      | e[josh-created->ripple] |
+
+  @UserSuppliedEdgeIds
+  Scenario: g_V_out_outE_asXheadX_path_order_byXascX_selectXheadX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().outE().as("head").path().order().by(asc).select("head")
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | e[josh-created->ripple] |
+      | e[josh-created->lop] |
+
+  @UserSuppliedEdgeIds
+  Scenario: g_V_out_outE_asXheadX_path_order_byXdescX_selectXheadX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().outE().as("head").path().order().by(desc).select("head")
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | e[josh-created->lop] |
+      | e[josh-created->ripple] |
+
+  @UserSuppliedVertexIds
+  @UserSuppliedVertexPropertyIds
+  Scenario: g_V_out_out_properties_asXheadX_path_order_byXascX_selectXheadX_value
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().out().properties().as("head").path().order().by(asc).select("head").value()
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | lop |
+      | java |
+      | ripple |
+      | java |
+
+  @UserSuppliedVertexIds
+  @UserSuppliedVertexPropertyIds
+  Scenario: g_V_out_out_properties_asXheadX_path_order_byXdescX_selectXheadX_value
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().out().properties().as("head").path().order().by(desc).select("head").value()
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | java |
+      | ripple |
+      | java |
+      | lop |
+
+  @UserSuppliedVertexIds
+  Scenario: g_V_out_out_values_asXheadX_path_order_byXascX_selectXheadX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().out().values().as("head").path().order().by(asc).select("head")
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | java |
+      | lop |
+      | java |
+      | ripple |
+
+  @UserSuppliedVertexIds
+  Scenario: g_V_out_out_values_asXheadX_path_order_byXdescX_selectXheadX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().out().out().values().as("head").path().order().by(desc).select("head")
+      """
+    When iterated to list
+    Then the result should be ordered
+      | result |
+      | ripple |
+      | java |
+      | lop |
+      | java |
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
index 7fd094b..b8ab47f 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
@@ -220,6 +220,14 @@ public abstract class AbstractGremlinTest {
         return (GraphTraversal<Vertex, VertexProperty<Object>>) graphProvider.traversal(graph).V().has("name", vertexName).properties(vertexPropertyKey);
     }
 
+    public VertexProperty convertToVertexProperty(final String vertexName, final String propertyKey, final Object propertyValue) {
+        return convertToVertexProperty(graph, vertexName, propertyKey).hasValue(propertyValue).toList().get(0);
+    }
+
+    public Edge convertToEdge(final String outVertexName, String edgeLabel, final String inVertexName) {
+        return convertToEdge(graph, outVertexName, edgeLabel, inVertexName);
+    }
+
     public Edge convertToEdge(final Graph graph, final String outVertexName, String edgeLabel, final String inVertexName) {
         return graphProvider.traversal(graph).V().has("name", outVertexName).outE(edgeLabel).as("e").inV().has("name", inVertexName).<Edge>select("e").toList().get(0);
     }
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
index 8976a12..b8021c1 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/features/StepDefinition.java
@@ -38,6 +38,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSo
 import org.apache.tinkerpop.gremlin.structure.Direction;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
 import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
@@ -136,6 +137,8 @@ public final class StepDefinition {
             throw new AssumptionViolatedException("This test uses a Set as a parameter which is not supported by gremlin-language");
         }));
         add(Pair.with(Pattern.compile("(null)"), s -> "null"));
+        add(Pair.with(Pattern.compile("(true)"), s -> "true"));
+        add(Pair.with(Pattern.compile("(false)"), s -> "false"));
     }};
 
     private List<Pair<Pattern, Function<String,Object>>> objectMatcherConverters = new ArrayList<Pair<Pattern, Function<String,Object>>>() {{
@@ -157,6 +160,13 @@ public final class StepDefinition {
         }));
 
         add(Pair.with(Pattern.compile("(null)"), s -> null));
+        add(Pair.with(Pattern.compile("(true)"), s -> true));
+        add(Pair.with(Pattern.compile("(false)"), s -> false));
+
+        /*
+         * TODO FIXME Add same support for other languages (js, python, .net)
+         */
+        add(Pair.with(Pattern.compile("vp\\[(.+)\\]"), s -> getVertexProperty(g, s)));
 
         add(Pair.with(Pattern.compile("p\\[(.*)\\]"), s -> {
             throw new AssumptionViolatedException("This test uses a Path as a parameter which is not supported by gremlin-language");
@@ -458,6 +468,17 @@ public final class StepDefinition {
                    filter(edge -> g.V(edge.inVertex().id()).has("name", t.getValue2()).hasNext()).findFirst().get();
     }
 
+    /**
+     * Reuse edge triplet syntax for VertexProperty: vp[vertexName-key->value]
+     */
+    private VertexProperty getVertexProperty(final GraphTraversalSource g, final String e) {
+        final Triplet<String,String,String> t = getEdgeTriplet(e);
+        return (VertexProperty) g.V().has("name", t.getValue0())
+                                     .properties(t.getValue1())
+                                     .hasValue(convertToObject(t.getValue2()))
+                .tryNext().orElse(null);
+    }
+
     private static Object getEdgeId(final GraphTraversalSource g, final String e) {
         return getEdge(g, e).id();
     }
@@ -468,8 +489,11 @@ public final class StepDefinition {
 
     private String applyParameters(final String docString) {
         String replaced = docString;
-        for (Map.Entry<String, String> kv : stringParameters.entrySet()) {
-            replaced = replaced.replace(kv.getKey(), kv.getValue());
+        // sort from longest to shortest so that xx1 does not replace xx10
+        final List<String> paramNames = new ArrayList<>(stringParameters.keySet());
+        paramNames.sort((a,b) -> b.length() - a.length());
+        for (String k : paramNames) {
+            replaced = replaced.replace(k, stringParameters.get(k));
         }
         return replaced;
     }
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessLimitedStandardSuite.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessLimitedStandardSuite.java
index ddf3280..e9c4602 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessLimitedStandardSuite.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessLimitedStandardSuite.java
@@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.CoreTraversalTest;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.ComplexTest;
+import org.apache.tinkerpop.gremlin.process.traversal.step.OrderabilityTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.BranchTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.ChooseTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.LocalTest;
@@ -139,7 +140,10 @@ public class ProcessLimitedStandardSuite extends AbstractGremlinSuite {
 
             // optimizations
             IncidentToAdjacentStrategyProcessTest.class,
-            EarlyLimitStrategyProcessTest.class
+            EarlyLimitStrategyProcessTest.class,
+
+            // semantics
+            OrderabilityTest.Traversals.class,
     };
 
     /**
@@ -167,4 +171,4 @@ public class ProcessLimitedStandardSuite extends AbstractGremlinSuite {
     public ProcessLimitedStandardSuite(final Class<?> klass, final RunnerBuilder builder, final Class<?>[] testsToExecute) throws InitializationError {
         super(klass, builder, testsToExecute, testsToEnforce, true, TraversalEngine.Type.STANDARD);
     }
-}
+}
\ No newline at end of file
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
index 2f31678..ac8dc99 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
@@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.CoreTraversalTest;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.ComplexTest;
+import org.apache.tinkerpop.gremlin.process.traversal.step.OrderabilityTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.BranchTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.ChooseTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.LocalTest;
@@ -199,7 +200,10 @@ public class ProcessStandardSuite extends AbstractGremlinSuite {
 
             // optimizations
             IncidentToAdjacentStrategyProcessTest.class,
-            EarlyLimitStrategyProcessTest.class
+            EarlyLimitStrategyProcessTest.class,
+
+            // semantics
+            OrderabilityTest.Traversals.class,
     };
 
     /**
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/OrderabilityTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/OrderabilityTest.java
new file mode 100644
index 0000000..33dcb92
--- /dev/null
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/OrderabilityTest.java
@@ -0,0 +1,536 @@
+/*
+ * 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 org.apache.tinkerpop.gremlin.FeatureRequirement;
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
+import org.apache.tinkerpop.gremlin.process.GremlinProcessRunner;
+import org.apache.tinkerpop.gremlin.process.traversal.Order;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
+import static org.apache.tinkerpop.gremlin.structure.Graph.Features.EdgeFeatures;
+import static org.apache.tinkerpop.gremlin.structure.Graph.Features.GraphFeatures;
+import static org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexFeatures;
+import static org.apache.tinkerpop.gremlin.structure.Graph.Features.VertexPropertyFeatures;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@RunWith(GremlinProcessRunner.class)
+public abstract class OrderabilityTest extends AbstractGremlinProcessTest {
+
+    private interface Constants {
+        UUID uuid = UUID.randomUUID();
+        Date date = new Date();
+        List list1 = Arrays.asList(1, 2, 3);
+        List list2 = Arrays.asList(1, 2, 3, 4);
+        Set set1 = new LinkedHashSet(list1);
+        Set set2 = new LinkedHashSet(list2);
+        Map map1 = new LinkedHashMap() {{
+            put(1, 11);
+            put(2, 22);
+            put(3, false);
+            put(4, 44);
+        }};
+        Map map2 = new LinkedHashMap() {{
+            put(1, 11);
+            put(2, 22);
+            put(3, 33);
+        }};
+
+        Object[] unordered = { map2, 1, map1, "foo", null, list1, date, set1, list2, true, uuid, "bar", 2.0, false, set2 };
+    }
+
+    public abstract Traversal<Vertex, Object> get_g_V_values_order();
+
+    public abstract Traversal<Vertex, ? extends Property> get_g_V_properties_order();
+
+    public abstract Traversal<Edge, Object> get_g_E_properties_order_value();
+
+    public abstract Traversal<Edge, Object> get_g_E_properties_order_byXdescX_value();
+
+    public abstract Traversal<Object, Object> get_g_inject_order();
+
+    // order asc by vertex: v[3], v[5]
+    public abstract Traversal<Vertex, Vertex> get_g_V_out_out_order_byXascX();
+
+    // order asc by vertex in path: v[3], v[5]
+    public abstract Traversal<Vertex, Vertex> get_g_V_out_out_asXheadX_path_order_byXascX_selectXheadX();
+
+    // order asc by edge: e[10], v[e11]
+    public abstract Traversal<Vertex, Edge> get_g_V_out_outE_order_byXascX();
+
+    // order asc by edge in path: e[10], e[11]
+    public abstract Traversal<Vertex, Edge> get_g_V_out_outE_asXheadX_path_order_byXascX_selectXheadX();
+
+    // order asc by vertex and then vertex property id in path.
+    public abstract Traversal<Vertex, Object> get_g_V_out_out_properties_asXheadX_path_order_byXascX_selectXheadX_value();
+
+    // order asc by vertex and then vertex property value in path.
+    public abstract Traversal<Vertex, Object> get_g_V_out_out_values_asXheadX_path_order_byXascX_selectXheadX();
+
+    // order desc by vertex: v[3], v[5]
+    public abstract Traversal<Vertex, Vertex> get_g_V_out_out_order_byXdescX();
+
+    // order desc by vertex in path: v[3], v[5]
+    public abstract Traversal<Vertex, Vertex> get_g_V_out_out_asXheadX_path_order_byXdescX_selectXheadX();
+
+    // order desc by edge: e[10], v[e11]
+    public abstract Traversal<Vertex, Edge> get_g_V_out_outE_order_byXdescX();
+
+    // order desc by edge in path: e[10], e[11]
+    public abstract Traversal<Vertex, Edge> get_g_V_out_outE_asXheadX_path_order_byXdescX_selectXheadX();
+
+    // order desc by vertex and then vertex property id in path.
+    public abstract Traversal<Vertex, Object> get_g_V_out_out_properties_asXheadX_path_order_byXdescX_selectXheadX_value();
+
+    // order desc by vertex and then vertex property value in path.
+    public abstract Traversal<Vertex, Object> get_g_V_out_out_values_asXheadX_path_order_byXdescX_selectXheadX();
+
+    /**
+     * Order by property value (mixed types).
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    public void g_V_values_order() {
+        final Traversal<Vertex, Object> traversal = get_g_V_values_order();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                27, 29, 32, 35, "java", "java", "josh", "lop", "marko", "peter", "ripple", "vadas"
+        ), traversal);
+    }
+
+    /**
+     * Order by vertex property (orders by id).
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = VertexPropertyFeatures.FEATURE_USER_SUPPLIED_IDS)
+    public void g_V_properties_order() {
+        final Traversal traversal = get_g_V_properties_order();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                convertToVertexProperty("marko", "name", "marko"),    // vpid = 0
+                convertToVertexProperty("marko", "age", 29),          // vpid = 1
+                convertToVertexProperty("vadas", "name", "vadas"),    // vpid = 2
+                convertToVertexProperty("vadas", "age", 27),          // vpid = 3
+                convertToVertexProperty("lop", "name", "lop"),        // vpid = 4
+                convertToVertexProperty("lop", "lang", "java"),       // vpid = 5
+                convertToVertexProperty("josh", "name", "josh"),      // vpid = 6
+                convertToVertexProperty("josh", "age", 32),           // vpid = 7
+                convertToVertexProperty("ripple", "name", "ripple"),  // vpid = 8
+                convertToVertexProperty("ripple", "lang", "java"),    // vpid = 9
+                convertToVertexProperty("peter", "name", "peter"),    // vpid = 10
+                convertToVertexProperty("peter", "age", 35)           // vpid = 11
+        ), traversal);
+    }
+
+    /**
+     * Order by edge property (orders by key, then value).
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    @FeatureRequirement(featureClass = EdgeFeatures.class, feature = EdgeFeatures.FEATURE_ADD_PROPERTY)
+    public void g_E_properties_order_value() {
+        { // add some more edge properties
+            final AtomicInteger a = new AtomicInteger();
+            g.E().forEachRemaining(e -> e.property("a", a.getAndIncrement()));
+        }
+
+        final Traversal asc = get_g_E_properties_order_value();
+        printTraversalForm(asc);
+        checkOrderedResults(Arrays.asList(
+                0, 1, 2, 3, 4, 5, 0.2, 0.4, 0.4, 0.5, 1.0, 1.0
+        ), asc);
+
+        final Traversal desc = get_g_E_properties_order_byXdescX_value();
+        printTraversalForm(desc);
+        checkOrderedResults(Arrays.asList(
+                1.0, 1.0, 0.5, 0.4, 0.4, 0.2, 5, 4, 3, 2, 1, 0
+        ), desc);
+    }
+
+    /**
+     * Mixed type values including list, set, map, uuid, date, boolean, numeric, string, null.
+     */
+    @Test
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    public void g_inject_order() {
+        final Traversal traversal = get_g_inject_order();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                null,
+                false, true,
+                1, 2.0,
+                Constants.date,
+                "bar", "foo",
+                Constants.uuid,
+                Constants.set1, Constants.set2,
+                Constants.list1, Constants.list2,
+                Constants.map1, Constants.map2
+        ), traversal);
+    }
+
+    /**
+     * More mixed type values including a Java Object (unknown type).
+     */
+    @Test
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    public void g_inject_order_with_unknown_type() {
+        final Object unknown = new Object();
+        final Object[] unordered = new Object[Constants.unordered.length+1];
+        unordered[0] = unknown;
+        System.arraycopy(Constants.unordered, 0, unordered, 1, Constants.unordered.length);
+
+        final Traversal traversal = g.inject(unordered).order();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                null,
+                false, true,
+                1, 2.0,
+                Constants.date,
+                "bar", "foo",
+                Constants.uuid,
+                Constants.set1, Constants.set2,
+                Constants.list1, Constants.list2,
+                Constants.map1, Constants.map2,
+                unknown
+        ), traversal);
+    }
+
+    /**
+     * Order asc by vertex: v[3], v[5]
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    @FeatureRequirement(featureClass = VertexFeatures.class, feature = VertexFeatures.FEATURE_USER_SUPPLIED_IDS)
+    public void g_V_out_out_order_byXascX() {
+        final Traversal traversal = get_g_V_out_out_order_byXascX();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                convertToVertex("lop"),         // vid = 3
+                convertToVertex("ripple")       // vid = 5
+        ), traversal);
+    }
+
+    /**
+     * Order asc by vertex in path: v[3], v[5]
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    @FeatureRequirement(featureClass = VertexFeatures.class, feature = VertexFeatures.FEATURE_USER_SUPPLIED_IDS)
+    public void g_V_out_out_asXheadX_path_order_byXascX_selectXheadX() {
+        final Traversal traversal = get_g_V_out_out_asXheadX_path_order_byXascX_selectXheadX();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                convertToVertex("lop"),         // vid = 3
+                convertToVertex("ripple")       // vid = 5
+        ), traversal);
+    }
+
+    /**
+     * Order asc by edge: e[10], v[e11]
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    @FeatureRequirement(featureClass = EdgeFeatures.class, feature = EdgeFeatures.FEATURE_USER_SUPPLIED_IDS)
+    public void g_V_out_outE_order_byXascX() {
+        final Traversal traversal = get_g_V_out_outE_order_byXascX();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                convertToEdge("josh", "created", "ripple"),      // eid = 10
+                convertToEdge("josh", "created", "lop")          // eid = 11
+        ), traversal);
+    }
+
+    /**
+     * Order asc by edge in path: e[10], e[11]
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    @FeatureRequirement(featureClass = EdgeFeatures.class, feature = EdgeFeatures.FEATURE_USER_SUPPLIED_IDS)
+    public void g_V_out_outE_asXheadX_path_order_byXascX_selectXheadX() {
+        final Traversal traversal = get_g_V_out_outE_asXheadX_path_order_byXascX_selectXheadX();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                convertToEdge("josh", "created", "ripple"),      // eid = 10
+                convertToEdge("josh", "created", "lop")          // eid = 11
+        ), traversal);
+    }
+
+    /**
+     * Order asc by vertex and then vertex property id in path.
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    @FeatureRequirement(featureClass = VertexFeatures.class, feature = VertexFeatures.FEATURE_USER_SUPPLIED_IDS)
+    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = VertexPropertyFeatures.FEATURE_USER_SUPPLIED_IDS)
+    public void g_V_out_out_properties_asXheadX_path_order_byXascX_selectXheadX_value() {
+        final Traversal traversal = get_g_V_out_out_properties_asXheadX_path_order_byXascX_selectXheadX_value();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                "lop",      // vid = 3, vpid = 4
+                "java",     // vid = 3, vpid = 5
+                "ripple",   // vid = 5, vpid = 8
+                "java"      // vid = 5, vpid = 9
+        ), traversal);
+    }
+
+    /**
+     * Order asc by vertex and then vertex property value in path.
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    @FeatureRequirement(featureClass = VertexFeatures.class, feature = VertexFeatures.FEATURE_USER_SUPPLIED_IDS)
+    public void g_V_out_out_values_asXheadX_path_order_byXascX_selectXheadX() {
+        final Traversal traversal = get_g_V_out_out_values_asXheadX_path_order_byXascX_selectXheadX();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                "java",     // vid = 3, val = "java"
+                "lop",      // vid = 3, val = "lop"
+                "java",     // vid = 5, val = "java"
+                "ripple"    // vid = 5, val = "ripple"
+        ), traversal);
+    }
+
+    /**
+     * Order desc by vertex: v[5], v[3]
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    @FeatureRequirement(featureClass = VertexFeatures.class, feature = VertexFeatures.FEATURE_USER_SUPPLIED_IDS)
+    public void g_V_out_out_order_byXdescX() {
+        final Traversal traversal = get_g_V_out_out_order_byXdescX();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                convertToVertex("ripple"),     // vid = 5
+                convertToVertex("lop")         // vid = 3
+        ), traversal);
+    }
+
+    /**
+     * Order desc by vertex in path: v[5], v[3]
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    @FeatureRequirement(featureClass = VertexFeatures.class, feature = VertexFeatures.FEATURE_USER_SUPPLIED_IDS)
+    public void g_V_out_out_asXheadX_path_order_byXdescX_selectXheadX() {
+        final Traversal traversal = get_g_V_out_out_asXheadX_path_order_byXdescX_selectXheadX();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                convertToVertex("ripple"),     // vid = 5
+                convertToVertex("lop")         // vid = 3
+        ), traversal);
+    }
+
+    /**
+     * Order desc by edge: e[11], v[e10]
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    @FeatureRequirement(featureClass = EdgeFeatures.class, feature = EdgeFeatures.FEATURE_USER_SUPPLIED_IDS)
+    public void g_V_out_outE_order_byXdescX() {
+        final Traversal traversal = get_g_V_out_outE_order_byXdescX();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                convertToEdge("josh", "created", "lop"),        // eid = 11
+                convertToEdge("josh", "created", "ripple")      // eid = 10
+        ), traversal);
+    }
+
+    /**
+     * Order desc by edge in path: e[11], e[10]
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    @FeatureRequirement(featureClass = EdgeFeatures.class, feature = EdgeFeatures.FEATURE_USER_SUPPLIED_IDS)
+    public void g_V_out_outE_asXheadX_path_order_byXdescX_selectXheadX() {
+        final Traversal traversal = get_g_V_out_outE_asXheadX_path_order_byXdescX_selectXheadX();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                convertToEdge("josh", "created", "lop"),        // eid = 11
+                convertToEdge("josh", "created", "ripple")      // eid = 10
+        ), traversal);
+    }
+
+    /**
+     * Order desc by vertex and then vertex property id in path.
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    @FeatureRequirement(featureClass = VertexFeatures.class, feature = VertexFeatures.FEATURE_USER_SUPPLIED_IDS)
+    @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = VertexPropertyFeatures.FEATURE_USER_SUPPLIED_IDS)
+    public void g_V_out_out_properties_asXheadX_path_order_byXdescX_selectXheadX_value() {
+        final Traversal traversal = get_g_V_out_out_properties_asXheadX_path_order_byXdescX_selectXheadX_value();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                "java",     // vid = 5, vpid = 9
+                "ripple",   // vid = 5, vpid = 8
+                "java",     // vid = 3, vpid = 5
+                "lop"       // vid = 3, vpid = 4
+        ), traversal);
+    }
+
+    /**
+     * Order desc by vertex and then vertex property value in path.
+     */
+    @Test
+    @LoadGraphWith(MODERN)
+    @FeatureRequirement(featureClass = GraphFeatures.class, feature = GraphFeatures.FEATURE_ORDERABILITY_SEMANTICS)
+    @FeatureRequirement(featureClass = VertexFeatures.class, feature = VertexFeatures.FEATURE_USER_SUPPLIED_IDS)
+    public void g_V_out_out_values_asXheadX_path_order_byXdescX_selectXheadX() {
+        final Traversal traversal = get_g_V_out_out_values_asXheadX_path_order_byXdescX_selectXheadX();
+        printTraversalForm(traversal);
+        checkOrderedResults(Arrays.asList(
+                "ripple",   // vid = 5, val = "ripple"
+                "java",     // vid = 5, val = "java"
+                "lop",      // vid = 3, val = "lop"
+                "java"      // vid = 3, val = "java"
+        ), traversal);
+    }
+
+    public static class Traversals extends OrderabilityTest implements Constants {
+
+        @Override
+        public Traversal<Vertex, Object> get_g_V_values_order() {
+            return g.V().values().order();
+        }
+
+        @Override
+        public Traversal<Vertex, ? extends Property> get_g_V_properties_order() {
+            return g.V().properties().order();
+        }
+
+        @Override
+        public Traversal<Edge, Object> get_g_E_properties_order_value() {
+            return g.E().properties().order().value();
+        }
+
+        @Override
+        public Traversal<Edge, Object> get_g_E_properties_order_byXdescX_value() {
+            return g.E().properties().order().by(Order.desc).value();
+        }
+
+        @Override
+        public Traversal<Object, Object> get_g_inject_order() {
+            return g.inject(unordered).order();
+        }
+
+        // order asc by vertex: v[3], v[5]
+        @Override
+        public Traversal<Vertex, Vertex> get_g_V_out_out_order_byXascX() {
+            return g.V().out().out().order().by(Order.asc);
+        }
+
+        // order asc by vertex in path: v[3], v[5]
+        @Override
+        public Traversal<Vertex, Vertex> get_g_V_out_out_asXheadX_path_order_byXascX_selectXheadX() {
+            return g.V().out().out().as("head").path().order().by(Order.asc).select("head");
+        }
+
+        // order asc by edge: e[10], v[e11]
+        @Override
+        public Traversal<Vertex, Edge> get_g_V_out_outE_order_byXascX() {
+            return g.V().out().outE().order().by(Order.asc);
+        }
+
+        // order asc by edge in path: e[10], e[11]
+        @Override
+        public Traversal<Vertex, Edge> get_g_V_out_outE_asXheadX_path_order_byXascX_selectXheadX() {
+            return g.V().out().outE().as("head").path().order().by(Order.asc).select("head");
+        }
+
+        // order asc by vertex and then vertex property id in path.
+        @Override
+        public Traversal<Vertex, Object> get_g_V_out_out_properties_asXheadX_path_order_byXascX_selectXheadX_value() {
+            return g.V().out().out().properties().as("head").path().order().by(Order.asc).select("head").value();
+        }
+
+        // order asc by vertex and then vertex property value in path.
+        @Override
+        public Traversal<Vertex, Object> get_g_V_out_out_values_asXheadX_path_order_byXascX_selectXheadX() {
+            return g.V().out().out().values().as("head").path().order().by(Order.asc).select("head");
+        }
+
+        // order desc by vertex: v[5], v[3]
+        @Override
+        public Traversal<Vertex, Vertex> get_g_V_out_out_order_byXdescX() {
+            return g.V().out().out().order().by(Order.desc);
+        }
+
+        // order desc by vertex in path: v[5], v[3]
+        @Override
+        public Traversal<Vertex, Vertex> get_g_V_out_out_asXheadX_path_order_byXdescX_selectXheadX() {
+            return g.V().out().out().as("head").path().order().by(Order.desc).select("head");
+        }
+
+        // order desc by edge: e[11], v[e10]
+        @Override
+        public Traversal<Vertex, Edge> get_g_V_out_outE_order_byXdescX() {
+            return g.V().out().outE().order().by(Order.desc);
+        }
+
+        // order desc by edge in path: e[11], e[10]
+        @Override
+        public Traversal<Vertex, Edge> get_g_V_out_outE_asXheadX_path_order_byXdescX_selectXheadX() {
+            return g.V().out().outE().as("head").path().order().by(Order.desc).select("head");
+        }
+
+        // order desc by vertex and then vertex property id in path.
+        @Override
+        public Traversal<Vertex, Object> get_g_V_out_out_properties_asXheadX_path_order_byXdescX_selectXheadX_value() {
+            return g.V().out().out().properties().as("head").path().order().by(Order.desc).select("head").value();
+        }
+
+        // order desc by vertex and then vertex property value in path.
+        @Override
+        public Traversal<Vertex, Object> get_g_V_out_out_values_asXheadX_path_order_byXdescX_selectXheadX() {
+            return g.V().out().out().values().as("head").path().order().by(Order.desc).select("head");
+        }
+
+    }
+}
diff --git a/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/Neo4jGraphFeatureTest.java b/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/Neo4jGraphFeatureTest.java
index f40e95b..7b5c39b 100644
--- a/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/Neo4jGraphFeatureTest.java
+++ b/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/Neo4jGraphFeatureTest.java
@@ -50,7 +50,7 @@ import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData;
 
 @RunWith(Cucumber.class)
 @CucumberOptions(
-        tags = "not @RemoteOnly and not @MultiMetaProperties and not @GraphComputerOnly and not @AllowNullPropertyValues",
+        tags = "not @RemoteOnly and not @MultiMetaProperties and not @GraphComputerOnly and not @AllowNullPropertyValues and not @UserSuppliedVertexPropertyIds and not @UserSuppliedEdgeIds and not @UserSuppliedVertexIds",
         glue = { "org.apache.tinkerpop.gremlin.features" },
         objectFactory = GuiceFactory.class,
         features = { "../gremlin-test/features" },
diff --git a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerFactory.java b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerFactory.java
index 61cc7a8..df939ec 100644
--- a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerFactory.java
+++ b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerFactory.java
@@ -87,12 +87,25 @@ public final class TinkerFactory {
      * Generate the graph in {@link #createModern()} into an existing graph.
      */
     public static void generateModern(final TinkerGraph g) {
-        final Vertex marko = g.addVertex(T.id, 1, T.label, "person", "name", "marko", "age", 29);
-        final Vertex vadas = g.addVertex(T.id, 2, T.label, "person", "name", "vadas", "age", 27);
-        final Vertex lop = g.addVertex(T.id, 3, T.label, "software", "name", "lop", "lang", "java");
-        final Vertex josh = g.addVertex(T.id, 4, T.label, "person", "name", "josh", "age", 32);
-        final Vertex ripple = g.addVertex(T.id, 5, T.label, "software", "name", "ripple", "lang", "java");
-        final Vertex peter = g.addVertex(T.id, 6, T.label, "person", "name", "peter", "age", 35);
+        final Vertex marko = g.addVertex(T.id, 1, T.label, "person");
+        marko.property("name", "marko", T.id, 0);
+        marko.property("age", 29, T.id, 1);
+        final Vertex vadas = g.addVertex(T.id, 2, T.label, "person");
+        vadas.property("name", "vadas", T.id, 2);
+        vadas.property("age", 27, T.id, 3);
+        final Vertex lop = g.addVertex(T.id, 3, T.label, "software");
+        lop.property("name", "lop", T.id, 4);
+        lop.property("lang", "java", T.id, 5);
+        final Vertex josh = g.addVertex(T.id, 4, T.label, "person");
+        josh.property("name", "josh", T.id, 6);
+        josh.property("age", 32, T.id, 7);
+        final Vertex ripple = g.addVertex(T.id, 5, T.label, "software");
+        ripple.property("name", "ripple", T.id, 8);
+        ripple.property("lang", "java", T.id, 9);
+        final Vertex peter = g.addVertex(T.id, 6, T.label, "person");
+        peter.property("name", "peter", T.id, 10);
+        peter.property("age", 35, T.id, 11);
+
         marko.addEdge("knows", vadas, T.id, 7, "weight", 0.5d);
         marko.addEdge("knows", josh, T.id, 8, "weight", 1.0d);
         marko.addEdge("created", lop, T.id, 9, "weight", 0.4d);
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/io/graphson/AbstractTinkerGraphGraphSONTranslatorProvider.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/io/graphson/AbstractTinkerGraphGraphSONTranslatorProvider.java
index 7f4ebe8..2cbf137 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/io/graphson/AbstractTinkerGraphGraphSONTranslatorProvider.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/io/graphson/AbstractTinkerGraphGraphSONTranslatorProvider.java
@@ -242,12 +242,24 @@ public abstract class AbstractTinkerGraphGraphSONTranslatorProvider extends Tink
         return g.withStrategies(new TranslationStrategy(g, new GraphSONTranslator<>(JavaTranslator.of(g), version), true));
     }
 
+    @Graph.OptOut(
+            test = "org.apache.tinkerpop.gremlin.process.traversal.step.OrderabilityTest",
+            method = "g_inject_order",
+            reason = "GraphSONv2 does not properly round trip Maps and Sets")
+    @Graph.OptOut(
+            test = "org.apache.tinkerpop.gremlin.process.traversal.step.OrderabilityTest",
+            method = "g_inject_order_with_unknown_type",
+            reason = "Remoting serializers only support known Gremlin types")
     public static class TinkerGraphGraphSONv2TranslatorProvider extends AbstractTinkerGraphGraphSONTranslatorProvider {
         public TinkerGraphGraphSONv2TranslatorProvider() {
             super(GraphSONVersion.V2_0);
         }
     }
 
+    @Graph.OptOut(
+            test = "org.apache.tinkerpop.gremlin.process.traversal.step.OrderabilityTest",
+            method = "g_inject_order_with_unknown_type",
+            reason = "Remoting serializers only support known Gremlin types")
     public static class TinkerGraphGraphSONv3TranslatorProvider extends AbstractTinkerGraphGraphSONTranslatorProvider {
         public TinkerGraphGraphSONv3TranslatorProvider() {
             super(GraphSONVersion.V3_0);
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/io/gryo/TinkerGraphGryoTranslatorProvider.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/io/gryo/TinkerGraphGryoTranslatorProvider.java
index 0d30df9..9b9b19a 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/io/gryo/TinkerGraphGryoTranslatorProvider.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/io/gryo/TinkerGraphGryoTranslatorProvider.java
@@ -216,6 +216,10 @@ import org.apache.tinkerpop.gremlin.tinkergraph.TinkerGraphProvider;
         test = "org.apache.tinkerpop.gremlin.process.traversal.step.map.WriteTest",
         method = "*",
         reason = "read and write tests don't translate locally well because of calling iterate() inside read()/write() add a none()")
+@Graph.OptOut(
+        test = "org.apache.tinkerpop.gremlin.process.traversal.step.OrderabilityTest",
+        method = "g_inject_order_with_unknown_type",
+        reason = "Remoting serializers only support known Gremlin types")
 public class TinkerGraphGryoTranslatorProvider extends TinkerGraphProvider {
 
     @Override