Merge branch '3.4-dev'
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index bbcea25..a86957c 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -111,6 +111,7 @@
 * Prevented Java driver from sending multiple request messages with the same identifier.
 * Improved error message for `property(T,Object)` when mutating graph elements.
 * Added method caching for GraphSON 3.0 deserialization of `P` and `TextP` instances.
+* Allowed setting `ssl_options` for gremlin-python.  
 * Fixed bug with global `dedup()` when used in reducing `by()` of `group()`.
 * Fixed bug with Javascript Groovy `Translator` when generating Gremlin with multiple embedded traversals.
 * Modified Gremlin Server `Settings` to be more extensible allowing for custom options with the YAML parser.
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientAuthenticationTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientAuthenticationTests.cs
index 5045f3c..03546dd 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientAuthenticationTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientAuthenticationTests.cs
@@ -22,7 +22,11 @@
 #endregion
 
 using System;
+using System.Net.Http;
+using System.Net.WebSockets;
 using System.Threading.Tasks;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
 using Gremlin.Net.Driver;
 using Gremlin.Net.Driver.Exceptions;
 using Gremlin.Net.IntegrationTest.Util;
@@ -36,11 +40,27 @@
         private static readonly int TestPort = Convert.ToInt32(ConfigProvider.Configuration["TestSecureServerPort"]);
         private readonly RequestMessageProvider _requestMessageProvider = new RequestMessageProvider();
 
+        public static bool IgnoreCertificateValidationLiveDangerouslyWheeeeeeee(
+              object sender,
+              X509Certificate certificate,
+              X509Chain chain,
+              SslPolicyErrors sslPolicyErrors)
+        {
+           return true;
+        }
+
         [Fact]
         public async Task ShouldThrowForMissingCredentials()
         {
-            var gremlinServer = new GremlinServer(TestHost, TestPort);
-            using (var gremlinClient = new GremlinClient(gremlinServer))
+            ClientWebSocketOptions optionsSet = null;
+            var webSocketConfiguration =
+                            new Action<ClientWebSocketOptions>(options =>
+                            {
+                                options.RemoteCertificateValidationCallback += IgnoreCertificateValidationLiveDangerouslyWheeeeeeee;
+                                optionsSet = options;
+                            });
+            var gremlinServer = new GremlinServer(TestHost, TestPort, enableSsl: true);
+            using (var gremlinClient = new GremlinClient(gremlinServer, webSocketConfiguration: webSocketConfiguration))
             {
                 var exception = await Assert.ThrowsAsync<InvalidOperationException>(
                     async () => await gremlinClient.SubmitWithSingleResultAsync<string>(_requestMessageProvider
@@ -56,8 +76,15 @@
         [InlineData("stephen", "wrongPassword")]
         public async Task ShouldThrowForWrongCredentials(string username, string password)
         {
-            var gremlinServer = new GremlinServer(TestHost, TestPort, username: username, password: password);
-            using (var gremlinClient = new GremlinClient(gremlinServer))
+            ClientWebSocketOptions optionsSet = null;
+            var webSocketConfiguration =
+                            new Action<ClientWebSocketOptions>(options =>
+                            {
+                                options.RemoteCertificateValidationCallback += IgnoreCertificateValidationLiveDangerouslyWheeeeeeee;
+                                optionsSet = options;
+                            });
+            var gremlinServer = new GremlinServer(TestHost, TestPort, username: username, password: password, enableSsl: true);
+            using (var gremlinClient = new GremlinClient(gremlinServer, webSocketConfiguration: webSocketConfiguration))
             {
                 var exception = await Assert.ThrowsAsync<ResponseException>(
                     async () => await gremlinClient.SubmitWithSingleResultAsync<string>(_requestMessageProvider
@@ -72,10 +99,17 @@
         public async Task ScriptShouldBeEvaluatedAndResultReturnedForCorrectCredentials(string requestMsg,
             string expectedResponse)
         {
+            ClientWebSocketOptions optionsSet = null;
+            var webSocketConfiguration =
+                            new Action<ClientWebSocketOptions>(options =>
+                            {
+                                options.RemoteCertificateValidationCallback += IgnoreCertificateValidationLiveDangerouslyWheeeeeeee;
+                                optionsSet = options;
+                            });
             const string username = "stephen";
             const string password = "password";
-            var gremlinServer = new GremlinServer(TestHost, TestPort, username: username, password: password);
-            using (var gremlinClient = new GremlinClient(gremlinServer))
+            var gremlinServer = new GremlinServer(TestHost, TestPort, username: username, password: password, enableSsl: true);
+            using (var gremlinClient = new GremlinClient(gremlinServer, webSocketConfiguration: webSocketConfiguration))
             {
                 var response = await gremlinClient.SubmitWithSingleResultAsync<string>(requestMsg);
 
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js
index fb01b2d..a9ecb60 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js
@@ -28,7 +28,7 @@
 const PlainTextSaslAuthenticator = require('../lib/driver/auth/plain-text-sasl-authenticator');
 
 const serverUrl = 'ws://localhost:45940/gremlin';
-const serverAuthUrl = 'ws://localhost:45941/gremlin';
+const serverAuthUrl = 'wss://localhost:45941/gremlin';
 
 /** @returns {DriverRemoteConnection} */
 exports.getConnection = function getConnection(traversalSource) {
diff --git a/gremlin-python/src/main/python/gremlin_python/driver/tornado/transport.py b/gremlin-python/src/main/python/gremlin_python/driver/tornado/transport.py
index 29baef6..f14c518 100644
--- a/gremlin-python/src/main/python/gremlin_python/driver/tornado/transport.py
+++ b/gremlin-python/src/main/python/gremlin_python/driver/tornado/transport.py
@@ -27,16 +27,18 @@
 class TornadoTransport(AbstractBaseTransport):
 
     def __init__(self, read_timeout=None, write_timeout=None,
-                 compression_options={'compression_level': 5, 'mem_level': 5}):
+                 compression_options={'compression_level': 5, 'mem_level': 5},
+                 ssl_options=None):
         self._loop = ioloop.IOLoop(make_current=False)
         self._ws = None
         self._read_timeout = read_timeout
         self._write_timeout = write_timeout
         self._compression_options = compression_options
+        self._ssl_options = ssl_options
 
     def connect(self, url, headers=None):
-        if headers:
-            url = httpclient.HTTPRequest(url, headers=headers)
+        if headers or self._ssl_options:
+            url = httpclient.HTTPRequest(url, headers=headers, ssl_options=self._ssl_options)
         self._ws = self._loop.run_sync(
             lambda: websocket.websocket_connect(url, compression_options=self._compression_options))
 
diff --git a/gremlin-python/src/main/python/tests/conftest.py b/gremlin-python/src/main/python/tests/conftest.py
index a5bbbcc..b277b1c 100644
--- a/gremlin-python/src/main/python/tests/conftest.py
+++ b/gremlin-python/src/main/python/tests/conftest.py
@@ -18,7 +18,9 @@
 #
 
 import concurrent.futures
+import ssl
 import pytest
+import sys
 import socket
 
 from six.moves import queue
@@ -36,7 +38,7 @@
 
 gremlin_server_url = 'ws://localhost:{}/gremlin'
 anonymous_url = gremlin_server_url.format(45940)
-basic_url = gremlin_server_url.format(45941)
+basic_url = 'wss://localhost:{}/gremlin'.format(45941)
 kerberos_url = gremlin_server_url.format(45942)
 kerberized_service = 'test-service@{}'.format(socket.gethostname())
 
@@ -79,7 +81,11 @@
 def authenticated_client(request):
     try:
         if request.param == 'basic':
-            client = Client(basic_url, 'gmodern', username='stephen', password='password')
+            # turn off certificate verification for testing purposes only
+            ssl_opts = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
+            ssl_opts.verify_mode = ssl.CERT_NONE
+            client = Client(basic_url, 'gmodern', username='stephen', password='password',
+                            transport_factory=lambda: TornadoTransport(ssl_options=ssl_opts))
         elif request.param == 'kerberos':
             client = Client(kerberos_url, 'gmodern', kerberized_service=kerberized_service)
         else:
@@ -120,9 +126,13 @@
 def remote_connection_authenticated(request):
     try:
         if request.param == 'basic':
+            # turn off certificate verification for testing purposes only
+            ssl_opts = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
+            ssl_opts.verify_mode = ssl.CERT_NONE
             remote_conn = DriverRemoteConnection(basic_url, 'gmodern',
                                                  username='stephen', password='password',
-                                                 message_serializer=serializer.GraphSONSerializersV2d0())
+                                                 message_serializer=serializer.GraphSONSerializersV2d0(),
+                                                 transport_factory=lambda: TornadoTransport(ssl_options=ssl_opts))
         elif request.param == 'kerberos':
             remote_conn = DriverRemoteConnection(kerberos_url, 'gmodern', kerberized_service=kerberized_service,
                                                  message_serializer=serializer.GraphSONSerializersV2d0())
diff --git a/gremlin-server/src/test/scripts/test-server-start.groovy b/gremlin-server/src/test/scripts/test-server-start.groovy
index 324492e..ca59745 100644
--- a/gremlin-server/src/test/scripts/test-server-start.groovy
+++ b/gremlin-server/src/test/scripts/test-server-start.groovy
@@ -73,6 +73,11 @@
 settingsSecure.port = 45941
 settingsSecure.authentication.authenticator = "org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator"
 settingsSecure.authentication.config = [credentialsDb: projectBaseDir + "/target/tinkergraph-credentials.properties"]
+settingsSecure.ssl = new Settings.SslSettings()
+settingsSecure.ssl.enabled = true
+settingsSecure.ssl.sslEnabledProtocols = ["TLSv1.2"]
+settingsSecure.ssl.keyStore = gremlinServerDir + "/src/test/resources/server-key.jks"
+settingsSecure.ssl.keyStorePassword = "changeit"
 
 def serverSecure = new GremlinServer(settingsSecure)
 serverSecure.start().join()