Merge branch 'pr-2115' into 3.6-dev
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 09b2a71..18378b4 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -33,7 +33,7 @@
 === TinkerPop 3.6.4 (Release Date: May 12, 2023)
 
 * Fixed bug in `TextP.regex` and `TextP.notRegex` serialization for Java GLV.
-* Fixed a memory leak in the Gremlin.Net driver that only occurred if a CancellationToken was provided.
+* Fixed a memory leak in the Gremlin.Net driver that only occurred if a `CancellationToken` was provided.
 
 ==== Bugs
 
@@ -54,10 +54,10 @@
 * Fixed `Direction` enum bug in `gremlin-javascript` where `Direction.from_` and `Direction.to` was not properly aliased to `Direction.OUT` and `Direction.IN`
 * Fixed `Direction` enum in `gremlin-python` where `Direction.from_` and `Direction.to` were not added, and they can now be used instead of defining `from_=Direction.OUT` and `to=Direction.IN`
 * Improved performance of comparison (equals) between not compatible types and nulls.
-* Fixed MergeV/MergeE steps to work when onCreate is immutable map.
+* Fixed `mergeV()` and `mergeE()` steps to work when `onCreate` is immutable map.
 * Introduced `Writing` and `Deleting` marker interfaces to identify whether a step can perform write or delete or both on Graph.
-* For mergeV/mergeE, added checks for illegal hidden keys and refactored searchVertices to allow subclasses to override search criteria.
-* Added static map capturing possible Traversal steps that shall be added to traversal for a given operator
+* For `mergeV()` and `mergeE()`, added checks for illegal hidden keys and refactored `searchVertices` to allow subclasses to override search criteria.
+* Added static map capturing possible `Traversal` steps that shall be added to traversal for a given operator.
 * Fixed bug which caused some traversals to throw `GremlinTypeErrorException` to users.
 
 ==== Bugs
@@ -360,14 +360,16 @@
 [[release-3-5-7]]
 === TinkerPop 3.5.7 (Release Date: NOT OFFICIALLY RELEASED YET)
 
-* Fixed a memory leak in the Gremlin.Net driver that only occurred if a CancellationToken was provided.
+* Fixed a memory leak in the Gremlin.Net driver that only occurred if a `CancellationToken` was provided.
 * Fixed gremlin-python `Client` problem where calling `submit()` after` `close()` would hang the system.
 * Added `gremlin.spark.dontDeleteNonEmptyOutput` to stop deleting the output folder if it is not empty in `spark-gremlin`.
+* Fixed a bug in `SubgraphStrategy` where the vertex property filter produced errors if a `Vertex` was missing the key provided to `by()` as a token.
 * Upgraded `gremlin-javascript` and `gremlint` to Node 16.20.0.
 * Upgraded `gremlin-go` to Go 1.20.
-* Improved the python Translator class
+* Improved the python `Translator` class with better handling for `P`, `None` and subclasses of `str`.
 * Added `gremlin-java8.bat` file as a workaround to allow loading the console using Java 8 on Windows.
 * Fixed a bug in `gremlin-server` where timeout tasks were not cancelled and could cause very large memory usage when timeout is large.
+* Removed `jcabi-manifests` dependency from `gremlin-core`, `gremlin-driver`, and `gremlin-server`.
 
 [[release-3-5-6]]
 === TinkerPop 3.5.6 (Release Date: May 1, 2023)
@@ -399,7 +401,7 @@
 * Fixed `CountStrategy` bug for cases where predicates contain negative numbers by disabling the optimization.
 * Improved `count` step optimization for negative values in input for 'eq' comparison.
 * Fixed performance issue when using `SampleGlobalStep` with a traverser that has either a `LABELED_PATH` or `PATH` requirement.
-* Reduce the toString() of ObjectWritable to avoid OOM for running OLAP queries on Spark.
+* Reduce the `toString()` of `ObjectWritable` to avoid OOM for running OLAP queries on Spark.
 
 ==== Bugs
 
@@ -476,7 +478,7 @@
 * Provides users with potentially more information to driver TimeoutExceptions.
 * Fixed an issue in Go and Python GLVs where modifying per request settings to override request_id's was not working correctly.
 * Fixed incorrect implementation for `GraphTraversalSource.With` in `gremlin-go`.
-* Changed Gremlin.version() to return `"VersionNotFound"` if the version is missing from the manifest.
+* Changed `Gremlin.version()` to return "VersionNotFound" if the version is missing from the manifest.
 * Fixed local steps to avoid throwing an exception for non-iterable input.
 * Fixed a case sensitivity issue when comparing request UUIDs in `gremlin-javascript`.
 
diff --git a/gremlin-console/pom.xml b/gremlin-console/pom.xml
index f97ed2d..cd45170 100644
--- a/gremlin-console/pom.xml
+++ b/gremlin-console/pom.xml
@@ -267,14 +267,6 @@
                                     <file>src/main/static/licenses/jbcrypt</file>
                                 </transformer>
                                 <transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
-                                    <resource>META-INF/licenses/jcabi-log</resource>
-                                    <file>src/main/static/licenses/jcabi-log</file>
-                                </transformer>
-                                <transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
-                                    <resource>META-INF/licenses/jcabi-manifests</resource>
-                                    <file>src/main/static/licenses/jcabi-manifests</file>
-                                </transformer>
-                                <transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
                                     <resource>META-INF/licenses/jline2</resource>
                                     <file>src/main/static/licenses/jline2</file>
                                 </transformer>
diff --git a/gremlin-console/src/main/static/LICENSE b/gremlin-console/src/main/static/LICENSE
index fba6db1..07e20c0 100644
--- a/gremlin-console/src/main/static/LICENSE
+++ b/gremlin-console/src/main/static/LICENSE
@@ -208,8 +208,6 @@
 The Apache TinkerPop project bundles the following components under the BSD License:
 
      Antlr4 (org.antlr:antlr4-runtime:4.9.1 - https://www.antlr.org) - for details, see licenses/antlr4
-     jcabi-log (com.jcabi:jcabi-log:0.14 - http://www.jcabi.com/jcabi-log) - for details, see licenses/jcabi-log
-     jcabi-manifests 1.1 (com.jcabi:jcabi-manifests:1.1 - http://www.jcabi.com/jcabi-manifests) - for details, see licenses/jcabi-manifests
      JLine (jline:jline:2.14.6 - https://github.com/jline/jline2) - for details, see licenses/jline2
      Kryo (com.esotericsoftware:kryo-shaded:3.0.3 - https://github.com/EsotericSoftware/kryo)
        - shaded in gremlin-shaded to org.apache.tinkerpop.shaded.kryo
diff --git a/gremlin-console/src/main/static/licenses/jcabi-log b/gremlin-console/src/main/static/licenses/jcabi-log
deleted file mode 100644
index ece789e..0000000
--- a/gremlin-console/src/main/static/licenses/jcabi-log
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2012-2015, jcabi.com
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met: 1) Redistributions of source code must retain the above
-copyright notice, this list of conditions and the following
-disclaimer. 2) Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following
-disclaimer in the documentation and/or other materials provided
-with the distribution. 3) Neither the name of the jcabi.com nor
-the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
-NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/gremlin-console/src/main/static/licenses/jcabi-manifests b/gremlin-console/src/main/static/licenses/jcabi-manifests
deleted file mode 100644
index ece789e..0000000
--- a/gremlin-console/src/main/static/licenses/jcabi-manifests
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2012-2015, jcabi.com
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met: 1) Redistributions of source code must retain the above
-copyright notice, this list of conditions and the following
-disclaimer. 2) Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following
-disclaimer in the documentation and/or other materials provided
-with the distribution. 3) Neither the name of the jcabi.com nor
-the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
-NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/gremlin-core/pom.xml b/gremlin-core/pom.xml
index 95ec172..46c0bdd 100644
--- a/gremlin-core/pom.xml
+++ b/gremlin-core/pom.xml
@@ -62,19 +62,9 @@
             <version>0.7.1</version>
         </dependency>
         <dependency>
-            <groupId>com.jcabi</groupId>
-            <artifactId>jcabi-manifests</artifactId>
-            <version>${jcabi.version}</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.mockito</groupId>
-                    <artifactId>mockito-core</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.slf4j</groupId>
-                    <artifactId>slf4j-api</artifactId>
-                </exclusion>
-            </exclusions>
+            <groupId>com.squareup</groupId>
+            <artifactId>javapoet</artifactId>
+            <version>${javapoet.version}</version>
         </dependency>
         <dependency>
             <groupId>net.objecthunter</groupId>
@@ -130,6 +120,19 @@
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
+            <plugin>
+                <groupId>com.google.code.maven-replacer-plugin</groupId>
+                <artifactId>replacer</artifactId>
+                <configuration>
+                    <file>src/main/java/org/apache/tinkerpop/gremlin/util/Gremlin.java</file>
+                    <replacements>
+                        <replacement>
+                            <token>gremlinVersion = ".*"</token>
+                            <value>gremlinVersion = "${project.version}"</value>
+                        </replacement>
+                    </replacements>
+                </configuration>
+            </plugin>
         </plugins>
     </build>
 </project>
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ValueTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ValueTraversal.java
index b62927c..9a8e84a 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ValueTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/ValueTraversal.java
@@ -115,7 +115,12 @@
                         "The by(\"%s\") modulator can only be applied to a traverser that is an Element or a Map - it is being applied to [%s] a %s class instead",
                         propertyKey, o, o.getClass().getSimpleName()));
         } else {
-            this.value = TraversalUtil.apply(start, this.bypassTraversal);
+            final Iterator<V> itty = TraversalUtil.applyAll(start, this.bypassTraversal);
+            if (itty.hasNext()) {
+                this.value = itty.next();
+            } else {
+                noStarts = true;
+            }
         }
     }
 
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyMapStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyMapStep.java
index f089636..812f13b 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyMapStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyMapStep.java
@@ -138,6 +138,10 @@
         return propertyKeys;
     }
 
+    public Traversal.Admin<Element, ? extends Property> getPropertyTraversal() {
+        return propertyTraversal;
+    }
+
     public String toString() {
         return StringFactory.stepString(this, Arrays.asList(this.propertyKeys),
                 this.traversalRing, this.returnType.name().toLowerCase());
@@ -252,10 +256,6 @@
         }
     }
 
-    public Traversal.Admin<Element, ? extends Property> getPropertyTraversal() {
-        return propertyTraversal;
-    }
-
     public TraversalRing<K, E> getTraversalRing() {
         return traversalRing;
     }
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ProductiveByStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ProductiveByStrategy.java
index ba7b92d..ccdb820 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ProductiveByStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ProductiveByStrategy.java
@@ -21,17 +21,16 @@
 
 import org.apache.commons.configuration2.Configuration;
 import org.apache.commons.configuration2.MapConfiguration;
-import org.apache.tinkerpop.gremlin.process.traversal.Step;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.lambda.ConstantTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.lambda.ValueTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
-import org.apache.tinkerpop.gremlin.process.traversal.step.Grouping;
 import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CoalesceStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.ConstantStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertyMapStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
@@ -91,8 +90,23 @@
         TraversalHelper.getStepsOfAssignableClass(ByModulating.class, traversal).stream().
                 filter(bm -> bm instanceof TraversalParent).forEach(bm -> {
             final TraversalParent parentStep = (TraversalParent) bm;
-            parentStep.getLocalChildren().forEach(child -> {
-                if (child instanceof ValueTraversal && !containsValidByPass((ValueTraversal) child) &&
+            for (Traversal.Admin child : parentStep.getLocalChildren()) {
+                // just outright skip the PropertyMapStep.propertyTraversal - it is only set by SubgraphStrategy and
+                // for this case it doesn't make sense to force that traversal to be productive. if it is forced then
+                // PropertyMap actually gets a null Property object if the traversal is not productive and that
+                // causes an NPE. It doesn't make sense to catch the NPE there really as the code wants an empty
+                // Iterator<Property> rather than a productive null. Actually, the propertyTraversal isn't even a
+                // by() provided Traversal, so it really doesn't make sense for this strategy to touch it. Another
+                // sort of example where strategies shouldn't have to know so much about one another. also, another
+                // scenario where ProductiveByStrategy isn't so good. the default behavior without this strategy
+                // works so much more nicely
+                if (parentStep instanceof PropertyMapStep) {
+                    final Traversal.Admin propertyTraversal = ((PropertyMapStep) parentStep).getPropertyTraversal();
+                    if (propertyTraversal != null && propertyTraversal.equals(child))
+                        continue;
+                }
+
+                if (child instanceof ValueTraversal &&  !containsValidByPass((ValueTraversal) child) &&
                         hasKeyNotKnownAsProductive((ValueTraversal) child)) {
                     wrapValueTraversalInCoalesce(parentStep, child);
                 } else if (!(child.getEndStep() instanceof ReducingBarrierStep)) {
@@ -110,7 +124,7 @@
                         // we simply retain whatever the original behavior was even if it is inconsistent
                     }
                 }
-            });
+            }
         });
     }
 
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
index 82d818f..32a29e7 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
@@ -557,6 +557,7 @@
                     MatchAlgorithmStrategy.class,
                     AdjacentToIncidentStrategy.class,
                     ByModulatorOptimizationStrategy.class,
+                    ProductiveByStrategy.class,
                     CountStrategy.class,
                     FilterRankingStrategy.class,
                     IdentityRemovalStrategy.class,
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/Gremlin.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/Gremlin.java
index a03789e..450e03e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/Gremlin.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/util/Gremlin.java
@@ -18,24 +18,13 @@
  */
 package org.apache.tinkerpop.gremlin.util;
 
-import com.jcabi.manifests.Manifests;
-
 import java.io.IOException;
 
 /**
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public final class Gremlin {
-    private static String version;
-
-    static {
-        try {
-            version = Manifests.read("version");
-        }
-        catch (Throwable t) {
-            version = "VersionNotFound";
-        }
-    }
+    private final static String gremlinVersion = "3.6.5-SNAPSHOT"; // DO NOT MODIFY - Configured automatically by Maven Replacer Plugin
 
     private Gremlin() {
     }
@@ -45,7 +34,7 @@
      * the version. This typically would be the result of the version being missing from the manifest file.
      */
     public static String version() {
-        return version;
+        return gremlinVersion;
     }
 
     public static void main(final String[] arguments) throws IOException {
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs
index 2e2817a..c45e291 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs
@@ -31,6 +31,11 @@
     public class Tokens
     {
         /// <summary>
+        ///     Current TinkerPop version.
+        /// </summary>
+        public static string GremlinVersion = "3.6.5-SNAPSHOT"; // DO NOT MODIFY - Configured automatically by Maven Replacer Plugin
+
+        /// <summary>
         ///     The key for the unique identifier of the request.
         /// </summary>
         public static string RequestId = "requestId";
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Utils.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Utils.cs
index 81aa3e0..ffdc3b0 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Utils.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Utils.cs
@@ -25,6 +25,7 @@
 using System.Reflection;
 using System.Runtime.ExceptionServices;
 using System.Threading.Tasks;
+using Gremlin.Net.Driver;
 using static System.Runtime.InteropServices.RuntimeInformation;
 
 namespace Gremlin.Net.Process
@@ -79,8 +80,7 @@
         {
             var applicationName = Assembly.GetEntryAssembly()?.GetName().Name?
                                                         .Replace(' ', '_') ?? "NotAvailable";
-            var driverVersion = Assembly.GetExecutingAssembly().GetName().Version?.ToString()
-                                                        .Replace(' ', '_')  ?? "NotAvailable";
+            var driverVersion = Tokens.GremlinVersion;
             var languageVersion = Environment.Version.ToString().Replace(' ', '_');
             var osName = Environment.OSVersion.Platform.ToString().Replace(' ', '_');
             var osVersion = Environment.OSVersion.Version.ToString().Replace(' ', '_');
diff --git a/gremlin-dotnet/src/pom.xml b/gremlin-dotnet/src/pom.xml
index adedacd..a14db25 100644
--- a/gremlin-dotnet/src/pom.xml
+++ b/gremlin-dotnet/src/pom.xml
@@ -90,6 +90,19 @@
                     <skip>true</skip>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>com.google.code.maven-replacer-plugin</groupId>
+                <artifactId>replacer</artifactId>
+                <configuration>
+                    <file>Gremlin.Net/Driver/Tokens.cs</file>
+                    <replacements>
+                        <replacement>
+                            <token>GremlinVersion = ".*"</token>
+                            <value>GremlinVersion = "${project.version}"</value>
+                        </replacement>
+                    </replacements>
+                </configuration>
+            </plugin>
         </plugins>
     </build>
 
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
index 6580b19..f47e9e2 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -458,6 +458,7 @@
                {"g_addV_propertyXset_emptyX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("foo"), (g,p) =>g.V().HasLabel("person").Values<object>()}}, 
                {"g_addVXpersonX_propertyXname_joshX_propertyXage_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name","josh").Property("age",null), (g,p) =>g.V().Has("person","age",(object) null)}}, 
                {"g_addVXpersonX_propertyXname_markoX_propertyXfriendWeight_null_acl_nullX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name","marko").Property("friendWeight",null,"acl",null), (g,p) =>g.V().Has("person","name","marko").Has("friendWeight",(object) null), (g,p) =>g.V().Has("person","name","marko").Properties<object>("friendWeight").Has("acl",(object) null), (g,p) =>g.V().Has("person","name","marko").Properties<object>("friendWeight").Count()}}, 
+               {"g_V_hasXperson_name_aliceX_propertyXsingle_age_unionXage_constantX1XX_sumX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.AddV("person").Property("name","alice").Property(Cardinality.Single,"age",50), (g,p) =>g.V().Has("person","name","alice").Property("age",__.Union<object>(__.Values<object>("age"),__.Constant<object>(1)).Sum<object>()), (g,p) =>g.V().Has("person","age",50), (g,p) =>g.V().Has("person","age",51)}}, 
                {"g_call", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Call<object>()}}, 
                {"g_callXlistX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Call<object>("--list")}}, 
                {"g_callXlistX_withXstring_stringX", new List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> {(g,p) =>g.Call<object>("--list").With("service","tinker.search")}}, 
diff --git a/gremlin-driver/pom.xml b/gremlin-driver/pom.xml
index a20842d..1b8a6da 100644
--- a/gremlin-driver/pom.xml
+++ b/gremlin-driver/pom.xml
@@ -158,10 +158,6 @@
                                     <shadedPattern>com.shaded.carrotsearch</shadedPattern>
                                 </relocation>
                                 <relocation>
-                                    <pattern>com.jcabi</pattern>
-                                    <shadedPattern>com.shaded.jcabi</shadedPattern>
-                                </relocation>
-                                <relocation>
                                     <pattern>com.squareup</pattern>
                                     <shadedPattern>com.shaded.squareup</shadedPattern>
                                 </relocation>
@@ -211,14 +207,6 @@
                                     <file>src/main/static/NOTICE</file>
                                 </transformer>
                                 <transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
-                                    <resource>META-INF/licenses/jcabi-log</resource>
-                                    <file>src/main/static/licenses/jcabi-log</file>
-                                </transformer>
-                                <transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
-                                    <resource>META-INF/licenses/jcabi-manifests</resource>
-                                    <file>src/main/static/licenses/jcabi-manifests</file>
-                                </transformer>
-                                <transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
                                     <resource>META-INF/licenses/kryo</resource>
                                     <file>src/main/static/licenses/kryo</file>
                                 </transformer>
diff --git a/gremlin-driver/src/main/static/LICENSE b/gremlin-driver/src/main/static/LICENSE
index d6d5735..2a6fc08 100644
--- a/gremlin-driver/src/main/static/LICENSE
+++ b/gremlin-driver/src/main/static/LICENSE
@@ -208,12 +208,6 @@
 The Apache TinkerPop project bundles the following components under the BSD License:
 
      Antlr4 (org.antlr:antlr4-runtime:4.9.1 - https://www.antlr.org) - for details, see licenses/antlr4
-     jcabi-log (com.jcabi:jcabi-log:0.14 - http://www.jcabi.com/jcabi-log) - for details, see
-       - shaded to com.shaded.jcabi.log
-       - for details, see licenses/jcabi-log
-     jcabi-manifests 1.1 (com.jcabi:jcabi-manifests:1.1 - http://www.jcabi.com/jcabi-manifests)
-       - shaded to com.shaded.jcabi.manifests
-       - for details, see licenses/jcabi-manifests
      Kryo (com.esotericsoftware:kryo-shaded:3.0.3 - https://github.com/EsotericSoftware/kryo)
        - shaded to org.apache.tinkerpop.shaded.kryo
        - for details, see licenses/kryo
diff --git a/gremlin-driver/src/main/static/licenses/jcabi-log b/gremlin-driver/src/main/static/licenses/jcabi-log
deleted file mode 100644
index ece789e..0000000
--- a/gremlin-driver/src/main/static/licenses/jcabi-log
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2012-2015, jcabi.com
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met: 1) Redistributions of source code must retain the above
-copyright notice, this list of conditions and the following
-disclaimer. 2) Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following
-disclaimer in the documentation and/or other materials provided
-with the distribution. 3) Neither the name of the jcabi.com nor
-the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
-NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/gremlin-driver/src/main/static/licenses/jcabi-manifests b/gremlin-driver/src/main/static/licenses/jcabi-manifests
deleted file mode 100644
index ece789e..0000000
--- a/gremlin-driver/src/main/static/licenses/jcabi-manifests
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2012-2015, jcabi.com
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met: 1) Redistributions of source code must retain the above
-copyright notice, this list of conditions and the following
-disclaimer. 2) Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following
-disclaimer in the documentation and/or other materials provided
-with the distribution. 3) Neither the name of the jcabi.com nor
-the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
-NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/gremlin-go/driver/cucumber/gremlin.go b/gremlin-go/driver/cucumber/gremlin.go
index 1444206..026c45e 100644
--- a/gremlin-go/driver/cucumber/gremlin.go
+++ b/gremlin-go/driver/cucumber/gremlin.go
@@ -429,6 +429,7 @@
     "g_addV_propertyXset_emptyX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("foo")}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().HasLabel("person").Values()}}, 
     "g_addVXpersonX_propertyXname_joshX_propertyXage_nullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", "josh").Property("age", nil)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "age", nil)}}, 
     "g_addVXpersonX_propertyXname_markoX_propertyXfriendWeight_null_acl_nullX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", "marko").Property("friendWeight", nil, "acl", nil)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "marko").Has("friendWeight", nil)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "marko").Properties("friendWeight").Has("acl", nil)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "marko").Properties("friendWeight").Count()}}, 
+    "g_V_hasXperson_name_aliceX_propertyXsingle_age_unionXage_constantX1XX_sumX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.AddV("person").Property("name", "alice").Property(gremlingo.Cardinality.Single, "age", 50)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "name", "alice").Property("age", gremlingo.T__.Union(gremlingo.T__.Values("age"), gremlingo.T__.Constant(1)).Sum())}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "age", 50)}, func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.V().Has("person", "age", 51)}}, 
     "g_call": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Call()}}, 
     "g_callXlistX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Call("--list")}}, 
     "g_callXlistX_withXstring_stringX": {func(g *gremlingo.GraphTraversalSource, p map[string]interface{}) *gremlingo.GraphTraversal {return g.Call("--list").With("service", "tinker.search")}}, 
diff --git a/gremlin-go/driver/user_agent.go b/gremlin-go/driver/user_agent.go
index 334d2a0..0801e3b 100644
--- a/gremlin-go/driver/user_agent.go
+++ b/gremlin-go/driver/user_agent.go
@@ -23,7 +23,6 @@
 	"os"
 	"path/filepath"
 	"runtime"
-	"runtime/debug"
 	"strings"
 )
 
@@ -38,28 +37,19 @@
 
 const userAgentHeader = "User-Agent"
 
+const gremlinVersion = "3.6.5-SNAPSHOT" // DO NOT MODIFY - Configured automatically by Maven Replacer Plugin
+
 func init() {
 	applicationName := "NotAvailable"
-	driverVersion := "NotAvailable"
 
 	path, err := os.Executable()
 	if err == nil {
 		applicationName = filepath.Base(path)
 	}
 
-	bi, ok := debug.ReadBuildInfo()
-	if ok {
-		for _, dep := range bi.Deps {
-			if strings.Contains(dep.Path, "gremlin-go") {
-				driverVersion = dep.Version
-				break
-			}
-		}
-	}
 	applicationName = strings.ReplaceAll(applicationName, " ", "_")
-	driverVersion = strings.ReplaceAll(driverVersion, " ", "_")
 	runtimeVersion := strings.ReplaceAll(runtime.Version(), " ", "_")
 	osName := strings.ReplaceAll(runtime.GOOS, " ", "_")
 	architecture := strings.ReplaceAll(runtime.GOARCH, " ", "_")
-	userAgent = fmt.Sprintf("%v Gremlin-Go.%v %v %v.NotAvailable %v", applicationName, driverVersion, runtimeVersion, osName, architecture)
+	userAgent = fmt.Sprintf("%v Gremlin-Go.%v %v %v.NotAvailable %v", applicationName, gremlinVersion, runtimeVersion, osName, architecture)
 }
diff --git a/gremlin-go/go.mod b/gremlin-go/go.mod
index 22b61dc..294c394 100644
--- a/gremlin-go/go.mod
+++ b/gremlin-go/go.mod
@@ -25,7 +25,7 @@
 	github.com/gorilla/websocket v1.5.0
 	github.com/nicksnyder/go-i18n/v2 v2.2.1
 	github.com/stretchr/testify v1.8.4
-	golang.org/x/text v0.10.0
+	golang.org/x/text v0.11.0
 )
 
 require (
diff --git a/gremlin-go/go.sum b/gremlin-go/go.sum
index 8ea36c3..7825122 100644
--- a/gremlin-go/go.sum
+++ b/gremlin-go/go.sum
@@ -81,8 +81,8 @@
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
-golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
+golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
diff --git a/gremlin-go/pom.xml b/gremlin-go/pom.xml
index 0e5dda3..34aa9da 100644
--- a/gremlin-go/pom.xml
+++ b/gremlin-go/pom.xml
@@ -65,6 +65,19 @@
                     <skip>true</skip>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>com.google.code.maven-replacer-plugin</groupId>
+                <artifactId>replacer</artifactId>
+                <configuration>
+                    <file>driver/user_agent.go</file>
+                    <replacements>
+                        <replacement>
+                            <token>gremlinVersion = ".*"</token>
+                            <value>gremlinVersion = "${project.version}"</value>
+                        </replacement>
+                    </replacements>
+                </configuration>
+            </plugin>
         </plugins>
     </build>
 
diff --git a/gremlin-javascript/pom.xml b/gremlin-javascript/pom.xml
index 0aea68d..f7dbb5b 100644
--- a/gremlin-javascript/pom.xml
+++ b/gremlin-javascript/pom.xml
@@ -217,6 +217,19 @@
                     <skip>true</skip>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>com.google.code.maven-replacer-plugin</groupId>
+                <artifactId>replacer</artifactId>
+                <configuration>
+                    <file>src/main/javascript/gremlin-javascript/lib/utils.js</file>
+                    <replacements>
+                        <replacement>
+                            <token>gremlinVersion = '.*'</token>
+                            <value>gremlinVersion = '${project.version}'</value>
+                        </replacement>
+                    </replacements>
+                </configuration>
+            </plugin>
         </plugins>
     </build>
     <profiles>
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js
index 2bb3ecd..aeb315a 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/utils.js
@@ -25,7 +25,8 @@
 
 const crypto = require('crypto');
 const os = require('os');
-const { readFileSync } = require('fs');
+
+const gremlinVersion = '3.6.5-SNAPSHOT'; // DO NOT MODIFY - Configured automatically by Maven Replacer Plugin
 
 exports.toLong = function toLong(value) {
   return new Long(value);
@@ -84,12 +85,6 @@
 
 function generateUserAgent() {
   const applicationName = (process.env.npm_package_name || 'NotAvailable').replace('_', ' ');
-  let driverVersion;
-  try {
-    driverVersion = JSON.parse(readFileSync(__dirname + '/../package.json')).version.replace('_', ' ');
-  } catch (e) {
-    driverVersion = 'NotAvailable';
-  }
   let runtimeVersion;
   let osName;
   let osVersion;
@@ -108,7 +103,7 @@
     osVersion = os.release().replace(' ', '_');
   }
 
-  const userAgent = `${applicationName} Gremlin-Javascript.${driverVersion} ${runtimeVersion} ${osName}.${osVersion} ${cpuArch}`;
+  const userAgent = `${applicationName} Gremlin-Javascript.${gremlinVersion} ${runtimeVersion} ${osName}.${osVersion} ${cpuArch}`;
 
   return userAgent;
 }
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/package-lock.json b/gremlin-javascript/src/main/javascript/gremlin-javascript/package-lock.json
index 33c8ee2..cf0f69a 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/package-lock.json
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/package-lock.json
@@ -30,6 +30,15 @@
         "node": ">=16"
       }
     },
+    "node_modules/@aashutoshrathi/word-wrap": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
+      "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/@babel/parser": {
       "version": "7.14.4",
       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
@@ -80,14 +89,14 @@
       }
     },
     "node_modules/@eslint/eslintrc": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz",
-      "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz",
+      "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==",
       "dev": true,
       "dependencies": {
         "ajv": "^6.12.4",
         "debug": "^4.3.2",
-        "espree": "^9.5.2",
+        "espree": "^9.6.0",
         "globals": "^13.19.0",
         "ignore": "^5.2.0",
         "import-fresh": "^3.2.1",
@@ -121,9 +130,9 @@
       }
     },
     "node_modules/@eslint/js": {
-      "version": "8.43.0",
-      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz",
-      "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==",
+      "version": "8.44.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz",
+      "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==",
       "dev": true,
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1014,15 +1023,15 @@
       }
     },
     "node_modules/eslint": {
-      "version": "8.43.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz",
-      "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==",
+      "version": "8.44.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz",
+      "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==",
       "dev": true,
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.2.0",
         "@eslint-community/regexpp": "^4.4.0",
-        "@eslint/eslintrc": "^2.0.3",
-        "@eslint/js": "8.43.0",
+        "@eslint/eslintrc": "^2.1.0",
+        "@eslint/js": "8.44.0",
         "@humanwhocodes/config-array": "^0.11.10",
         "@humanwhocodes/module-importer": "^1.0.1",
         "@nodelib/fs.walk": "^1.2.8",
@@ -1034,7 +1043,7 @@
         "escape-string-regexp": "^4.0.0",
         "eslint-scope": "^7.2.0",
         "eslint-visitor-keys": "^3.4.1",
-        "espree": "^9.5.2",
+        "espree": "^9.6.0",
         "esquery": "^1.4.2",
         "esutils": "^2.0.2",
         "fast-deep-equal": "^3.1.3",
@@ -1054,7 +1063,7 @@
         "lodash.merge": "^4.6.2",
         "minimatch": "^3.1.2",
         "natural-compare": "^1.4.0",
-        "optionator": "^0.9.1",
+        "optionator": "^0.9.3",
         "strip-ansi": "^6.0.1",
         "strip-json-comments": "^3.1.0",
         "text-table": "^0.2.0"
@@ -1173,12 +1182,12 @@
       }
     },
     "node_modules/espree": {
-      "version": "9.5.2",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
-      "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz",
+      "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==",
       "dev": true,
       "dependencies": {
-        "acorn": "^8.8.0",
+        "acorn": "^8.9.0",
         "acorn-jsx": "^5.3.2",
         "eslint-visitor-keys": "^3.4.1"
       },
@@ -2938,17 +2947,17 @@
       }
     },
     "node_modules/optionator": {
-      "version": "0.9.1",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
-      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+      "version": "0.9.3",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
+      "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
       "dev": true,
       "dependencies": {
+        "@aashutoshrathi/word-wrap": "^1.2.3",
         "deep-is": "^0.1.3",
         "fast-levenshtein": "^2.0.6",
         "levn": "^0.4.1",
         "prelude-ls": "^1.2.1",
-        "type-check": "^0.4.0",
-        "word-wrap": "^1.2.3"
+        "type-check": "^0.4.0"
       },
       "engines": {
         "node": ">= 0.8.0"
@@ -3719,15 +3728,6 @@
         "which": "bin/which"
       }
     },
-    "node_modules/word-wrap": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
-      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/workerpool": {
       "version": "6.2.1",
       "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
@@ -3884,6 +3884,12 @@
     }
   },
   "dependencies": {
+    "@aashutoshrathi/word-wrap": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
+      "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
+      "dev": true
+    },
     "@babel/parser": {
       "version": "7.14.4",
       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
@@ -3916,14 +3922,14 @@
       "dev": true
     },
     "@eslint/eslintrc": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz",
-      "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz",
+      "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==",
       "dev": true,
       "requires": {
         "ajv": "^6.12.4",
         "debug": "^4.3.2",
-        "espree": "^9.5.2",
+        "espree": "^9.6.0",
         "globals": "^13.19.0",
         "ignore": "^5.2.0",
         "import-fresh": "^3.2.1",
@@ -3950,9 +3956,9 @@
       }
     },
     "@eslint/js": {
-      "version": "8.43.0",
-      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz",
-      "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==",
+      "version": "8.44.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz",
+      "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==",
       "dev": true
     },
     "@humanwhocodes/config-array": {
@@ -4639,15 +4645,15 @@
       "dev": true
     },
     "eslint": {
-      "version": "8.43.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz",
-      "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==",
+      "version": "8.44.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz",
+      "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==",
       "dev": true,
       "requires": {
         "@eslint-community/eslint-utils": "^4.2.0",
         "@eslint-community/regexpp": "^4.4.0",
-        "@eslint/eslintrc": "^2.0.3",
-        "@eslint/js": "8.43.0",
+        "@eslint/eslintrc": "^2.1.0",
+        "@eslint/js": "8.44.0",
         "@humanwhocodes/config-array": "^0.11.10",
         "@humanwhocodes/module-importer": "^1.0.1",
         "@nodelib/fs.walk": "^1.2.8",
@@ -4659,7 +4665,7 @@
         "escape-string-regexp": "^4.0.0",
         "eslint-scope": "^7.2.0",
         "eslint-visitor-keys": "^3.4.1",
-        "espree": "^9.5.2",
+        "espree": "^9.6.0",
         "esquery": "^1.4.2",
         "esutils": "^2.0.2",
         "fast-deep-equal": "^3.1.3",
@@ -4679,7 +4685,7 @@
         "lodash.merge": "^4.6.2",
         "minimatch": "^3.1.2",
         "natural-compare": "^1.4.0",
-        "optionator": "^0.9.1",
+        "optionator": "^0.9.3",
         "strip-ansi": "^6.0.1",
         "strip-json-comments": "^3.1.0",
         "text-table": "^0.2.0"
@@ -4750,12 +4756,12 @@
       "dev": true
     },
     "espree": {
-      "version": "9.5.2",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
-      "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz",
+      "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==",
       "dev": true,
       "requires": {
-        "acorn": "^8.8.0",
+        "acorn": "^8.9.0",
         "acorn-jsx": "^5.3.2",
         "eslint-visitor-keys": "^3.4.1"
       }
@@ -6100,17 +6106,17 @@
       }
     },
     "optionator": {
-      "version": "0.9.1",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
-      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+      "version": "0.9.3",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
+      "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
       "dev": true,
       "requires": {
+        "@aashutoshrathi/word-wrap": "^1.2.3",
         "deep-is": "^0.1.3",
         "fast-levenshtein": "^2.0.6",
         "levn": "^0.4.1",
         "prelude-ls": "^1.2.1",
-        "type-check": "^0.4.0",
-        "word-wrap": "^1.2.3"
+        "type-check": "^0.4.0"
       }
     },
     "os-homedir": {
@@ -6673,12 +6679,6 @@
         "isexe": "^2.0.0"
       }
     },
-    "word-wrap": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
-      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
-      "dev": true
-    },
     "workerpool": {
       "version": "6.2.1",
       "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
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 513042b..989999a 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
@@ -448,6 +448,7 @@
     g_addV_propertyXset_emptyX: [function({g}) { return g.addV("foo") }, function({g}) { return g.V().hasLabel("person").values() }], 
     g_addVXpersonX_propertyXname_joshX_propertyXage_nullX: [function({g}) { return g.addV("person").property("name","josh").property("age",null) }, function({g}) { return g.V().has("person","age",null) }], 
     g_addVXpersonX_propertyXname_markoX_propertyXfriendWeight_null_acl_nullX: [function({g}) { return g.addV("person").property("name","marko").property("friendWeight",null,"acl",null) }, function({g}) { return g.V().has("person","name","marko").has("friendWeight",null) }, function({g}) { return g.V().has("person","name","marko").properties("friendWeight").has("acl",null) }, function({g}) { return g.V().has("person","name","marko").properties("friendWeight").count() }], 
+    g_V_hasXperson_name_aliceX_propertyXsingle_age_unionXage_constantX1XX_sumX: [function({g}) { return g.addV("person").property("name","alice").property(Cardinality.single,"age",50) }, function({g}) { return g.V().has("person","name","alice").property("age",__.union(__.values("age"),__.constant(1)).sum()) }, function({g}) { return g.V().has("person","age",50) }, function({g}) { return g.V().has("person","age",51) }], 
     g_call: [function({g}) { return g.call() }], 
     g_callXlistX: [function({g}) { return g.call("--list") }], 
     g_callXlistX_withXstring_stringX: [function({g}) { return g.call("--list").with_("service","tinker.search") }], 
diff --git a/gremlin-python/pom.xml b/gremlin-python/pom.xml
index 8929b8d..bdf6b26 100644
--- a/gremlin-python/pom.xml
+++ b/gremlin-python/pom.xml
@@ -68,6 +68,19 @@
                     <skip>true</skip>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>com.google.code.maven-replacer-plugin</groupId>
+                <artifactId>replacer</artifactId>
+                <configuration>
+                    <file>src/main/python/gremlin_python/driver/useragent.py</file>
+                    <replacements>
+                        <replacement>
+                            <token>gremlin_version = ".*"</token>
+                            <value>gremlin_version = "${project.version}"</value>
+                        </replacement>
+                    </replacements>
+                </configuration>
+            </plugin>
         </plugins>
     </build>
 
diff --git a/gremlin-python/src/main/python/gremlin_python/driver/useragent.py b/gremlin-python/src/main/python/gremlin_python/driver/useragent.py
index 9cd1ea2..c9ca07c 100644
--- a/gremlin-python/src/main/python/gremlin_python/driver/useragent.py
+++ b/gremlin-python/src/main/python/gremlin_python/driver/useragent.py
@@ -18,20 +18,16 @@
 #
 import platform
 
+gremlin_version = "3.6.5-SNAPSHOT"  # DO NOT MODIFY - Configured automatically by Maven Replacer Plugin
 
 def _generate_user_agent():
     application_name = "NotAvailable"
-    try:
-        from gremlin_python import __version__
-        driver_version = __version__.version.replace(" ", "_")
-    except ImportError:
-        driver_version = "NotAvailable"
     runtime_version = platform.python_version().replace(" ", "_")
     os_name = platform.system().replace(" ", "_")
     os_version = platform.release().replace(" ", "_")
     architecture = platform.machine().replace(" ", "_")
     user_agent = "{appName} Gremlin-Python.{driverVersion} {runtimeVersion} {osName}.{osVersion} {cpuArch}".format(
-                    appName=application_name, driverVersion=driver_version, runtimeVersion=runtime_version,
+                    appName=application_name, driverVersion=gremlin_version, runtimeVersion=runtime_version,
                     osName=os_name, osVersion=os_version, cpuArch=architecture)
 
     return user_agent
diff --git a/gremlin-python/src/main/python/radish/gremlin.py b/gremlin-python/src/main/python/radish/gremlin.py
index 998289b..8f7ebec 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -430,6 +430,7 @@
     'g_addV_propertyXset_emptyX': [(lambda g:g.addV('foo')), (lambda g:g.V().hasLabel('person').values())], 
     'g_addVXpersonX_propertyXname_joshX_propertyXage_nullX': [(lambda g:g.addV('person').property('name','josh').property('age',None)), (lambda g:g.V().has('person','age',None))], 
     'g_addVXpersonX_propertyXname_markoX_propertyXfriendWeight_null_acl_nullX': [(lambda g:g.addV('person').property('name','marko').property('friendWeight',None,'acl',None)), (lambda g:g.V().has('person','name','marko').has('friendWeight',None)), (lambda g:g.V().has('person','name','marko').properties('friendWeight').has('acl',None)), (lambda g:g.V().has('person','name','marko').properties('friendWeight').count())], 
+    'g_V_hasXperson_name_aliceX_propertyXsingle_age_unionXage_constantX1XX_sumX': [(lambda g:g.addV('person').property('name','alice').property(Cardinality.single,'age',50)), (lambda g:g.V().has('person','name','alice').property('age',__.union(__.age,__.constant(1)).sum_())), (lambda g:g.V().has('person','age',50)), (lambda g:g.V().has('person','age',51))], 
     'g_call': [(lambda g:g.call())], 
     'g_callXlistX': [(lambda g:g.call('--list'))], 
     'g_callXlistX_withXstring_stringX': [(lambda g:g.call('--list').with_('service','tinker.search'))], 
diff --git a/gremlin-server/src/main/static/LICENSE b/gremlin-server/src/main/static/LICENSE
index dd3f492..1b205ed 100644
--- a/gremlin-server/src/main/static/LICENSE
+++ b/gremlin-server/src/main/static/LICENSE
@@ -208,8 +208,6 @@
 The Apache TinkerPop project bundles the following components under the BSD License:
 
      Antlr4 (org.antlr:antlr4-runtime:4.9.1 - https://www.antlr.org) - for details, see licenses/antlr4
-     jcabi-log (com.jcabi:jcabi-log:0.14 - http://www.jcabi.com/jcabi-log) - for details, see licenses/jcabi-log
-     jcabi-manifests 1.1 (com.jcabi:jcabi-manifests:1.1 - http://www.jcabi.com/jcabi-manifests) - for details, see licenses/jcabi-manifests
      JLine (jline:jline:2.14.6 - https://github.com/jline/jline2) - for details, see licenses/jline2
      Kryo (com.esotericsoftware:kryo-shaded:3.0.3 - https://github.com/EsotericSoftware/kryo)
        - shaded in gremlin-shaded to org.apache.tinkerpop.shaded.kryo
diff --git a/gremlin-server/src/main/static/licenses/jcabi-log b/gremlin-server/src/main/static/licenses/jcabi-log
deleted file mode 100644
index ece789e..0000000
--- a/gremlin-server/src/main/static/licenses/jcabi-log
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2012-2015, jcabi.com
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met: 1) Redistributions of source code must retain the above
-copyright notice, this list of conditions and the following
-disclaimer. 2) Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following
-disclaimer in the documentation and/or other materials provided
-with the distribution. 3) Neither the name of the jcabi.com nor
-the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
-NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/gremlin-server/src/main/static/licenses/jcabi-manifests b/gremlin-server/src/main/static/licenses/jcabi-manifests
deleted file mode 100644
index ece789e..0000000
--- a/gremlin-server/src/main/static/licenses/jcabi-manifests
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2012-2015, jcabi.com
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met: 1) Redistributions of source code must retain the above
-copyright notice, this list of conditions and the following
-disclaimer. 2) Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following
-disclaimer in the documentation and/or other materials provided
-with the distribution. 3) Neither the name of the jcabi.com nor
-the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
-NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
index 7bb4fa9..ef26a08 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
@@ -22,6 +22,7 @@
 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.strategy.optimization.ProductiveByStrategy;
 import org.apache.tinkerpop.gremlin.structure.RemoteGraph;
 import org.apache.tinkerpop.gremlin.process.traversal.Order;
 import org.apache.tinkerpop.gremlin.process.traversal.P;
@@ -38,6 +39,8 @@
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.util.CloseableIterator;
+import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyVertexProperty;
+import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceVertexProperty;
 import org.hamcrest.Matchers;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -45,12 +48,14 @@
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.NoSuchElementException;
 
 import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.CREW;
 import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.both;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.bothE;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.constant;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.has;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.hasNot;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out;
@@ -59,6 +64,7 @@
 import static org.hamcrest.core.IsCollectionContaining.hasItems;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeThat;
@@ -508,6 +514,23 @@
         checkResults(Arrays.asList(3, 3, 3, 4, 4, 5, 5, 5), sg.V().outE("uses").values("skill"));
         checkResults(Arrays.asList(3, 3, 3, 4, 4, 5, 5, 5), sg.V().as("a").properties().select("a").dedup().outE().values("skill"));
         checkResults(Arrays.asList(3, 3, 3, 4, 4, 5, 5, 5), sg.V().as("a").properties().select("a").dedup().outE().properties("skill").as("b").identity().select("b").by(__.value()));
+        //
+
+        // testing situations where the key specified is not present for the vertices - TINKERPOP-2920 use of
+        // constant(true) here is sorta weird because a Traversal<?,VertexProperty> is expected, but not really
+        sg = g.withStrategies(SubgraphStrategy.create(new MapConfiguration(new HashMap<String, Object>() {{
+            put(SubgraphStrategy.VERTEX_PROPERTIES, constant(true));
+        }})));
+        final List<Map<String, Object>> l = sg.V().project("example").by("example").toList();
+        l.forEach(map -> {
+            assertEquals(0, map.size());
+        });
+        checkResults(Arrays.asList("aachen","baltimore","bremen","brussels","centreville","dulles","kaiserslautern",
+                        "oakland","purcellville","san diego","santa cruz","santa fe","seattle","spremberg"),
+                sg.withoutStrategies(ProductiveByStrategy.class).V().valueMap("location").select(Column.values).unfold().unfold());
+        checkResults(Arrays.asList("aachen","baltimore","bremen","brussels","centreville","dulles","kaiserslautern",
+                "oakland","purcellville","san diego","santa cruz","santa fe","seattle","spremberg"),
+                sg.V().valueMap("location").select(Column.values).unfold().unfold());
     }
 
     @Test
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AddVertex.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AddVertex.feature
index 0780469..505969a 100644
--- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AddVertex.feature
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AddVertex.feature
@@ -516,4 +516,19 @@
     Then the result should have a count of 1
     And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"marko\").has(\"friendWeight\", null)"
     And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"marko\").properties(\"friendWeight\").has(\"acl\",null)"
-    And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"marko\").properties(\"friendWeight\").count()"
\ No newline at end of file
+    And the graph should return 1 for count of "g.V().has(\"person\",\"name\",\"marko\").properties(\"friendWeight\").count()"
+
+  Scenario: g_V_hasXperson_name_aliceX_propertyXsingle_age_unionXage_constantX1XX_sumX
+    Given the empty graph
+    And the graph initializer of
+      """
+      g.addV("person").property("name", "alice").property(single, "age", 50)
+      """
+    And the traversal of
+      """
+      g.V().has("person","name","alice").property("age", __.union(__.values("age"), constant(1)).sum())
+      """
+    When iterated to list
+    Then the result should have a count of 1
+    And the graph should return 0 for count of "g.V().has(\"person\",\"age\",50)"
+    And the graph should return 1 for count of "g.V().has(\"person\",\"age\",51)"
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index ab32d38..713ad81 100644
--- a/pom.xml
+++ b/pom.xml
@@ -168,7 +168,6 @@
         <javadoc-plugin.version>3.3.1</javadoc-plugin.version>
         <javapoet.version>1.13.0</javapoet.version>
         <jbcrypt.version>0.4</jbcrypt.version>
-        <jcabi.version>1.2.1</jcabi.version>
         <junit.version>4.13.1</junit.version>
         <kerby.version>2.0.1</kerby.version>
         <logback.version>1.2.11</logback.version>
@@ -537,7 +536,23 @@
 
         <pluginManagement>
             <plugins>
-                <!-- there is a jdk11 profile that will be enabled if built with that version - these settings will be overridden -->
+                <plugin>
+                    <groupId>com.google.code.maven-replacer-plugin</groupId>
+                    <artifactId>replacer</artifactId>
+                    <version>1.5.3</version>
+                    <executions>
+                        <execution>
+                            <phase>generate-sources</phase>
+                            <goals>
+                                <goal>replace</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                    <configuration>
+                        <basedir>${basedir}</basedir>
+                    </configuration>
+                </plugin>
+                <!-- there is a jdk11 profile that will be enabled if built with that version - these settings will be overriden -->
                 <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-compiler-plugin</artifactId>
@@ -1610,11 +1625,6 @@
                                             <artifactId>snakeyaml</artifactId>
                                             <version>${snakeyaml.version}</version>
                                         </additionalDependency>
-                                        <additionalDependency>
-                                            <groupId>com.jcabi</groupId>
-                                            <artifactId>jcabi-manifests</artifactId>
-                                            <version>${jcabi.version}</version>
-                                        </additionalDependency>
                                     </additionalDependencies>
                                 </configuration>
                             </execution>
@@ -1821,11 +1831,6 @@
                                             <artifactId>snakeyaml</artifactId>
                                             <version>${snakeyaml.version}</version>
                                         </additionalDependency>
-                                        <additionalDependency>
-                                            <groupId>com.jcabi</groupId>
-                                            <artifactId>jcabi-manifests</artifactId>
-                                            <version>${jcabi.version}</version>
-                                        </additionalDependency>
                                     </additionalDependencies>
                                 </configuration>
                             </execution>