You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by xi...@apache.org on 2024/07/15 16:12:44 UTC

(tinkerpop) branch python-http-chunked updated: remove ws, switch to graphbinaryv4, complete support for chunked transfer & clean up

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

xiazcy pushed a commit to branch python-http-chunked
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/python-http-chunked by this push:
     new 416bcf735f remove ws, switch to graphbinaryv4, complete support for chunked transfer & clean up
416bcf735f is described below

commit 416bcf735fa570716f12352c044b0dc0a414f36c
Author: Yang Xia <55...@users.noreply.github.com>
AuthorDate: Mon Jul 15 09:12:35 2024 -0700

    remove ws, switch to graphbinaryv4, complete support for chunked transfer & clean up
---
 CHANGELOG.asciidoc                                 |    2 +
 .../gremlin_python/driver/aiohttp/transport.py     |  192 +---
 .../main/python/gremlin_python/driver/client.py    |   54 +-
 .../python/gremlin_python/driver/connection.py     |   10 +-
 .../driver/driver_remote_connection.py             |   68 +-
 .../main/python/gremlin_python/driver/protocol.py  |  210 +---
 .../gremlin_python/driver/remote_connection.py     |    6 -
 .../python/gremlin_python/driver/serializer.py     |  265 +----
 .../gremlin_python/structure/io/graphbinaryV1.py   | 1161 --------------------
 .../gremlin_python/structure/io/graphsonV2d0.py    |  664 -----------
 .../gremlin_python/structure/io/graphsonV3d0.py    |  784 -------------
 gremlin-python/src/main/python/tests/conftest.py   |  297 +----
 .../src/main/python/tests/driver/test_client.py    |  266 ++---
 .../tests/driver/test_driver_remote_connection.py  |  155 +--
 .../driver/test_driver_remote_connection_http.py   |  229 ----
 .../test_driver_remote_connection_threaded.py      |   16 +-
 .../main/python/tests/driver/test_serializer.py    |    2 -
 .../tests/structure/io/test_functionalityio.py     |   60 +-
 .../tests/structure/io/test_graphbinaryV1.py       |  235 ----
 .../python/tests/structure/io/test_graphsonV2d0.py |  538 ---------
 .../python/tests/structure/io/test_graphsonV3d0.py |  556 ----------
 21 files changed, 359 insertions(+), 5411 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 00c4b8de81..5351366cea 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -40,6 +40,8 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 * Added `withoutStrategies()` syntax to the Gremlin ANTLR grammar.
 * Modified the Gremlin ANTLR grammar to more dynamically interact with any strategies registered globally to the `TraversalStrategies` cache sets.
 * Made `new` keyword optional in the Gremlin grammar.
+* Switched to HTTP protocol in `gremlin-python` and replaced GraphSONV2, GraphSONV2 & GraphBinaryV1 with GraphBinaryV4
+* Added support for chunked transfer in `gremlin-python`
 * Added TypeScript & ECMAScript module support.
 
 == TinkerPop 3.7.0 (Gremfir Master of the Pan Flute)
diff --git a/gremlin-python/src/main/python/gremlin_python/driver/aiohttp/transport.py b/gremlin-python/src/main/python/gremlin_python/driver/aiohttp/transport.py
index 2ae80f7db7..2f4164f1ca 100644
--- a/gremlin-python/src/main/python/gremlin_python/driver/aiohttp/transport.py
+++ b/gremlin-python/src/main/python/gremlin_python/driver/aiohttp/transport.py
@@ -19,134 +19,18 @@
 import aiohttp
 import asyncio
 import async_timeout
-from aiohttp import ClientResponseError
-
+from aiohttp import ClientPayloadError
+from gremlin_python.driver.protocol import GremlinServerError
 from gremlin_python.driver.transport import AbstractBaseTransport
 
 __author__ = 'Lyndon Bauto (lyndonb@bitquilltech.com)'
 
 
-# TODO: remove WS transport & refactor
-class AiohttpTransport(AbstractBaseTransport):
-    nest_asyncio_applied = False
-
-    def __init__(self, call_from_event_loop=None, read_timeout=None, write_timeout=None, **kwargs):
-        if call_from_event_loop is not None and call_from_event_loop and not AiohttpTransport.nest_asyncio_applied:
-            """ 
-                The AiohttpTransport implementation uses the asyncio event loop. Because of this, it cannot be called 
-                within an event loop without nest_asyncio. If the code is ever refactored so that it can be called 
-                within an event loop this import and call can be removed. Without this, applications which use the 
-                event loop to call gremlin-python (such as Jupyter) will not work.
-            """
-            import nest_asyncio
-            nest_asyncio.apply()
-            AiohttpTransport.nest_asyncio_applied = True
-
-        # Start event loop and initialize websocket and client to None
-        self._loop = asyncio.new_event_loop()
-        self._websocket = None
-        self._client_session = None
-
-        # Set all inner variables to parameters passed in.
-        self._aiohttp_kwargs = kwargs
-        self._write_timeout = write_timeout
-        self._read_timeout = read_timeout
-        if "max_content_length" in self._aiohttp_kwargs:
-            self._aiohttp_kwargs["max_msg_size"] = self._aiohttp_kwargs.pop("max_content_length")
-        if "ssl_options" in self._aiohttp_kwargs:
-            self._aiohttp_kwargs["ssl"] = self._aiohttp_kwargs.pop("ssl_options")
-
-    def __del__(self):
-        # Close will only actually close if things are left open, so this is safe to call.
-        # Clean up any connection resources and close the event loop.
-        self.close()
-
-    def connect(self, url, headers=None):
-        # Inner function to perform async connect.
-        async def async_connect():
-            # Start client session and use it to create a websocket with all the connection options provided.
-            self._client_session = aiohttp.ClientSession(loop=self._loop)
-            try:
-                self._websocket = await self._client_session.ws_connect(url, **self._aiohttp_kwargs, headers=headers)
-            except ClientResponseError as err:
-                # If 403, just send forbidden because in some cases this prints out a huge verbose message
-                # that includes credentials.
-                if err.status == 403:
-                    raise Exception('Failed to connect to server: HTTP Error code 403 - Forbidden.')
-                else:
-                    raise
-
-        # Execute the async connect synchronously.
-        self._loop.run_until_complete(async_connect())
-
-    def write(self, message):
-        # Inner function to perform async write.
-        async def async_write():
-            async with async_timeout.timeout(self._write_timeout):
-                await self._websocket.send_bytes(message)
-
-        # Execute the async write synchronously.
-        self._loop.run_until_complete(async_write())
-
-    def read(self):
-        # Inner function to perform async read.
-        async def async_read():
-            async with async_timeout.timeout(self._read_timeout):
-                return await self._websocket.receive()
-
-        # Execute the async read synchronously.
-        msg = self._loop.run_until_complete(async_read())
-
-        # Need to handle multiple potential message types.
-        if msg.type == aiohttp.WSMsgType.close:
-            # Server is closing connection, shutdown and throw exception.
-            self.close()
-            raise RuntimeError("Connection was closed by server.")
-        elif msg.type == aiohttp.WSMsgType.closed:
-            # Should not be possible since our loop and socket would be closed.
-            raise RuntimeError("Connection was already closed.")
-        elif msg.type == aiohttp.WSMsgType.error:
-            # Error on connection, try to convert message to a string in error.
-            raise RuntimeError("Received error on read: '" + str(msg.data) + "'")
-        elif msg.type == aiohttp.WSMsgType.text:
-            # Convert message to bytes.
-            data = msg.data.strip().encode('utf-8')
-        else:
-            # General handle, return byte data.
-            data = msg.data
-        return data
-
-    def close(self):
-        # Inner function to perform async close.
-        async def async_close():
-            if self._websocket is not None and not self._websocket.closed:
-                await self._websocket.close()
-                self._websocket = None
-
-            if self._client_session is not None and not self._client_session.closed:
-                await self._client_session.close()
-                self._client_session = None
-
-        # If the loop is not closed (connection hasn't already been closed)
-        if not self._loop.is_closed():
-            # Execute the async close synchronously.
-            self._loop.run_until_complete(async_close())
-
-            # Close the event loop.
-            self._loop.close()
-
-    @property
-    def closed(self):
-        # Connection is closed if either the websocket or the client session is closed.
-        return self._websocket.closed or self._client_session.closed
-
-
 class AiohttpHTTPTransport(AbstractBaseTransport):
     nest_asyncio_applied = False
 
-    def __init__(self, message_serializer=None,
-                 call_from_event_loop=None, read_timeout=None, write_timeout=None, **kwargs):
-        if call_from_event_loop is not None and call_from_event_loop and not AiohttpTransport.nest_asyncio_applied:
+    def __init__(self, call_from_event_loop=None, read_timeout=None, write_timeout=None, **kwargs):
+        if call_from_event_loop is not None and call_from_event_loop and not AiohttpHTTPTransport.nest_asyncio_applied:
             """ 
                 The AiohttpTransport implementation uses the asyncio event loop. Because of this, it cannot be called 
                 within an event loop without nest_asyncio. If the code is ever refactored so that it can be called 
@@ -155,19 +39,22 @@ class AiohttpHTTPTransport(AbstractBaseTransport):
             """
             import nest_asyncio
             nest_asyncio.apply()
-            AiohttpTransport.nest_asyncio_applied = True
+            AiohttpHTTPTransport.nest_asyncio_applied = True
 
         # Start event loop and initialize client session and response to None
         self._loop = asyncio.new_event_loop()
         self._client_session = None
         self._http_req_resp = None
         self._enable_ssl = False
-        self._message_serializer = message_serializer
 
         # Set all inner variables to parameters passed in.
         self._aiohttp_kwargs = kwargs
         self._write_timeout = write_timeout
         self._read_timeout = read_timeout
+        if "max_content_length" in self._aiohttp_kwargs:
+            self._max_content_len = self._aiohttp_kwargs.pop("max_content_length")
+        else:
+            self._max_content_len = 10 * 1024 * 1024
         if "ssl_options" in self._aiohttp_kwargs:
             self._ssl_context = self._aiohttp_kwargs.pop("ssl_options")
             self._enable_ssl = True
@@ -210,42 +97,35 @@ class AiohttpHTTPTransport(AbstractBaseTransport):
         # Execute the async write synchronously.
         self._loop.run_until_complete(async_write())
 
-    def read(self):
+    def read(self, stream_chunk=None):
+        if not stream_chunk:
+            raise Exception('missing handling of streamed responses to protocol')
+
         # Inner function to perform async read.
         async def async_read():
-            # TODO: set-up chunked reading
-            # buffer = b""
-            message = {'status': {'code': 0,
-                                  'message': '',
-                                  'exception': ''},
-                       'result': {'meta': {},
-                                  'data': []}}
-            is_first_chunk = True
-
-            async for data, _ in self._http_req_resp.content.iter_chunks():
-                chunk_msg = self._message_serializer.deserialize_message(data, is_first_chunk)
-                if 'result' in chunk_msg:
-                    msg_data = message['result']['data']
-                    chunk_data = chunk_msg['result']['data']
-                    message['result']['data'] = [*msg_data, *chunk_data]
-                if 'status' in chunk_msg:
-                    message.update({'status': chunk_msg['status']})
-                is_first_chunk = False
-
-            msg = {"content": message,  #use deserialzed content
-                   "ok": self._http_req_resp.ok,
-                   "status": self._http_req_resp.status}
-            return msg
-
-            # async with async_timeout.timeout(self._read_timeout):
-            #     data = await self._http_req_resp.read()
-            #     print(self._http_req_resp.headers)
-            #     print(self._http_req_resp.status)
-            #     print(self._http_req_resp.ok)
-            #     print(len(data))
-            #     return {"content": data,
-            #             "ok": self._http_req_resp.ok,
-            #             "status": self._http_req_resp.status}
+            # TODO: potentially refactor to just use streaming and remove transport/protocol
+            async with async_timeout.timeout(self._read_timeout):
+                read_completed = False
+                # aiohttp streaming may not iterate through one whole chunk if it's too large, need to buffer it
+                data_buffer = b""
+                async for data, end_of_http_chunk in self._http_req_resp.content.iter_chunks():
+                    try:
+                        data_buffer += data
+                        if end_of_http_chunk:
+                            if self._max_content_len and len(
+                                    data_buffer) > self._max_content_len:
+                                raise Exception(  # TODO: do we need proper exception class for this?
+                                    f'Response size {len(data_buffer)} exceeds limit {self._max_content_len} bytes')
+                            stream_chunk(data_buffer, read_completed, self._http_req_resp.ok)
+                            data_buffer = b""
+                    except ClientPayloadError:
+                        # server disconnect during streaming will cause ClientPayLoadError from aiohttp
+                        # TODO: double check during refactoring
+                        raise GremlinServerError({'code': 500,
+                                                  'message': 'Server disconnected - please try to reconnect',
+                                                  'exception': ClientPayloadError})
+                read_completed = True
+                stream_chunk(data_buffer, read_completed, self._http_req_resp.ok)
 
         return self._loop.run_until_complete(async_read())
 
diff --git a/gremlin-python/src/main/python/gremlin_python/driver/client.py b/gremlin-python/src/main/python/gremlin_python/driver/client.py
index c6b0bc1f1e..a1d1137afe 100644
--- a/gremlin-python/src/main/python/gremlin_python/driver/client.py
+++ b/gremlin-python/src/main/python/gremlin_python/driver/client.py
@@ -43,8 +43,7 @@ class Client:
 
     def __init__(self, url, traversal_source, protocol_factory=None,
                  transport_factory=None, pool_size=None, max_workers=None,
-                 message_serializer=None, username="", password="",
-                 kerberized_service="", headers=None, session=None,
+                 message_serializer=None, username="", password="", headers=None,
                  enable_user_agent_on_connect=True, **transport_kwargs):
         log.info("Creating Client with url '%s'", url)
 
@@ -56,7 +55,7 @@ class Client:
         self._headers = headers
         self._enable_user_agent_on_connect = enable_user_agent_on_connect
         self._traversal_source = traversal_source
-        if not self._use_http and "max_content_length" not in transport_kwargs:
+        if "max_content_length" not in transport_kwargs:
             transport_kwargs["max_content_length"] = 10 * 1024 * 1024
         if message_serializer is None:
             message_serializer = serializer.GraphBinarySerializersV4()
@@ -64,42 +63,28 @@ class Client:
         self._message_serializer = message_serializer
         self._username = username
         self._password = password
-        self._session = session
-        self._session_enabled = (session is not None and session != "")
+
         if transport_factory is None:
             try:
-                from gremlin_python.driver.aiohttp.transport import (
-                    AiohttpTransport, AiohttpHTTPTransport)
+                from gremlin_python.driver.aiohttp.transport import AiohttpHTTPTransport
             except ImportError:
                 raise Exception("Please install AIOHTTP or pass "
                                 "custom transport factory")
             else:
                 def transport_factory():
-                    if self._use_http:
-                        return AiohttpHTTPTransport(self._message_serializer, **transport_kwargs)
-                    else:
-                        return AiohttpTransport(**transport_kwargs)
+                    if self._protocol_factory is None:
+                        self._protocol_factory = protocol_factory
+                    return AiohttpHTTPTransport(**transport_kwargs)
         self._transport_factory = transport_factory
+
         if protocol_factory is None:
             def protocol_factory():
-                if self._use_http:
-                    return protocol.GremlinServerHTTPProtocol(
-                        self._message_serializer,
-                        username=self._username,
-                        password=self._password)
-                else:
-                    return protocol.GremlinServerWSProtocol(
-                        self._message_serializer,
-                        username=self._username,
-                        password=self._password,
-                        kerberized_service=kerberized_service,
-                        max_content_length=transport_kwargs["max_content_length"])
+                return protocol.GremlinServerHTTPProtocol(
+                    self._message_serializer,
+                    username=self._username,
+                    password=self._password)
         self._protocol_factory = protocol_factory
-        if self._session_enabled:
-            if pool_size is None:
-                pool_size = 1
-            elif pool_size != 1:
-                raise Exception("PoolSize must be 1 on session mode!")
+
         if pool_size is None:
             pool_size = 8
         self._pool_size = pool_size
@@ -139,8 +124,6 @@ class Client:
         if self._closed:
             return
 
-        if self._session_enabled:
-            self._close_session()
         log.info("Closing Client with url '%s'", self._url)
         while not self._pool.empty():
             conn = self._pool.get(True)
@@ -148,17 +131,6 @@ class Client:
         self._executor.shutdown()
         self._closed = True
 
-    def _close_session(self):
-        message = request.RequestMessage(
-            processor='session', op='close',
-            args={'session': str(self._session)})
-        conn = self._pool.get(True)
-        try:
-            write_result_set = conn.write(message).result()
-            return write_result_set.all().result()  # wait for _receive() to finish
-        except protocol.GremlinServerError:
-            pass
-
     def _get_connection(self):
         protocol = self._protocol_factory()
         return connection.Connection(
diff --git a/gremlin-python/src/main/python/gremlin_python/driver/connection.py b/gremlin-python/src/main/python/gremlin_python/driver/connection.py
index 94a3c63cd3..de9a81034d 100644
--- a/gremlin-python/src/main/python/gremlin_python/driver/connection.py
+++ b/gremlin-python/src/main/python/gremlin_python/driver/connection.py
@@ -14,7 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-import uuid
 import queue
 from concurrent.futures import Future
 
@@ -81,10 +80,9 @@ class Connection:
 
     def _receive(self):
         try:
-            while True:
-                data = self._transport.read()
-                status_code = self._protocol.data_received(data, self._result_set)
-                if status_code != 206:
-                    break
+            self._transport.read(self.stream_chunk)
         finally:
             self._pool.put_nowait(self)
+
+    def stream_chunk(self, chunk_data, read_completed=None, http_req_resp=None):
+        self._protocol.data_received(chunk_data, self._result_set, read_completed, http_req_resp)
diff --git a/gremlin-python/src/main/python/gremlin_python/driver/driver_remote_connection.py b/gremlin-python/src/main/python/gremlin_python/driver/driver_remote_connection.py
index 6058a6ba4b..f1fd19d0e8 100644
--- a/gremlin-python/src/main/python/gremlin_python/driver/driver_remote_connection.py
+++ b/gremlin-python/src/main/python/gremlin_python/driver/driver_remote_connection.py
@@ -36,9 +36,8 @@ class DriverRemoteConnection(RemoteConnection):
 
     def __init__(self, url, traversal_source="g", protocol_factory=None,
                  transport_factory=None, pool_size=None, max_workers=None,
-                 username="", password="", kerberized_service='',
-                 message_serializer=None, graphson_reader=None,
-                 graphson_writer=None, headers=None, session=None,
+                 username="", password="",
+                 message_serializer=None, headers=None,
                  enable_user_agent_on_connect=True, **transport_kwargs):
         log.info("Creating DriverRemoteConnection with url '%s'", str(url))
         self.__url = url
@@ -49,23 +48,13 @@ class DriverRemoteConnection(RemoteConnection):
         self.__max_workers = max_workers
         self.__username = username
         self.__password = password
-        self.__kerberized_service = kerberized_service
         self.__message_serializer = message_serializer
-        self.__graphson_reader = graphson_reader
-        self.__graphson_writer = graphson_writer
         self.__headers = headers
-        self.__session = session
         self.__enable_user_agent_on_connect = enable_user_agent_on_connect
         self.__transport_kwargs = transport_kwargs
 
-        # keeps a list of sessions that have been spawned from this DriverRemoteConnection
-        # so that they can be closed if this parent session is closed.
-        self.__spawned_sessions = []
-
-        if message_serializer is None and graphson_reader is not None and graphson_writer is not None:
-            message_serializer = serializer.GraphSONMessageSerializer(
-                reader=graphson_reader,
-                writer=graphson_writer)
+        if message_serializer is None:
+            message_serializer = serializer.GraphBinarySerializersV4()
         self._client = client.Client(url, traversal_source,
                                      protocol_factory=protocol_factory,
                                      transport_factory=transport_factory,
@@ -74,28 +63,14 @@ class DriverRemoteConnection(RemoteConnection):
                                      message_serializer=message_serializer,
                                      username=username,
                                      password=password,
-                                     kerberized_service=kerberized_service,
                                      headers=headers,
-                                     session=session,
                                      enable_user_agent_on_connect=enable_user_agent_on_connect,
                                      **transport_kwargs)
         self._url = self._client._url
         self._traversal_source = self._client._traversal_source
 
     def close(self):
-        # close this client and any DriverRemoteConnection instances spawned from this one
-        # for a session
-        if len(self.__spawned_sessions) > 0:
-            log.info("closing spawned sessions from DriverRemoteConnection with url '%s'", str(self._url))
-            for spawned_session in self.__spawned_sessions:
-                spawned_session.close()
-            self.__spawned_sessions.clear()
-
-        if self.__session:
-            log.info("closing DriverRemoteConnection with url '%s' with session '%s'",
-                         str(self._url), str(self.__session))
-        else:
-            log.info("closing DriverRemoteConnection with url '%s'", str(self._url))
+        log.info("closing DriverRemoteConnection with url '%s'", str(self._url))
 
         self._client.close()
 
@@ -131,36 +106,6 @@ class DriverRemoteConnection(RemoteConnection):
     def is_closed(self):
         return self._client.is_closed()
 
-    def is_session_bound(self):
-        return self.__session is not None
-
-    def create_session(self):
-        log.info("Creating session based connection")
-        if self.is_session_bound():
-            raise Exception('Connection is already bound to a session - child sessions are not allowed')
-        conn = DriverRemoteConnection(self.__url,
-                                      traversal_source=self.__traversal_source,
-                                      protocol_factory=self.__protocol_factory,
-                                      transport_factory=self.__transport_factory,
-                                      pool_size=self.__pool_size,
-                                      max_workers=self.__max_workers,
-                                      username=self.__username,
-                                      password=self.__password,
-                                      kerberized_service=self.__kerberized_service,
-                                      message_serializer=self.__message_serializer,
-                                      graphson_reader=self.__graphson_reader,
-                                      graphson_writer=self.__graphson_writer,
-                                      headers=self.__headers,
-                                      session=uuid.uuid4(),
-                                      enable_user_agent_on_connect=self.__enable_user_agent_on_connect,
-                                      **self.__transport_kwargs)
-        self.__spawned_sessions.append(conn)
-        return conn
-
-    def remove_session(self, session_based_connection):
-        session_based_connection.close()
-        self.__spawned_sessions.remove(session_based_connection)
-
     def commit(self):
         log.info("Submitting commit graph operation.")
         return self._client.submit(Bytecode.GraphOp.commit())
@@ -175,7 +120,8 @@ class DriverRemoteConnection(RemoteConnection):
                                  if x[0] == "withStrategies" and type(x[1]) is OptionsStrategy), None)
         request_options = None
         if options_strategy:
-            allowed_keys = ['evaluationTimeout', 'scriptEvaluationTimeout', 'batchSize', 'requestId', 'userAgent', 'materializeProperties']
+            allowed_keys = ['evaluationTimeout', 'scriptEvaluationTimeout', 'batchSize', 'requestId', 'userAgent',
+                            'materializeProperties']
             request_options = {allowed: options_strategy[1].configuration[allowed] for allowed in allowed_keys
                                if allowed in options_strategy[1].configuration}
         return request_options
diff --git a/gremlin-python/src/main/python/gremlin_python/driver/protocol.py b/gremlin-python/src/main/python/gremlin_python/driver/protocol.py
index 0ed263f6c6..a35c004a2a 100644
--- a/gremlin-python/src/main/python/gremlin_python/driver/protocol.py
+++ b/gremlin-python/src/main/python/gremlin_python/driver/protocol.py
@@ -19,15 +19,6 @@
 import json
 import logging
 import abc
-import base64
-import struct
-
-# import kerberos    Optional dependency imported in relevant codeblock
-
-from gremlin_python.driver import request
-from gremlin_python.driver.resultset import ResultSet
-from gremlin_python.process.translator import Translator
-from gremlin_python.process.traversal import Bytecode
 
 log = logging.getLogger("gremlinpython")
 
@@ -37,13 +28,9 @@ __author__ = 'David M. Brown (davebshow@gmail.com)'
 class GremlinServerError(Exception):
     def __init__(self, status):
         super(GremlinServerError, self).__init__('{0}: {1}'.format(status['code'], status['message']))
-        self._status_attributes = status['attributes']
         self.status_code = status['code']
         self.status_message = status['message']
-
-    @property
-    def status_attributes(self):
-        return self._status_attributes
+        self.status_exception = status['exception']
 
 
 class ConfigurationError(Exception):
@@ -65,136 +52,6 @@ class AbstractBaseProtocol(metaclass=abc.ABCMeta):
         pass
 
 
-# TODO: remove WS protocol & refactor
-class GremlinServerWSProtocol(AbstractBaseProtocol):
-    QOP_AUTH_BIT = 1
-    _kerberos_context = None
-    _max_content_length = 10 * 1024 * 1024
-
-    def __init__(self,
-                 message_serializer,
-                 username='', password='',
-                 kerberized_service='',
-                 max_content_length=10 * 1024 * 1024):
-        self._message_serializer = message_serializer
-        self._username = username
-        self._password = password
-        self._kerberized_service = kerberized_service
-        self._max_content_length = max_content_length
-
-    def connection_made(self, transport):
-        super(GremlinServerWSProtocol, self).connection_made(transport)
-
-    def write(self, request_id, request_message):
-        message = self._message_serializer.serialize_message(request_id, request_message)
-        self._transport.write(message)
-
-    def data_received(self, message, results_dict):
-        # if Gremlin Server cuts off then we get a None for the message
-        if message is None:
-            log.error("Received empty message from server.")
-            raise GremlinServerError({'code': 500,
-                                      'message': 'Server disconnected - please try to reconnect', 'attributes': {}})
-
-        message = self._message_serializer.deserialize_message(message)
-        request_id = message['requestId']
-        result_set = results_dict[request_id] if request_id in results_dict else ResultSet(None, None)
-        status_code = message['status']['code']
-        aggregate_to = message['result']['meta'].get('aggregateTo', 'list')
-        data = message['result']['data']
-        result_set.aggregate_to = aggregate_to
-        if status_code == 407:
-            if self._username and self._password:
-                auth_bytes = b''.join([b'\x00', self._username.encode('utf-8'),
-                                       b'\x00', self._password.encode('utf-8')])
-                auth = base64.b64encode(auth_bytes)
-                request_message = request.RequestMessage(
-                    'traversal', 'authentication', {'sasl': auth.decode()})
-            elif self._kerberized_service:
-                request_message = self._kerberos_received(message)
-            else:
-                error_message = 'Gremlin server requires authentication credentials in DriverRemoteConnection. ' \
-                                'For basic authentication provide username and password. ' \
-                                'For kerberos authentication provide the kerberized_service parameter.'
-                log.error(error_message)
-                raise ConfigurationError(error_message)
-            self.write(request_id, request_message)
-            data = self._transport.read()
-            # Allow for auth handshake with multiple steps
-            return self.data_received(data, results_dict)
-        elif status_code == 204:
-            result_set.stream.put_nowait([])
-            del results_dict[request_id]
-            return status_code
-        elif status_code in [200, 206]:
-            result_set.stream.put_nowait(data)
-            if status_code == 200:
-                result_set.status_attributes = message['status']['attributes']
-                del results_dict[request_id]
-            return status_code
-        else:
-            # This message is going to be huge and kind of hard to read, but in the event of an error,
-            # it can provide invaluable info, so space it out appropriately.
-            log.error("\r\nReceived error message '%s'\r\n\r\nWith results dictionary '%s'",
-                      str(message), str(results_dict))
-            del results_dict[request_id]
-            raise GremlinServerError(message['status'])
-
-    def _kerberos_received(self, message):
-        # Inspired by: https://github.com/thobbs/pure-sasl/blob/0.6.2/puresasl/mechanisms.py
-        #              https://github.com/thobbs/pure-sasl/blob/0.6.2/LICENSE
-        try:
-            import kerberos
-        except ImportError:
-            raise ImportError('Please install gremlinpython[kerberos].')
-
-        # First pass: get service granting ticket and return it to gremlin-server
-        if not self._kerberos_context:
-            try:
-                _, kerberos_context = kerberos.authGSSClientInit(
-                    self._kerberized_service, gssflags=kerberos.GSS_C_MUTUAL_FLAG)
-                kerberos.authGSSClientStep(kerberos_context, '')
-                auth = kerberos.authGSSClientResponse(kerberos_context)
-                self._kerberos_context = kerberos_context
-            except kerberos.KrbError as e:
-                raise ConfigurationError(
-                    'Kerberos authentication requires a valid service name in DriverRemoteConnection, '
-                    'as well as a valid tgt (export KRB5CCNAME) or keytab (export KRB5_KTNAME): ' + str(e))
-            return request.RequestMessage('', 'authentication', {'sasl': auth})
-
-        # Second pass: completion of authentication
-        sasl_response = message['status']['attributes']['sasl']
-        if not self._username:
-            result_code = kerberos.authGSSClientStep(self._kerberos_context, sasl_response)
-            if result_code == kerberos.AUTH_GSS_COMPLETE:
-                self._username = kerberos.authGSSClientUserName(self._kerberos_context)
-            return request.RequestMessage('', 'authentication', {'sasl': ''})
-
-        # Third pass: sasl quality of protection (qop) handshake
-
-        # Gremlin-server Krb5Authenticator only supports qop=QOP_AUTH; use ssl for confidentiality.
-        # Handshake content format:
-        # byte 0: the selected qop. 1==auth, 2==auth-int, 4==auth-conf
-        # byte 1-3: the max length for any buffer sent back and forth on this connection. (big endian)
-        # the rest of the buffer: the authorization user name in UTF-8 - not null terminated.
-        kerberos.authGSSClientUnwrap(self._kerberos_context, sasl_response)
-        data = kerberos.authGSSClientResponse(self._kerberos_context)
-        plaintext_data = base64.b64decode(data)
-        assert len(plaintext_data) == 4, "Unexpected response from gremlin server sasl handshake"
-        word, = struct.unpack('!I', plaintext_data)
-        qop_bits = word >> 24
-        assert self.QOP_AUTH_BIT & qop_bits, "Unexpected sasl qop level received from gremlin server"
-
-        name_length = len(self._username)
-        fmt = '!I' + str(name_length) + 's'
-        word = self.QOP_AUTH_BIT << 24 | self._max_content_length
-        out = struct.pack(fmt, word, self._username.encode("utf-8"), )
-        encoded = base64.b64encode(out).decode('ascii')
-        kerberos.authGSSClientWrap(self._kerberos_context, encoded)
-        auth = kerberos.authGSSClientResponse(self._kerberos_context)
-        return request.RequestMessage('', 'authentication', {'sasl': auth})
-
-
 class GremlinServerHTTPProtocol(AbstractBaseProtocol):
 
     def __init__(self,
@@ -203,6 +60,12 @@ class GremlinServerHTTPProtocol(AbstractBaseProtocol):
         self._message_serializer = message_serializer
         self._username = username
         self._password = password
+        self._response_msg = {'status': {'code': 0,
+                                         'message': '',
+                                         'exception': ''},
+                              'result': {'meta': {},
+                                         'data': []}}
+        self._is_first_chunk = True
 
     def connection_made(self, transport):
         super(GremlinServerHTTPProtocol, self).connection_made(transport)
@@ -224,35 +87,50 @@ class GremlinServerHTTPProtocol(AbstractBaseProtocol):
 
         self._transport.write(message)
 
-    def data_received(self, response, result_set):
-        # if Gremlin Server cuts off then we get a None for the message
-        if response is None:
-            log.error("Received empty message from server.")
-            raise GremlinServerError({'code': 500,
-                                      'message': 'Server disconnected - please try to reconnect', 'attributes': {}})
-
-        if response['ok']:
-            message = response['content']
-            status_code = message['status']['code']
-            aggregate_to = message['result']['meta'].get('aggregateTo', 'list')
-            data = message['result']['data']
+    # data is received in chunks
+    def data_received(self, response_chunk, result_set, read_completed=None, http_req_resp=None):
+        # we shouldn't need to use the http_req_resp code as status is sent in response message, but leaving it for now
+        if read_completed:
+            status_code = self._response_msg['status']['code']
+            aggregate_to = self._response_msg['result']['meta'].get('aggregateTo', 'list')
+            data = self._response_msg['result']['data']
             result_set.aggregate_to = aggregate_to
 
+            # reset response message
+            self._response_msg = {'status': {'code': 0,
+                                             'message': '',
+                                             'exception': ''},
+                                  'result': {'meta': {},
+                                             'data': []}}
+            self._is_first_chunk = True
+
             if status_code == 204 and len(data) == 0:
                 result_set.stream.put_nowait([])
-                return status_code
             elif status_code in [200, 204, 206]:
                 result_set.stream.put_nowait(data)
-                return status_code
             else:
                 log.error("\r\nReceived error message '%s'\r\n\r\nWith result set '%s'",
-                          str(message), str(result_set))
+                          str(self._response_msg), str(result_set))
                 raise GremlinServerError({'code': status_code,
-                                          'message': message['status']['message'],
-                                          'attributes': {}})
+                                          'message': self._response_msg['status']['message'],
+                                          'exception': self._response_msg['status']['exception']})
         else:
-            # TODO check error deserialization after chunking implementation
-            log.error("\r\nReceived error message '%s'\r\n\r\nWith result set '%s'",
-                      str(response['content']), str(result_set))
-            body = json.loads(response['content'])
-            raise GremlinServerError({'code': response['status'], 'message': body['message'], 'attributes': {}})
+            self._response_msg = self._decode_chunk(self._response_msg, response_chunk, self._is_first_chunk)
+            self._is_first_chunk = False
+
+    def _decode_chunk(self, message, data_buffer, is_first_chunk):
+        chunk_msg = self._message_serializer.deserialize_message(data_buffer, is_first_chunk)
+
+        if 'result' in chunk_msg:
+            msg_data = message['result']['data']
+            chunk_data = chunk_msg['result']['data']
+            message['result']['data'] = [*msg_data, *chunk_data]
+        if 'status' in chunk_msg:
+            status_code = chunk_msg['status']['code']
+            if status_code in [200, 204, 206]:
+                message.update({'status': chunk_msg['status']})
+            else:
+                raise GremlinServerError({'code': status_code,
+                                          'message': chunk_msg['status']['message'],
+                                          'exception': chunk_msg['status']['exception']})
+        return message
diff --git a/gremlin-python/src/main/python/gremlin_python/driver/remote_connection.py b/gremlin-python/src/main/python/gremlin_python/driver/remote_connection.py
index 11d4fa9a43..74a0fabd15 100644
--- a/gremlin-python/src/main/python/gremlin_python/driver/remote_connection.py
+++ b/gremlin-python/src/main/python/gremlin_python/driver/remote_connection.py
@@ -43,12 +43,6 @@ class RemoteConnection(object, metaclass=abc.ABCMeta):
     def is_closed(self):
         raise Exception('is_closed() must be implemented')
 
-    def is_session_bound(self):
-        return False
-
-    def create_session(self):
-        raise Exception('createSession() must be implemented');
-
     def commit(self):
         raise Exception('commit() must be implemented')
 
diff --git a/gremlin-python/src/main/python/gremlin_python/driver/serializer.py b/gremlin-python/src/main/python/gremlin_python/driver/serializer.py
index b85a776c03..2e4622a699 100644
--- a/gremlin-python/src/main/python/gremlin_python/driver/serializer.py
+++ b/gremlin-python/src/main/python/gremlin_python/driver/serializer.py
@@ -20,7 +20,6 @@
 import base64
 import logging
 import struct
-import uuid
 import io
 try:
     import ujson as json
@@ -29,274 +28,12 @@ try:
 except ImportError:
     import json
 
-from gremlin_python.structure.io import graphbinaryV1
 from gremlin_python.structure.io import graphbinaryV4
-from gremlin_python.structure.io import graphsonV2d0
-from gremlin_python.structure.io import graphsonV3d0
 from gremlin_python.structure.io.util import Marker
 
 __author__ = 'David M. Brown (davebshow@gmail.com), Lyndon Bauto (lyndonb@bitquilltech.com)'
 
 
-# TODO: remove all classes except for GraphBinarySerializersV4
-class Processor:
-    """Base class for OpProcessor serialization system."""
-
-    def __init__(self, writer):
-        self._writer = writer
-
-    def get_op_args(self, op, args):
-        op_method = getattr(self, op, None)
-        if not op_method:
-            raise Exception("Processor does not support op: {}".format(op))
-        return op_method(args)
-
-
-class Standard(Processor):
-
-    def authentication(self, args):
-        return args
-
-    def eval(self, args):
-        return args
-
-
-class Session(Processor):
-
-    def authentication(self, args):
-        return args
-
-    def eval(self, args):
-        return args
-
-    def close(self, args):
-        return args
-
-    def bytecode(self, args):
-        gremlin = args['gremlin']
-        args['gremlin'] = self._writer.to_dict(gremlin)
-        aliases = args.get('aliases', '')
-        if not aliases:
-            aliases = {'g': 'g'}
-        args['aliases'] = aliases
-        return args
-
-
-class Traversal(Processor):
-
-    def authentication(self, args):
-        return args
-
-    def bytecode(self, args):
-        gremlin = args['gremlin']
-        args['gremlin'] = self._writer.to_dict(gremlin)
-        aliases = args.get('aliases', '')
-        if not aliases:
-            aliases = {'g': 'g'}
-        args['aliases'] = aliases
-        return args
-
-
-class GraphSONMessageSerializer(object):
-    """
-    Message serializer for GraphSON. Allow users to pass custom reader,
-    writer, and version kwargs for custom serialization. Otherwise,
-    use current GraphSON version as default.
-    """
-
-    # KEEP TRACK OF CURRENT DEFAULTS
-    DEFAULT_READER_CLASS = graphsonV3d0.GraphSONReader
-    DEFAULT_WRITER_CLASS = graphsonV3d0.GraphSONWriter
-    DEFAULT_VERSION = b"application/vnd.gremlin-v3.0+json"
-
-    def __init__(self, reader=None, writer=None, version=None):
-        if not version:
-            version = self.DEFAULT_VERSION
-        self._version = version
-        if not reader:
-            reader = self.DEFAULT_READER_CLASS()
-        self._graphson_reader = reader
-        if not writer:
-            writer = self.DEFAULT_WRITER_CLASS()
-        self.standard = Standard(writer)
-        self.traversal = Traversal(writer)
-        self.session = Session(writer)
-
-    @property
-    def version(self):
-        """Read only property"""
-        return self._version
-
-    def get_processor(self, processor):
-        processor = getattr(self, processor, None)
-        if not processor:
-            raise Exception("Unknown processor")
-        return processor
-
-    def serialize_message(self, request_id, request_message):
-        processor = request_message.processor
-        op = request_message.op
-        args = request_message.args
-        if not processor:
-            processor_obj = self.get_processor('standard')
-        else:
-            processor_obj = self.get_processor(processor)
-        args = processor_obj.get_op_args(op, args)
-        message = self.build_message(request_id, processor, op, args)
-        return message
-
-    def build_message(self, request_id, processor, op, args):
-        message = {
-            'requestId': {'@type': 'g:UUID', '@value': request_id},
-            'processor': processor,
-            'op': op,
-            'args': args
-        }
-        return self.finalize_message(message, b"\x21", self.version)
-
-    def finalize_message(self, message, mime_len, mime_type):
-        message = json.dumps(message)
-        message = b''.join([mime_len, mime_type, message.encode('utf-8')])
-        return message
-
-    def deserialize_message(self, message):
-        # for parsing string message via HTTP connections
-        msg = json.loads(message if isinstance(message, str) else message.decode('utf-8'))
-        return self._graphson_reader.to_object(msg)
-
-
-class GraphSONSerializersV2d0(GraphSONMessageSerializer):
-    """Message serializer for GraphSON 2.0"""
-    def __init__(self):
-        reader = graphsonV2d0.GraphSONReader()
-        writer = graphsonV2d0.GraphSONWriter()
-        version = b"application/vnd.gremlin-v2.0+json"
-        super(GraphSONSerializersV2d0, self).__init__(reader, writer, version)
-
-
-class GraphSONSerializersV3d0(GraphSONMessageSerializer):
-    """Message serializer for GraphSON 3.0"""
-    def __init__(self):
-        reader = graphsonV3d0.GraphSONReader()
-        writer = graphsonV3d0.GraphSONWriter()
-        version = b"application/vnd.gremlin-v3.0+json"
-        super(GraphSONSerializersV3d0, self).__init__(reader, writer, version)
-
-
-class GraphBinarySerializersV1(object):
-    DEFAULT_READER_CLASS = graphbinaryV1.GraphBinaryReader
-    DEFAULT_WRITER_CLASS = graphbinaryV1.GraphBinaryWriter
-    DEFAULT_VERSION = b"application/vnd.graphbinary-v1.0"
-
-    max_int64 = 0xFFFFFFFFFFFFFFFF
-    header_struct = struct.Struct('>b32sBQQ')
-    header_pack = header_struct.pack
-    int_pack = graphbinaryV1.int32_pack
-    int32_unpack = struct.Struct(">i").unpack
-
-    def __init__(self, reader=None, writer=None, version=None):
-        if not version:
-            version = self.DEFAULT_VERSION
-        self._version = version
-        if not reader:
-            reader = self.DEFAULT_READER_CLASS()
-        self._graphbinary_reader = reader
-        if not writer:
-            writer = self.DEFAULT_WRITER_CLASS()
-        self._graphbinary_writer = writer
-        self.standard = Standard(writer)
-        self.traversal = Traversal(writer)
-        self.session = Session(writer)
-
-    @property
-    def version(self):
-        """Read only property"""
-        return self._version
-
-    def get_processor(self, processor):
-        processor = getattr(self, processor, None)
-        if not processor:
-            raise Exception("Unknown processor")
-        return processor
-
-    def serialize_message(self, request_id, request_message):
-        processor = request_message.processor
-        op = request_message.op
-        args = request_message.args
-        if not processor:
-            processor_obj = self.get_processor('standard')
-        else:
-            processor_obj = self.get_processor(processor)
-        args = processor_obj.get_op_args(op, args)
-        message = self.build_message(request_id, processor, op, args)
-        return message
-
-    def build_message(self, request_id, processor, op, args):
-        message = {
-            'requestId': request_id,
-            'processor': processor,
-            'op': op,
-            'args': args
-        }
-        return self.finalize_message(message, 0x20, self.version)
-
-    def finalize_message(self, message, mime_len, mime_type):
-        ba = bytearray()
-
-        request_id = uuid.UUID(str(message['requestId']))
-        ba.extend(self.header_pack(mime_len, mime_type, 0x81,
-                                   (request_id.int >> 64) & self.max_int64, request_id.int & self.max_int64))
-
-        op_bytes = message['op'].encode("utf-8")
-        ba.extend(self.int_pack(len(op_bytes)))
-        ba.extend(op_bytes)
-
-        processor_bytes = message['processor'].encode("utf-8")
-        ba.extend(self.int_pack(len(processor_bytes)))
-        ba.extend(processor_bytes)
-
-        args = message["args"]
-        ba.extend(self.int_pack(len(args)))
-        for k, v in args.items():
-            self._graphbinary_writer.to_dict(k, ba)
-
-            # processor_obj.get_op_args in serialize_message() seems to already handle bytecode. in python 3
-            # because bytearray isn't bound to a type in graphbinary it falls through the writeObject() and
-            # just works but python 2 bytearray is bound to ByteBufferType so it writes DataType.bytebuffer
-            # rather than DataType.bytecode and the server gets confused. special casing this for now until
-            # it can be refactored
-            if k == "gremlin" and isinstance(v, bytearray):
-                ba.extend(v)
-            else:
-                self._graphbinary_writer.to_dict(v, ba)
-
-        return bytes(ba)
-
-    def deserialize_message(self, message):
-        # for parsing string message via HTTP connections
-        b = io.BytesIO(base64.b64decode(message) if isinstance(message, str) else message)
-
-        b.read(1)  # version
-
-        request_id = str(self._graphbinary_reader.to_object(b, graphbinaryV1.DataType.uuid))
-        status_code = self.int32_unpack(b.read(4))[0]
-        status_msg = self._graphbinary_reader.to_object(b, graphbinaryV1.DataType.string)
-        status_attrs = self._graphbinary_reader.to_object(b, graphbinaryV1.DataType.map, nullable=False)
-        meta_attrs = self._graphbinary_reader.to_object(b, graphbinaryV1.DataType.map, nullable=False)
-        result = self._graphbinary_reader.to_object(b)
-
-        b.close()
-
-        msg = {'requestId': request_id,
-               'status': {'code': status_code,
-                          'message': status_msg,
-                          'attributes': status_attrs},
-               'result': {'meta': meta_attrs,
-                          'data': result}}
-
-        return msg
-
-
 """
 GraphBinaryV4
 """
@@ -392,7 +129,7 @@ class GraphBinarySerializersV4(object):
 
     def read_payload(self, buffer):
         results = []
-        readable = True;
+        readable = True
         while buffer.readable():  # find method or way to access readable bytes without using buffer.getvalue()
             # print(buffer.tell())
             if buffer.tell() == len(buffer.getvalue()):
diff --git a/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV1.py b/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV1.py
deleted file mode 100644
index 1cc487bc3e..0000000000
--- a/gremlin-python/src/main/python/gremlin_python/structure/io/graphbinaryV1.py
+++ /dev/null
@@ -1,1161 +0,0 @@
-"""
-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.
-"""
-
-import datetime
-import calendar
-import uuid
-import math
-import io
-import struct
-from collections import OrderedDict
-import logging
-
-from struct import pack, unpack
-from aenum import Enum
-from datetime import timedelta
-from gremlin_python import statics
-from gremlin_python.statics import FloatType, BigDecimal, FunctionType, ShortType, IntType, LongType, BigIntType, \
-                                   TypeType, DictType, ListType, SetType, SingleByte, ByteBufferType, GremlinType, \
-                                   SingleChar
-from gremlin_python.process.traversal import Barrier, Binding, Bytecode, Cardinality, Column, Direction, DT, Merge, \
-                                             Operator, Order, Pick, Pop, P, Scope, TextP, Traversal, Traverser, \
-                                             TraversalStrategy, T
-from gremlin_python.process.graph_traversal import GraphTraversal
-from gremlin_python.structure.graph import Graph, Edge, Property, Vertex, VertexProperty, Path
-from gremlin_python.structure.io.util import HashableDict, SymbolUtil
-
-log = logging.getLogger(__name__)
-
-# When we fall back to a superclass's serializer, we iterate over this map.
-# We want that iteration order to be consistent, so we use an OrderedDict,
-# not a dict.
-_serializers = OrderedDict()
-_deserializers = {}
-
-
-# TODO: to be removed
-class DataType(Enum):
-    null = 0xfe
-    int = 0x01
-    long = 0x02
-    string = 0x03
-    date = 0x04
-    timestamp = 0x05
-    clazz = 0x06
-    double = 0x07
-    float = 0x08
-    list = 0x09
-    map = 0x0a
-    set = 0x0b
-    uuid = 0x0c
-    edge = 0x0d
-    path = 0x0e
-    property = 0x0f
-    graph = 0x10                  # not supported - no graph object in python yet
-    vertex = 0x11
-    vertexproperty = 0x12
-    barrier = 0x13
-    binding = 0x14
-    bytecode = 0x15
-    cardinality = 0x16
-    column = 0x17
-    direction = 0x18
-    operator = 0x19
-    order = 0x1a
-    pick = 0x1b
-    pop = 0x1c
-    lambda_ = 0x1d
-    p = 0x1e
-    scope = 0x1f
-    t = 0x20
-    traverser = 0x21
-    bigdecimal = 0x22
-    biginteger = 0x23
-    byte = 0x24
-    bytebuffer = 0x25
-    short = 0x26
-    boolean = 0x27
-    textp = 0x28
-    traversalstrategy = 0x29
-    bulkset = 0x2a
-    tree = 0x2b                   # not supported - no tree object in Python yet
-    metrics = 0x2c
-    traversalmetrics = 0x2d
-    merge = 0x2e
-    dt = 0x2f
-    char = 0x80
-    duration = 0x81
-    inetaddress = 0x82            # todo
-    instant = 0x83                # todo
-    localdate = 0x84              # todo
-    localdatetime = 0x85          # todo
-    localtime = 0x86              # todo
-    monthday = 0x87               # todo
-    offsetdatetime = 0x88         # todo
-    offsettime = 0x89             # todo
-    period = 0x8a                 # todo
-    year = 0x8b                   # todo
-    yearmonth = 0x8c              # todo
-    zonedatetime = 0x8d           # todo
-    zoneoffset = 0x8e             # todo
-    custom = 0x00                 # todo
-
-
-NULL_BYTES = [DataType.null.value, 0x01]
-
-
-def _make_packer(format_string):
-    packer = struct.Struct(format_string)
-    pack = packer.pack
-    unpack = lambda s: packer.unpack(s)[0]
-    return pack, unpack
-
-
-int64_pack, int64_unpack = _make_packer('>q')
-int32_pack, int32_unpack = _make_packer('>i')
-int16_pack, int16_unpack = _make_packer('>h')
-int8_pack, int8_unpack = _make_packer('>b')
-uint64_pack, uint64_unpack = _make_packer('>Q')
-uint8_pack, uint8_unpack = _make_packer('>B')
-float_pack, float_unpack = _make_packer('>f')
-double_pack, double_unpack = _make_packer('>d')
-
-
-class GraphBinaryTypeType(type):
-    def __new__(mcs, name, bases, dct):
-        cls = super(GraphBinaryTypeType, mcs).__new__(mcs, name, bases, dct)
-        if not name.startswith('_'):
-            if cls.python_type:
-                _serializers[cls.python_type] = cls
-            if cls.graphbinary_type:
-                _deserializers[cls.graphbinary_type] = cls
-        return cls
-
-
-class GraphBinaryWriter(object):
-    def __init__(self, serializer_map=None):
-        self.serializers = _serializers.copy()
-        if serializer_map:
-            self.serializers.update(serializer_map)
-
-    def write_object(self, object_data):
-        return self.to_dict(object_data)
-
-    def to_dict(self, obj, to_extend=None):
-        if to_extend is None:
-            to_extend = bytearray()
-
-        if obj is None:
-            to_extend.extend(NULL_BYTES)
-            return
-
-        try:
-            t = type(obj)
-            return self.serializers[t].dictify(obj, self, to_extend)
-        except KeyError:
-            for key, serializer in self.serializers.items():
-                if isinstance(obj, key):
-                    return serializer.dictify(obj, self, to_extend)
-
-        if isinstance(obj, dict):
-            return dict((self.to_dict(k, to_extend), self.to_dict(v, to_extend)) for k, v in obj.items())
-        elif isinstance(obj, set):
-            return set([self.to_dict(o, to_extend) for o in obj])
-        elif isinstance(obj, list):
-            return [self.to_dict(o, to_extend) for o in obj]
-        else:
-            return obj
-
-
-class GraphBinaryReader(object):
-    def __init__(self, deserializer_map=None):
-        self.deserializers = _deserializers.copy()
-        if deserializer_map:
-            self.deserializers.update(deserializer_map)
-
-    def read_object(self, b):
-        if isinstance(b, bytearray):
-            return self.to_object(io.BytesIO(b))
-        elif isinstance(b, io.BufferedIOBase):
-            return self.to_object(b)
-
-    def to_object(self, buff, data_type=None, nullable=True):
-        if data_type is None:
-            bt = uint8_unpack(buff.read(1))
-            if bt == DataType.null.value:
-                if nullable:
-                    buff.read(1)
-                return None
-            return self.deserializers[DataType(bt)].objectify(buff, self, nullable)
-        else:
-            return self.deserializers[data_type].objectify(buff, self, nullable)
-
-
-class _GraphBinaryTypeIO(object, metaclass=GraphBinaryTypeType):
-    python_type = None
-    graphbinary_type = None
-
-    @classmethod
-    def prefix_bytes(cls, graphbin_type, as_value=False, nullable=True, to_extend=None):
-        if to_extend is None:
-            to_extend = bytearray()
-
-        if not as_value:
-            to_extend += uint8_pack(graphbin_type.value)
-
-        if nullable:
-            to_extend += int8_pack(0)
-
-        return to_extend
-
-    @classmethod
-    def read_int(cls, buff):
-        return int32_unpack(buff.read(4))
-
-    @classmethod
-    def is_null(cls, buff, reader, else_opt, nullable=True):
-        return None if nullable and buff.read(1)[0] == 0x01 else else_opt(buff, reader)
-
-    def dictify(self, obj, writer, to_extend, as_value=False, nullable=True):
-        raise NotImplementedError()
-
-    def objectify(self, d, reader, nullable=True):
-        raise NotImplementedError()
-        
-
-class LongIO(_GraphBinaryTypeIO):
-
-    python_type = LongType
-    graphbinary_type = DataType.long
-    byte_format_pack = int64_pack
-    byte_format_unpack = int64_unpack
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        if obj < -9223372036854775808 or obj > 9223372036854775807:
-            raise Exception("Value too big, please use bigint Gremlin type")
-        else:
-            cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-            to_extend.extend(cls.byte_format_pack(obj))
-            return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, lambda b, r: int64_unpack(buff.read(8)), nullable)
-
-
-class IntIO(LongIO):
-
-    python_type = IntType
-    graphbinary_type = DataType.int
-    byte_format_pack = int32_pack
-    byte_format_unpack = int32_unpack
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, lambda b, r: cls.read_int(b), nullable)
-
-
-class ShortIO(LongIO):
-
-    python_type = ShortType
-    graphbinary_type = DataType.short
-    byte_format_pack = int16_pack
-    byte_format_unpack = int16_unpack
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, lambda b, r: int16_unpack(buff.read(2)), nullable)
-
-
-class BigIntIO(_GraphBinaryTypeIO):
-
-    python_type = BigIntType
-    graphbinary_type = DataType.biginteger
-
-    @classmethod
-    def write_bigint(cls, obj, to_extend):
-        length = (obj.bit_length() + 7) // 8
-        if obj > 0:
-            b = obj.to_bytes(length, byteorder='big')
-            to_extend.extend(int32_pack(length + 1))
-            to_extend.extend(int8_pack(0))
-            to_extend.extend(b)
-        else:
-            # handle negative
-            b = obj.to_bytes(length, byteorder='big', signed=True)
-            to_extend.extend(int32_pack(length))
-            to_extend.extend(b)
-        return to_extend
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        return cls.write_bigint(obj, to_extend)
-
-    @classmethod
-    def read_bigint(cls, buff):
-        size = cls.read_int(buff)
-        return int.from_bytes(buff.read(size), byteorder='big', signed=True)
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=False):
-        return cls.is_null(buff, reader, lambda b, r: cls.read_bigint(b), nullable)
-
-
-class DateIO(_GraphBinaryTypeIO):
-
-    python_type = datetime.datetime
-    graphbinary_type = DataType.date
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        try:
-            timestamp_seconds = calendar.timegm(obj.utctimetuple())
-            pts = timestamp_seconds * 1e3 + getattr(obj, 'microsecond', 0) / 1e3
-        except AttributeError:
-            pts = calendar.timegm(obj.timetuple()) * 1e3
-
-        ts = int(round(pts))
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        to_extend.extend(int64_pack(ts))
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader,
-                           lambda b, r: datetime.datetime.utcfromtimestamp(int64_unpack(b.read(8)) / 1000.0),
-                           nullable)
-
-
-# Based on current implementation, this class must always be declared before FloatIO.
-# Seems pretty fragile for future maintainers. Maybe look into this.
-class TimestampIO(_GraphBinaryTypeIO):
-    python_type = statics.timestamp
-    graphbinary_type = DataType.timestamp
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        # Java timestamp expects milliseconds integer - Have to use int because of legacy Python
-        ts = int(round(obj * 1000))
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        to_extend.extend(int64_pack(ts))
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        # Python timestamp expects seconds
-        return cls.is_null(buff, reader, lambda b, r: statics.timestamp(int64_unpack(b.read(8)) / 1000.0),
-                           nullable)
-    
-
-def _long_bits_to_double(bits):
-    return unpack('d', pack('Q', bits))[0]
-
-
-NAN = _long_bits_to_double(0x7ff8000000000000)
-POSITIVE_INFINITY = _long_bits_to_double(0x7ff0000000000000)
-NEGATIVE_INFINITY = _long_bits_to_double(0xFff0000000000000)
-
-
-class FloatIO(LongIO):
-
-    python_type = FloatType
-    graphbinary_type = DataType.float
-    graphbinary_base_type = DataType.float
-    byte_format_pack = float_pack
-    byte_format_unpack = float_unpack
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        if math.isnan(obj):
-            cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-            to_extend.extend(cls.byte_format_pack(NAN))
-        elif math.isinf(obj) and obj > 0:
-            cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-            to_extend.extend(cls.byte_format_pack(POSITIVE_INFINITY))
-        elif math.isinf(obj) and obj < 0:
-            cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-            to_extend.extend(cls.byte_format_pack(NEGATIVE_INFINITY))
-        else:
-            cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-            to_extend.extend(cls.byte_format_pack(obj))
-
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, lambda b, r: float_unpack(b.read(4)), nullable)
-
-
-class DoubleIO(FloatIO):
-    """
-    Floats basically just fall through to double serialization.
-    """
-
-    graphbinary_type = DataType.double
-    graphbinary_base_type = DataType.double
-    byte_format_pack = double_pack
-    byte_format_unpack = double_unpack
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, lambda b, r: double_unpack(b.read(8)), nullable)
-
-
-class BigDecimalIO(_GraphBinaryTypeIO):
-
-    python_type = BigDecimal
-    graphbinary_type = DataType.bigdecimal
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        to_extend.extend(int32_pack(obj.scale))
-        return BigIntIO.write_bigint(obj.unscaled_value, to_extend)
-
-    @classmethod
-    def _read(cls, buff):
-        scale = int32_unpack(buff.read(4))
-        unscaled_value = BigIntIO.read_bigint(buff)
-        return BigDecimal(scale, unscaled_value)
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=False):
-        return cls.is_null(buff, reader, lambda b, r: cls._read(b), nullable)
-
-
-class CharIO(_GraphBinaryTypeIO):
-    python_type = SingleChar
-    graphbinary_type = DataType.char
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        to_extend.extend(obj.encode("utf-8"))
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_char, nullable)
-
-    @classmethod
-    def _read_char(cls, b, r):
-        max_bytes = 4
-        x = b.read(1)
-        while max_bytes > 0:
-            max_bytes = max_bytes - 1
-            try:
-                return x.decode("utf-8")
-            except UnicodeDecodeError:
-                x += b.read(1)
-
-
-class StringIO(_GraphBinaryTypeIO):
-
-    python_type = str
-    graphbinary_type = DataType.string
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        str_bytes = obj.encode("utf-8")
-        to_extend += int32_pack(len(str_bytes))
-        to_extend += str_bytes
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, lambda b, r: b.read(cls.read_int(b)).decode("utf-8"), nullable)
-
-
-class ListIO(_GraphBinaryTypeIO):
-
-    python_type = list
-    graphbinary_type = DataType.list
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        to_extend.extend(int32_pack(len(obj)))
-        for item in obj:
-            writer.to_dict(item, to_extend)
-
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_list, nullable)
-
-    @classmethod
-    def _read_list(cls, b, r):
-        size = cls.read_int(b)
-        the_list = []
-        while size > 0:
-            the_list.append(r.read_object(b))
-            size = size - 1
-
-        return the_list
-
-
-class SetDeserializer(ListIO):
-
-    python_type = SetType
-    graphbinary_type = DataType.set
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return set(ListIO.objectify(buff, reader, nullable))
-
-
-class MapIO(_GraphBinaryTypeIO):
-
-    python_type = DictType
-    graphbinary_type = DataType.map
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-
-        to_extend.extend(int32_pack(len(obj)))
-        for k, v in obj.items():
-            writer.to_dict(k, to_extend)
-            writer.to_dict(v, to_extend)
-
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_map, nullable)
-
-    @classmethod
-    def _read_map(cls, b, r):
-        size = cls.read_int(b)
-        the_dict = {}
-        while size > 0:
-            k = HashableDict.of(r.read_object(b))
-            v = r.read_object(b)
-            the_dict[k] = v
-            size = size - 1
-
-        return the_dict
-
-
-class UuidIO(_GraphBinaryTypeIO):
-
-    python_type = uuid.UUID
-    graphbinary_type = DataType.uuid
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        to_extend.extend(obj.bytes)
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, lambda b, r: uuid.UUID(bytes=b.read(16)), nullable)
-
-
-class EdgeIO(_GraphBinaryTypeIO):
-
-    python_type = Edge
-    graphbinary_type = DataType.edge
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-
-        writer.to_dict(obj.id, to_extend)
-        StringIO.dictify(obj.label, writer, to_extend, True, False)
-        writer.to_dict(obj.inV.id, to_extend)
-        StringIO.dictify(obj.inV.label, writer, to_extend, True, False)
-        writer.to_dict(obj.outV.id, to_extend)
-        StringIO.dictify(obj.outV.label, writer, to_extend, True, False)
-        to_extend.extend(NULL_BYTES)
-        to_extend.extend(NULL_BYTES)
-
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_edge, nullable)
-
-    @classmethod
-    def _read_edge(cls, b, r):
-        edgeid = r.read_object(b)
-        edgelbl = r.to_object(b, DataType.string, False)
-        inv = Vertex(r.read_object(b), r.to_object(b, DataType.string, False))
-        outv = Vertex(r.read_object(b), r.to_object(b, DataType.string, False))
-        b.read(2)
-        properties = r.read_object(b)
-        edge = Edge(edgeid, outv, edgelbl, inv, properties)
-        return edge
-
-
-class PathIO(_GraphBinaryTypeIO):
-
-    python_type = Path
-    graphbinary_type = DataType.path
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        writer.to_dict(obj.labels, to_extend)
-        writer.to_dict(obj.objects, to_extend)
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, lambda b, r: Path(r.read_object(b), r.read_object(b)), nullable)
-
-
-class PropertyIO(_GraphBinaryTypeIO):
-
-    python_type = Property
-    graphbinary_type = DataType.property
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        StringIO.dictify(obj.key, writer, to_extend, True, False)
-        writer.to_dict(obj.value, to_extend)
-        to_extend.extend(NULL_BYTES)
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_property, nullable)
-
-    @classmethod
-    def _read_property(cls, b, r):
-        p = Property(r.to_object(b, DataType.string, False), r.read_object(b), None)
-        b.read(2)
-        return p
-
-
-class TinkerGraphIO(_GraphBinaryTypeIO):
-
-    python_type = Graph
-    graphbinary_type = DataType.graph
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        raise AttributeError("TinkerGraph serialization is not currently supported by gremlin-python")
-
-    @classmethod
-    def objectify(cls, b, reader, as_value=False):
-        raise AttributeError("TinkerGraph deserialization is not currently supported by gremlin-python")
-
-
-class VertexIO(_GraphBinaryTypeIO):
-
-    python_type = Vertex
-    graphbinary_type = DataType.vertex
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        writer.to_dict(obj.id, to_extend)
-        StringIO.dictify(obj.label, writer, to_extend, True, False)
-        to_extend.extend(NULL_BYTES)
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_vertex, nullable)
-
-    @classmethod
-    def _read_vertex(cls, b, r):
-        vertex = Vertex(r.read_object(b), r.to_object(b, DataType.string, False), r.read_object(b))
-        return vertex
-
-
-class VertexPropertyIO(_GraphBinaryTypeIO):
-
-    python_type = VertexProperty
-    graphbinary_type = DataType.vertexproperty
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        writer.to_dict(obj.id, to_extend)
-        StringIO.dictify(obj.label, writer, to_extend, True, False)
-        writer.to_dict(obj.value, to_extend)
-        to_extend.extend(NULL_BYTES)
-        to_extend.extend(NULL_BYTES)
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_vertexproperty, nullable)
-
-    @classmethod
-    def _read_vertexproperty(cls, b, r):
-        vp = VertexProperty(r.read_object(b), r.to_object(b, DataType.string, False), r.read_object(b), None)
-        b.read(2)
-        vp.properties = r.read_object(b)
-        return vp
-
-
-class _EnumIO(_GraphBinaryTypeIO):
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        StringIO.dictify(SymbolUtil.to_camel_case(str(obj.name)), writer, to_extend)
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_enumval, nullable)
-
-    @classmethod
-    def _read_enumval(cls, b, r):
-        enum_name = r.to_object(b)
-        return cls.python_type[SymbolUtil.to_snake_case(enum_name)]
-
-
-class BarrierIO(_EnumIO):
-    graphbinary_type = DataType.barrier
-    python_type = Barrier
-
-
-class CardinalityIO(_EnumIO):
-    graphbinary_type = DataType.cardinality
-    python_type = Cardinality
-
-
-class ColumnIO(_EnumIO):
-    graphbinary_type = DataType.column
-    python_type = Column
-
-
-class DirectionIO(_EnumIO):
-    graphbinary_type = DataType.direction
-    python_type = Direction
-
-    @classmethod
-    def _read_enumval(cls, b, r):
-        # Direction needs to retain all CAPS. note that to_/from_ are really just aliases of IN/OUT
-        # so they don't need to be accounted for in serialization
-        enum_name = r.to_object(b)
-        return cls.python_type[enum_name]
-
-
-class OperatorIO(_EnumIO):
-    graphbinary_type = DataType.operator
-    python_type = Operator
-
-
-class OrderIO(_EnumIO):
-    graphbinary_type = DataType.order
-    python_type = Order
-
-
-class PickIO(_EnumIO):
-    graphbinary_type = DataType.pick
-    python_type = Pick
-
-
-class PopIO(_EnumIO):
-    graphbinary_type = DataType.pop
-    python_type = Pop
-
-
-class BindingIO(_GraphBinaryTypeIO):
-
-    python_type = Binding
-    graphbinary_type = DataType.binding
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        StringIO.dictify(obj.key, writer, to_extend, True, False)
-        writer.to_dict(obj.value, to_extend)
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, lambda b, r: Binding(r.to_object(b, DataType.string, False),
-                                                              reader.read_object(b)), nullable)
-
-
-class BytecodeIO(_GraphBinaryTypeIO):
-    python_type = Bytecode
-    graphbinary_type = DataType.bytecode
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        bc = obj.bytecode if isinstance(obj, Traversal) else obj
-        to_extend.extend(int32_pack(len(bc.step_instructions)))
-        for inst in bc.step_instructions:
-            inst_name, inst_args = inst[0], inst[1:] if len(inst) > 1 else []
-            StringIO.dictify(inst_name, writer, to_extend, True, False)
-            to_extend.extend(int32_pack(len(inst_args)))
-            for arg in inst_args:
-                writer.to_dict(arg, to_extend)
-
-        to_extend.extend(int32_pack(len(bc.source_instructions)))
-        for inst in bc.source_instructions:
-            inst_name, inst_args = inst[0], inst[1:] if len(inst) > 1 else []
-            StringIO.dictify(inst_name, writer, to_extend, True, False)
-            to_extend.extend(int32_pack(len(inst_args)))
-            for arg in inst_args:
-                if isinstance(arg, TypeType):
-                    writer.to_dict(GremlinType(arg().fqcn), to_extend)
-                else:
-                    writer.to_dict(arg, to_extend)
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_bytecode, nullable)
-
-    @classmethod
-    def _read_bytecode(cls, b, r):
-        bytecode = Bytecode()
-
-        step_count = cls.read_int(b)
-        ix = 0
-        while ix < step_count:
-            inst = [r.to_object(b, DataType.string, False)]
-            inst_ct = cls.read_int(b)
-            iy = 0
-            while iy < inst_ct:
-                inst.append(r.read_object(b))
-                iy += 1
-            bytecode.step_instructions.append(inst)
-            ix += 1
-
-        source_count = cls.read_int(b)
-        ix = 0
-        while ix < source_count:
-            inst = [r.to_object(b, DataType.string, False)]
-            inst_ct = cls.read_int(b)
-            iy = 0
-            while iy < inst_ct:
-                inst.append(r.read_object(b))
-                iy += 1
-            bytecode.source_instructions.append(inst)
-            ix += 1
-
-        return bytecode
-
-
-class TraversalIO(BytecodeIO):
-    python_type = GraphTraversal
-
-
-class LambdaSerializer(_GraphBinaryTypeIO):
-
-    python_type = FunctionType
-    graphbinary_type = DataType.lambda_
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-
-        lambda_result = obj()
-        script = lambda_result if isinstance(lambda_result, str) else lambda_result[0]
-        language = statics.default_lambda_language if isinstance(lambda_result, str) else lambda_result[1]
-
-        StringIO.dictify(language, writer, to_extend, True, False)
-
-        script_cleaned = script
-        script_args = -1
-
-        if language == "gremlin-groovy" and "->" in script:
-            # if the user has explicitly added parameters to the groovy closure then we can easily detect one or two
-            # arg lambdas - if we can't detect 1 or 2 then we just go with "unknown"
-            args = script[0:script.find("->")]
-            script_args = 2 if "," in args else 1
-
-        StringIO.dictify(script_cleaned, writer, to_extend, True, False)
-        to_extend.extend(int32_pack(script_args))
-
-        return to_extend
-
-
-class PSerializer(_GraphBinaryTypeIO):
-    graphbinary_type = DataType.p
-    python_type = P
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-
-        StringIO.dictify(obj.operator, writer, to_extend, True, False)
-
-        args = []
-        if obj.other is None:
-            if isinstance(obj.value, ListType):
-                args = obj.value
-            else:
-                args.append(obj.value)
-        else:
-            args.append(obj.value)
-            args.append(obj.other)
-
-        to_extend.extend(int32_pack(len(args)))
-        for a in args:
-            writer.to_dict(a, to_extend)
-
-        return to_extend
-
-
-class DTIO(_EnumIO):
-    graphbinary_type = DataType.dt
-    python_type = DT
-
-
-class MergeIO(_EnumIO):
-    graphbinary_type = DataType.merge
-    python_type = Merge
-
-
-class ScopeIO(_EnumIO):
-    graphbinary_type = DataType.scope
-    python_type = Scope
-
-
-class TIO(_EnumIO):
-    graphbinary_type = DataType.t
-    python_type = T
-
-
-class TraverserIO(_GraphBinaryTypeIO):
-    graphbinary_type = DataType.traverser
-    python_type = Traverser
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        to_extend.extend(int64_pack(obj.bulk))
-        writer.to_dict(obj.object, to_extend)
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_traverser, nullable)
-
-    @classmethod
-    def _read_traverser(cls, b, r):
-        bulk = int64_unpack(b.read(8))
-        obj = r.read_object(b)
-        return Traverser(obj, bulk=bulk)
-
-
-class ByteIO(_GraphBinaryTypeIO):
-    python_type = SingleByte
-    graphbinary_type = DataType.byte
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        to_extend.extend(int8_pack(obj))
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader,
-                           lambda b, r: int.__new__(SingleByte, int8_unpack(b.read(1))),
-                           nullable)
-
-
-class ByteBufferIO(_GraphBinaryTypeIO):
-    python_type = ByteBufferType
-    graphbinary_type = DataType.bytebuffer
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        to_extend.extend(int32_pack(len(obj)))
-        to_extend.extend(obj)
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_bytebuffer, nullable)
-
-    @classmethod
-    def _read_bytebuffer(cls, b, r):
-        size = cls.read_int(b)
-        return ByteBufferType(b.read(size))
-
-
-class BooleanIO(_GraphBinaryTypeIO):
-    python_type = bool
-    graphbinary_type = DataType.boolean
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        to_extend.extend(int8_pack(0x01 if obj else 0x00))
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader,
-                           lambda b, r: True if int8_unpack(b.read(1)) == 0x01 else False,
-                           nullable)
-
-
-class TextPSerializer(_GraphBinaryTypeIO):
-    graphbinary_type = DataType.textp
-    python_type = TextP
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-
-        StringIO.dictify(obj.operator, writer, to_extend, True, False)
-
-        args = []
-        if obj.other is None:
-            if isinstance(obj.value, ListType):
-                args = obj.value
-            else:
-                args.append(obj.value)
-        else:
-            args.append(obj.value)
-            args.append(obj.other)
-
-        to_extend.extend(int32_pack(len(args)))
-        for a in args:
-            writer.to_dict(a, to_extend)
-
-        return to_extend
-
-
-class BulkSetDeserializer(_GraphBinaryTypeIO):
-
-    graphbinary_type = DataType.bulkset
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_bulkset, nullable)
-
-    @classmethod
-    def _read_bulkset(cls, b, r):
-        size = cls.read_int(b)
-        the_list = []
-        while size > 0:
-            itm = r.read_object(b)
-            bulk = int64_unpack(b.read(8))
-            for y in range(bulk):
-                the_list.append(itm)            
-            size = size - 1
-
-        return the_list
-
-
-class MetricsDeserializer(_GraphBinaryTypeIO):
-
-    graphbinary_type = DataType.metrics
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_metrics, nullable)
-
-    @classmethod
-    def _read_metrics(cls, b, r):
-        metricid = r.to_object(b, DataType.string, False)
-        name = r.to_object(b, DataType.string, False)
-        duration = r.to_object(b, DataType.long, nullable=False)
-        counts = r.to_object(b, DataType.map, nullable=False)
-        annotations = r.to_object(b, DataType.map, nullable=False)
-        metrics = r.to_object(b, DataType.list, nullable=False)
-
-        return {"id": metricid,
-                "name": name,
-                "dur": duration,
-                "counts": counts,
-                "annotations": annotations,
-                "metrics": metrics}
-
-
-class TraversalMetricsDeserializer(_GraphBinaryTypeIO):
-
-    graphbinary_type = DataType.traversalmetrics
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_traversalmetrics, nullable)
-
-    @classmethod
-    def _read_traversalmetrics(cls, b, r):
-        duration = r.to_object(b, DataType.long, nullable=False)
-        metrics = r.to_object(b, DataType.list, nullable=False)
-
-        return {"dur": duration,
-                "metrics": metrics}
-
-
-class ClassSerializer(_GraphBinaryTypeIO):
-    graphbinary_type = DataType.clazz
-    python_type = GremlinType
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        StringIO.dictify(obj.gremlin_type, writer, to_extend, True, False)
-        return to_extend
-
-
-class TraversalStrategySerializer(_GraphBinaryTypeIO):
-    graphbinary_type = DataType.traversalstrategy
-    python_type = TraversalStrategy
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-
-        ClassSerializer.dictify(GremlinType(obj.fqcn), writer, to_extend, True, False)
-        conf = {k: cls._convert(v) for k, v in obj.configuration.items()}
-        MapIO.dictify(conf, writer, to_extend, True, False)
-
-        return to_extend
-
-    @classmethod
-    def _convert(cls, v):
-        return v.bytecode if isinstance(v, Traversal) else v
-
-
-class DurationIO(_GraphBinaryTypeIO):
-    python_type = timedelta
-    graphbinary_type = DataType.duration
-
-    @classmethod
-    def dictify(cls, obj, writer, to_extend, as_value=False, nullable=True):
-        cls.prefix_bytes(cls.graphbinary_type, as_value, nullable, to_extend)
-        LongIO.dictify(obj.seconds, writer, to_extend, True, False)
-        IntIO.dictify(obj.microseconds * 1000, writer, to_extend, True, False)
-        return to_extend
-
-    @classmethod
-    def objectify(cls, buff, reader, nullable=True):
-        return cls.is_null(buff, reader, cls._read_duration, nullable)
-    
-    @classmethod
-    def _read_duration(cls, b, r):
-        seconds = r.to_object(b, DataType.long, False)
-        nanos = r.to_object(b, DataType.int, False)
-        return timedelta(seconds=seconds, microseconds=nanos / 1000)
diff --git a/gremlin-python/src/main/python/gremlin_python/structure/io/graphsonV2d0.py b/gremlin-python/src/main/python/gremlin_python/structure/io/graphsonV2d0.py
deleted file mode 100644
index 3e18ec6ac1..0000000000
--- a/gremlin-python/src/main/python/gremlin_python/structure/io/graphsonV2d0.py
+++ /dev/null
@@ -1,664 +0,0 @@
-#
-# 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.
-#
-
-import calendar
-import datetime
-import json
-import uuid
-import math
-from collections import OrderedDict
-from decimal import *
-from datetime import timedelta
-
-from aenum import Enum
-from isodate import parse_duration, duration_isoformat
-
-from gremlin_python import statics
-from gremlin_python.statics import FloatType, FunctionType, ShortType, IntType, LongType, TypeType, SingleByte, ByteBufferType, SingleChar
-from gremlin_python.process.traversal import Binding, Bytecode, P, TextP, Traversal, Traverser, TraversalStrategy
-from gremlin_python.structure.graph import Edge, Property, Vertex, VertexProperty, Path
-from gremlin_python.structure.io.util import SymbolUtil
-
-# When we fall back to a superclass's serializer, we iterate over this map.
-# We want that iteration order to be consistent, so we use an OrderedDict,
-# not a dict.
-_serializers = OrderedDict()
-_deserializers = {}
-
-
-# TODO: to be removed
-class GraphSONTypeType(type):
-    def __new__(mcs, name, bases, dct):
-        cls = super(GraphSONTypeType, mcs).__new__(mcs, name, bases, dct)
-        if not name.startswith('_'):
-            if cls.python_type:
-                _serializers[cls.python_type] = cls
-            if cls.graphson_type:
-                _deserializers[cls.graphson_type] = cls
-        return cls
-
-
-class GraphSONUtil(object):
-    TYPE_KEY = "@type"
-    VALUE_KEY = "@value"
-
-    @classmethod
-    def typed_value(cls, type_name, value, prefix="g"):
-        out = {cls.TYPE_KEY: cls.format_type(prefix, type_name)}
-        if value is not None:
-            out[cls.VALUE_KEY] = value
-        return out
-
-    @classmethod
-    def format_type(cls, prefix, type_name):
-        return "%s:%s" % (prefix, type_name)
-
-
-# Read/Write classes split to follow precedence of the Java API
-class GraphSONWriter(object):
-    def __init__(self, serializer_map=None):
-        """
-        :param serializer_map: map from Python type to serializer instance implementing `dictify`
-        """
-        self.serializers = _serializers.copy()
-        if serializer_map:
-            self.serializers.update(serializer_map)
-
-    def write_object(self, objectData):
-        # to JSON
-        return json.dumps(self.to_dict(objectData), separators=(',', ':'))
-
-    def to_dict(self, obj):
-        """
-        Encodes python objects in GraphSON type-tagged dict values
-        """
-        try:
-            return self.serializers[type(obj)].dictify(obj, self)
-        except KeyError:
-            for key, serializer in self.serializers.items():
-                if isinstance(obj, key):
-                    return serializer.dictify(obj, self)
-
-        # list and map are treated as normal json objs (could be isolated serializers)
-        if isinstance(obj, (list, set)):
-            return [self.to_dict(o) for o in obj]
-        elif isinstance(obj, dict):
-            return dict((self.to_dict(k), self.to_dict(v)) for k, v in obj.items())
-        else:
-            return obj
-
-
-class GraphSONReader(object):
-    def __init__(self, deserializer_map=None):
-        """
-        :param deserializer_map: map from GraphSON type tag to deserializer instance implementing `objectify`
-        """
-        self.deserializers = _deserializers.copy()
-        if deserializer_map:
-            self.deserializers.update(deserializer_map)
-
-    def read_object(self, json_data):
-        # from JSON
-        return self.to_object(json.loads(json_data))
-
-    def to_object(self, obj):
-        """
-        Unpacks GraphSON type-tagged dict values into objects mapped in self.deserializers
-        """
-        if isinstance(obj, dict):
-            try:
-                return self.deserializers[obj[GraphSONUtil.TYPE_KEY]].objectify(obj[GraphSONUtil.VALUE_KEY], self)
-            except KeyError:
-                pass
-            # list and map are treated as normal json objs (could be isolated deserializers)
-            return dict((self.to_object(k), self.to_object(v)) for k, v in obj.items())
-        elif isinstance(obj, list):
-            return [self.to_object(o) for o in obj]
-        else:
-            return obj
-
-
-class _GraphSONTypeIO(object, metaclass=GraphSONTypeType):
-    python_type = None
-    graphson_type = None
-
-    def dictify(self, obj, writer):
-        raise NotImplementedError()
-
-    def objectify(self, d, reader):
-        raise NotImplementedError()
-
-
-class _BytecodeSerializer(_GraphSONTypeIO):
-    @classmethod
-    def _dictify_instructions(cls, instructions, writer):
-        out = []
-        for instruction in instructions:
-            inst = [instruction[0]]
-            inst.extend(writer.to_dict(arg) for arg in instruction[1:])
-            out.append(inst)
-        return out
-
-    @classmethod
-    def dictify(cls, bytecode, writer):
-        if isinstance(bytecode, Traversal):
-            bytecode = bytecode.bytecode
-        out = {}
-        if bytecode.source_instructions:
-            out["source"] = cls._dictify_instructions(bytecode.source_instructions, writer)
-        if bytecode.step_instructions:
-            out["step"] = cls._dictify_instructions(bytecode.step_instructions, writer)
-        return GraphSONUtil.typed_value("Bytecode", out)
-
-class TraversalSerializer(_BytecodeSerializer):
-    python_type = Traversal
-
-
-class BytecodeSerializer(_BytecodeSerializer):
-    python_type = Bytecode
-
-
-class VertexSerializer(_GraphSONTypeIO):
-    python_type = Vertex
-    graphson_type = "g:Vertex"
-
-    @classmethod
-    def dictify(cls, vertex, writer):
-        return GraphSONUtil.typed_value("Vertex", {"id": writer.to_dict(vertex.id),
-                                                   "label": writer.to_dict(vertex.label)})
-
-
-class EdgeSerializer(_GraphSONTypeIO):
-    python_type = Edge
-    graphson_type = "g:Edge"
-
-    @classmethod
-    def dictify(cls, edge, writer):
-        return GraphSONUtil.typed_value("Edge", {"id": writer.to_dict(edge.id),
-                                                 "outV": writer.to_dict(edge.outV.id),
-                                                 "outVLabel": writer.to_dict(edge.outV.label),
-                                                 "label": writer.to_dict(edge.label),
-                                                 "inV": writer.to_dict(edge.inV.id),
-                                                 "inVLabel": writer.to_dict(edge.inV.label)})
-
-
-class VertexPropertySerializer(_GraphSONTypeIO):
-    python_type = VertexProperty
-    graphson_type = "g:VertexProperty"
-
-    @classmethod
-    def dictify(cls, vertex_property, writer):
-        return GraphSONUtil.typed_value("VertexProperty", {"id": writer.to_dict(vertex_property.id),
-                                                           "label": writer.to_dict(vertex_property.label),
-                                                           "value": writer.to_dict(vertex_property.value),
-                                                           "vertex": writer.to_dict(vertex_property.vertex.id)})
-
-
-class PropertySerializer(_GraphSONTypeIO):
-    python_type = Property
-    graphson_type = "g:Property"
-
-    @classmethod
-    def dictify(cls, property, writer):
-        element_dict = writer.to_dict(property.element)
-        if element_dict is not None:
-            value_dict = element_dict["@value"]
-            if "outVLabel" in value_dict:
-                del value_dict["outVLabel"]
-            if "inVLabel" in value_dict:
-                del value_dict["inVLabel"]
-            if "properties" in value_dict:
-                del value_dict["properties"]
-            if "value" in value_dict:
-                del value_dict["value"]
-        return GraphSONUtil.typed_value("Property", {"key": writer.to_dict(property.key),
-                                                    "value": writer.to_dict(property.value),
-                                                    "element": element_dict})
-
-
-class TraversalStrategySerializer(_GraphSONTypeIO):
-    python_type = TraversalStrategy
-
-    @classmethod
-    def dictify(cls, strategy, writer):
-        return GraphSONUtil.typed_value(strategy.strategy_name, writer.to_dict(strategy.configuration))
-
-
-class TraverserIO(_GraphSONTypeIO):
-    python_type = Traverser
-    graphson_type = "g:Traverser"
-
-    @classmethod
-    def dictify(cls, traverser, writer):
-        return GraphSONUtil.typed_value("Traverser", {"value": writer.to_dict(traverser.object),
-                                                     "bulk": writer.to_dict(traverser.bulk)})
-
-    @classmethod
-    def objectify(cls, d, reader):
-        return Traverser(reader.to_object(d["value"]),
-                         reader.to_object(d["bulk"]))
-
-
-class EnumSerializer(_GraphSONTypeIO):
-    python_type = Enum
-
-    @classmethod
-    def dictify(cls, enum, _):
-        return GraphSONUtil.typed_value(SymbolUtil.to_camel_case(type(enum).__name__),
-                                        SymbolUtil.to_camel_case(str(enum.name)))
-
-
-class PSerializer(_GraphSONTypeIO):
-    python_type = P
-
-    @classmethod
-    def dictify(cls, p, writer):
-        out = {"predicate": p.operator,
-               "value": [writer.to_dict(p.value), writer.to_dict(p.other)] if p.other is not None else
-               writer.to_dict(p.value)}
-        return GraphSONUtil.typed_value("P", out)
-
-
-class TextPSerializer(_GraphSONTypeIO):
-    python_type = TextP
-
-    @classmethod
-    def dictify(cls, p, writer):
-        out = {"predicate": p.operator,
-               "value": [writer.to_dict(p.value), writer.to_dict(p.other)] if p.other is not None else
-               writer.to_dict(p.value)}
-        return GraphSONUtil.typed_value("TextP", out)
-
-
-class BindingSerializer(_GraphSONTypeIO):
-    python_type = Binding
-
-    @classmethod
-    def dictify(cls, binding, writer):
-        out = {"key": binding.key,
-               "value": writer.to_dict(binding.value)}
-        return GraphSONUtil.typed_value("Binding", out)
-
-
-class LambdaSerializer(_GraphSONTypeIO):
-    python_type = FunctionType
-
-    @classmethod
-    def dictify(cls, lambda_object, writer):
-        lambda_result = lambda_object()
-        script = lambda_result if isinstance(lambda_result, str) else lambda_result[0]
-        language = statics.default_lambda_language if isinstance(lambda_result, str) else lambda_result[1]
-        out = {"script": script,
-               "language": language}
-        if language == "gremlin-groovy" and "->" in script:
-            # if the user has explicitly added parameters to the groovy closure then we can easily detect one or two
-            # arg lambdas - if we can't detect 1 or 2 then we just go with "unknown"
-            args = script[0:script.find("->")]
-            out["arguments"] = 2 if "," in args else 1
-        else:
-            out["arguments"] = -1
-
-        return GraphSONUtil.typed_value("Lambda", out)
-
-
-class TypeSerializer(_GraphSONTypeIO):
-    python_type = TypeType
-
-    @classmethod
-    def dictify(cls, typ, writer):
-        return writer.to_dict(typ())
-
-
-class UUIDIO(_GraphSONTypeIO):
-    python_type = uuid.UUID
-    graphson_type = "g:UUID"
-    graphson_base_type = "UUID"
-
-    @classmethod
-    def dictify(cls, obj, writer):
-        return GraphSONUtil.typed_value(cls.graphson_base_type, str(obj))
-
-    @classmethod
-    def objectify(cls, d, reader):
-        return cls.python_type(d)
-
-
-class DateIO(_GraphSONTypeIO):
-    python_type = datetime.datetime
-    graphson_type = "g:Date"
-    graphson_base_type = "Date"
-
-    @classmethod
-    def dictify(cls, obj, writer):
-        try:
-            timestamp_seconds = calendar.timegm(obj.utctimetuple())
-            pts = timestamp_seconds * 1e3 + getattr(obj, 'microsecond', 0) / 1e3
-        except AttributeError:
-            pts = calendar.timegm(obj.timetuple()) * 1e3
-
-        ts = int(round(pts))
-        return GraphSONUtil.typed_value(cls.graphson_base_type, ts)
-
-    @classmethod
-    def objectify(cls, ts, reader):
-        # Python timestamp expects seconds
-        return datetime.datetime.utcfromtimestamp(ts / 1000.0)
-
-
-# Based on current implementation, this class must always be declared before FloatIO.
-# Seems pretty fragile for future maintainers. Maybe look into this.
-class TimestampIO(_GraphSONTypeIO):
-    """A timestamp in Python is type float"""
-    python_type = statics.timestamp
-    graphson_type = "g:Timestamp"
-    graphson_base_type = "Timestamp"
-
-    @classmethod
-    def dictify(cls, obj, writer):
-        # Java timestamp expects milliseconds integer
-        # Have to use int because of legacy Python
-        ts = int(round(obj * 1000))
-        return GraphSONUtil.typed_value(cls.graphson_base_type, ts)
-
-    @classmethod
-    def objectify(cls, ts, reader):
-        # Python timestamp expects seconds
-        return cls.python_type(ts / 1000.0)
-
-
-class _NumberIO(_GraphSONTypeIO):
-    @classmethod
-    def dictify(cls, n, writer):
-        if isinstance(n, bool):  # because isinstance(False, int) and isinstance(True, int)
-            return n
-        return GraphSONUtil.typed_value(cls.graphson_base_type, n)
-
-    @classmethod
-    def objectify(cls, v, _):
-        return cls.python_type(v)
-
-
-class FloatIO(_NumberIO):
-    python_type = FloatType
-    graphson_type = "g:Float"
-    graphson_base_type = "Float"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        if isinstance(n, bool):  # because isinstance(False, int) and isinstance(True, int)
-            return n
-        elif math.isnan(n):
-            return GraphSONUtil.typed_value(cls.graphson_base_type, "NaN")
-        elif math.isinf(n) and n > 0:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, "Infinity")
-        elif math.isinf(n) and n < 0:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, "-Infinity")
-        else:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, n)
-
-    @classmethod
-    def objectify(cls, v, _):
-        if isinstance(v, str):
-            if v == 'NaN':
-                return float('nan')
-            elif v == "Infinity":
-                return float('inf')
-            elif v == "-Infinity":
-                return float('-inf')
-
-        return cls.python_type(v)
-
-
-class BigDecimalIO(_NumberIO):
-    python_type = Decimal
-    graphson_type = "gx:BigDecimal"
-    graphson_base_type = "BigDecimal"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        if isinstance(n, bool):  # because isinstance(False, int) and isinstance(True, int)
-            return n
-        elif math.isnan(n):
-            return GraphSONUtil.typed_value(cls.graphson_base_type, "NaN", "gx")
-        elif math.isinf(n) and n > 0:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, "Infinity", "gx")
-        elif math.isinf(n) and n < 0:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, "-Infinity", "gx")
-        else:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, str(n), "gx")
-
-    @classmethod
-    def objectify(cls, v, _):
-        if isinstance(v, str):
-            if v == 'NaN':
-                return Decimal('nan')
-            elif v == "Infinity":
-                return Decimal('inf')
-            elif v == "-Infinity":
-                return Decimal('-inf')
-
-        return Decimal(v)
-
-
-class DoubleIO(FloatIO):
-    graphson_type = "g:Double"
-    graphson_base_type = "Double"
-
-
-class Int64IO(_NumberIO):
-    python_type = LongType
-    graphson_type = "g:Int64"
-    graphson_base_type = "Int64"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        # if we exceed Java long range then we need a BigInteger
-        if isinstance(n, bool):
-            return n
-        elif n < -9223372036854775808 or n > 9223372036854775807:
-            return GraphSONUtil.typed_value("BigInteger", str(n), "gx")
-        else:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, n)
-
-
-class BigIntegerIO(Int64IO):
-    graphson_type = "gx:BigInteger"
-
-
-class Int32IO(Int64IO):
-    python_type = IntType
-    graphson_type = "g:Int32"
-    graphson_base_type = "Int32"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        # if we exceed Java int range then we need a long
-        if isinstance(n, bool):
-            return n
-        elif n < -9223372036854775808 or n > 9223372036854775807:
-            return GraphSONUtil.typed_value("BigInteger", str(n), "gx")
-        elif n < -2147483648 or n > 2147483647:
-            return GraphSONUtil.typed_value("Int64", n)
-        else:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, n)
-
-
-class Int16IO(Int64IO):
-    python_type = ShortType
-    graphson_type = "gx:Int16"
-    graphson_base_type = "Int16"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        # if we exceed Java int range then we need a long
-        if isinstance(n, bool):
-            return n
-        elif n < -9223372036854775808 or n > 9223372036854775807:
-            return GraphSONUtil.typed_value("BigInteger", str(n), "gx")
-        elif n < -2147483648 or n > 2147483647:
-            return GraphSONUtil.typed_value("Int64", n)
-        elif n < -32768 or n > 32767:
-            return GraphSONUtil.typed_value("Int32", n)
-        else:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, n, "gx")
-
-    @classmethod
-    def objectify(cls, v, _):
-        return int.__new__(ShortType, v)
-
-
-class ByteIO(_NumberIO):
-    python_type = SingleByte
-    graphson_type = "gx:Byte"
-    graphson_base_type = "Byte"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        if isinstance(n, bool):  # because isinstance(False, int) and isinstance(True, int)
-            return n
-        return GraphSONUtil.typed_value(cls.graphson_base_type, n, "gx")
-
-    @classmethod
-    def objectify(cls, v, _):
-        return int.__new__(SingleByte, v)
-
-
-class ByteBufferIO(_GraphSONTypeIO):
-    python_type = ByteBufferType
-    graphson_type = "gx:ByteBuffer"
-    graphson_base_type = "ByteBuffer"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        return GraphSONUtil.typed_value(cls.graphson_base_type, "".join(chr(x) for x in n), "gx")
-
-    @classmethod
-    def objectify(cls, v, _):
-        return cls.python_type(v, "utf8")
-
-
-class CharIO(_GraphSONTypeIO):
-    python_type = SingleChar
-    graphson_type = "gx:Char"
-    graphson_base_type = "Char"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        return GraphSONUtil.typed_value(cls.graphson_base_type, n, "gx")
-
-    @classmethod
-    def objectify(cls, v, _):
-        return str.__new__(SingleChar, v)
-
-
-class DurationIO(_GraphSONTypeIO):
-    python_type = timedelta
-    graphson_type = "gx:Duration"
-    graphson_base_type = "Duration"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        return GraphSONUtil.typed_value(cls.graphson_base_type, duration_isoformat(n), "gx")
-
-    @classmethod
-    def objectify(cls, v, _):
-        return parse_duration(v)
-
-
-class VertexDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:Vertex"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        properties = None
-        if "properties" in d:
-            properties = reader.to_object(d["properties"])
-            if properties is not None:
-                properties = [item for sublist in properties.values() for item in sublist]
-        return Vertex(reader.to_object(d["id"]), d.get("label", "vertex"), properties)
-
-
-class EdgeDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:Edge"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        properties = None
-        if "properties" in d:
-            properties = reader.to_object(d["properties"])
-            if properties is not None:
-                properties = list(properties.values())
-        return Edge(reader.to_object(d["id"]),
-                    Vertex(reader.to_object(d["outV"]), d.get("outVLabel", "vertex")),
-                    d.get("label", "edge"),
-                    Vertex(reader.to_object(d["inV"]), d.get("inVLabel", "vertex")),
-                    properties)
-
-
-class VertexPropertyDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:VertexProperty"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        properties = None
-        if "properties" in d:
-            properties = reader.to_object(d["properties"])
-            if properties is not None:
-                properties = list(map(lambda x: Property(x[0], x[1], None), properties.items()))
-        vertex = Vertex(reader.to_object(d.get("vertex"))) if "vertex" in d else None
-        return VertexProperty(reader.to_object(d["id"]),
-                              d["label"],
-                              reader.to_object(d["value"]),
-                              vertex,
-                              properties)
-
-
-class PropertyDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:Property"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        element = reader.to_object(d["element"]) if "element" in d else None
-        return Property(d["key"], reader.to_object(d["value"]), element)
-
-
-class PathDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:Path"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        labels = [set(label) for label in d["labels"]]
-        objects = [reader.to_object(o) for o in d["objects"]]
-        return Path(labels, objects)
-
-
-class TraversalMetricsDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:TraversalMetrics"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        return reader.to_object(d)
-
-
-class MetricsDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:Metrics"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        return reader.to_object(d)
diff --git a/gremlin-python/src/main/python/gremlin_python/structure/io/graphsonV3d0.py b/gremlin-python/src/main/python/gremlin_python/structure/io/graphsonV3d0.py
deleted file mode 100644
index 932d17088a..0000000000
--- a/gremlin-python/src/main/python/gremlin_python/structure/io/graphsonV3d0.py
+++ /dev/null
@@ -1,784 +0,0 @@
-# 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.
-
-import calendar
-import datetime
-import json
-import uuid
-import math
-from collections import OrderedDict
-from decimal import *
-import logging
-from datetime import timedelta
-
-from aenum import Enum
-from isodate import parse_duration, duration_isoformat
-
-from gremlin_python import statics
-from gremlin_python.statics import FloatType, FunctionType, ShortType, IntType, LongType, TypeType, DictType, ListType, SetType, SingleByte, ByteBufferType, SingleChar
-from gremlin_python.process.traversal import Binding, Bytecode, Direction, P, TextP, Traversal, Traverser, TraversalStrategy, T
-from gremlin_python.structure.graph import Edge, Property, Vertex, VertexProperty, Path
-from gremlin_python.structure.io.util import HashableDict, SymbolUtil
-
-log = logging.getLogger(__name__)
-
-# When we fall back to a superclass's serializer, we iterate over this map.
-# We want that iteration order to be consistent, so we use an OrderedDict,
-# not a dict.
-_serializers = OrderedDict()
-_deserializers = {}
-
-
-# TODO: to be removed
-class GraphSONTypeType(type):
-    def __new__(mcs, name, bases, dct):
-        cls = super(GraphSONTypeType, mcs).__new__(mcs, name, bases, dct)
-        if not name.startswith('_'):
-            if cls.python_type:
-                _serializers[cls.python_type] = cls
-            if cls.graphson_type:
-                _deserializers[cls.graphson_type] = cls
-        return cls
-
-
-class GraphSONUtil(object):
-    TYPE_KEY = "@type"
-    VALUE_KEY = "@value"
-
-    @classmethod
-    def typed_value(cls, type_name, value, prefix="g"):
-        out = {cls.TYPE_KEY: cls.format_type(prefix, type_name)}
-        if value is not None:
-            out[cls.VALUE_KEY] = value
-        return out
-
-    @classmethod
-    def format_type(cls, prefix, type_name):
-        return "%s:%s" % (prefix, type_name)
-
-
-# Read/Write classes split to follow precedence of the Java API
-class GraphSONWriter(object):
-    def __init__(self, serializer_map=None):
-        """
-        :param serializer_map: map from Python type to serializer instance implementing `dictify`
-        """
-        self.serializers = _serializers.copy()
-        if serializer_map:
-            self.serializers.update(serializer_map)
-
-    def write_object(self, objectData):
-        # to JSON
-        return json.dumps(self.to_dict(objectData), separators=(',', ':'))
-
-    def to_dict(self, obj):
-        """
-        Encodes python objects in GraphSON type-tagged dict values
-        """
-        try:
-            return self.serializers[type(obj)].dictify(obj, self)
-        except KeyError:
-            for key, serializer in self.serializers.items():
-                if isinstance(obj, key):
-                    return serializer.dictify(obj, self)
-
-        if isinstance(obj, dict):
-            return dict((self.to_dict(k), self.to_dict(v)) for k, v in obj.items())
-        elif isinstance(obj, set):
-            return set([self.to_dict(o) for o in obj])
-        elif isinstance(obj, list):
-            return [self.to_dict(o) for o in obj]
-        else:
-            return obj
-
-
-class GraphSONReader(object):
-    def __init__(self, deserializer_map=None):
-        """
-        :param deserializer_map: map from GraphSON type tag to deserializer instance implementing `objectify`
-        """
-        self.deserializers = _deserializers.copy()
-        if deserializer_map:
-            self.deserializers.update(deserializer_map)
-
-    def read_object(self, json_data):
-        # from JSON
-        return self.to_object(json.loads(json_data))
-
-    def to_object(self, obj):
-        """
-        Unpacks GraphSON type-tagged dict values into objects mapped in self.deserializers
-        """
-        if isinstance(obj, dict):
-            try:
-                return self.deserializers[obj[GraphSONUtil.TYPE_KEY]].objectify(obj[GraphSONUtil.VALUE_KEY], self)
-            except KeyError:
-                pass
-            return dict((self.to_object(k), self.to_object(v)) for k, v in obj.items())
-        elif isinstance(obj, set):
-            return set([self.to_object(o) for o in obj])
-        elif isinstance(obj, list):
-            return [self.to_object(o) for o in obj]
-        else:
-            return obj
-
-
-class _GraphSONTypeIO(object, metaclass=GraphSONTypeType):
-    python_type = None
-    graphson_type = None
-
-    def dictify(self, obj, writer):
-        raise NotImplementedError()
-
-    def objectify(self, d, reader):
-        raise NotImplementedError()
-
-
-class _BytecodeSerializer(_GraphSONTypeIO):
-    @classmethod
-    def _dictify_instructions(cls, instructions, writer):
-        out = []
-        for instruction in instructions:
-            inst = [instruction[0]]
-            inst.extend(writer.to_dict(arg) for arg in instruction[1:])
-            out.append(inst)
-        return out
-
-    @classmethod
-    def dictify(cls, bytecode, writer):
-        if isinstance(bytecode, Traversal):
-            bytecode = bytecode.bytecode
-        out = {}
-        if bytecode.source_instructions:
-            out["source"] = cls._dictify_instructions(bytecode.source_instructions, writer)
-        if bytecode.step_instructions:
-            out["step"] = cls._dictify_instructions(bytecode.step_instructions, writer)
-        return GraphSONUtil.typed_value("Bytecode", out)
-
-
-class TraversalSerializer(_BytecodeSerializer):
-    python_type = Traversal
-
-
-class BytecodeSerializer(_BytecodeSerializer):
-    python_type = Bytecode
-
-
-class VertexSerializer(_GraphSONTypeIO):
-    python_type = Vertex
-    graphson_type = "g:Vertex"
-
-    @classmethod
-    def dictify(cls, vertex, writer):
-        return GraphSONUtil.typed_value("Vertex", {"id": writer.to_dict(vertex.id),
-                                                  "label": writer.to_dict(vertex.label)})
-
-
-class EdgeSerializer(_GraphSONTypeIO):
-    python_type = Edge
-    graphson_type = "g:Edge"
-
-    @classmethod
-    def dictify(cls, edge, writer):
-        return GraphSONUtil.typed_value("Edge", {"id": writer.to_dict(edge.id),
-                                                "outV": writer.to_dict(edge.outV.id),
-                                                "outVLabel": writer.to_dict(edge.outV.label),
-                                                "label": writer.to_dict(edge.label),
-                                                "inV": writer.to_dict(edge.inV.id),
-                                                "inVLabel": writer.to_dict(edge.inV.label)})
-
-
-class VertexPropertySerializer(_GraphSONTypeIO):
-    python_type = VertexProperty
-    graphson_type = "g:VertexProperty"
-
-    @classmethod
-    def dictify(cls, vertex_property, writer):
-        return GraphSONUtil.typed_value("VertexProperty", {"id": writer.to_dict(vertex_property.id),
-                                                          "label": writer.to_dict(vertex_property.label),
-                                                          "value": writer.to_dict(vertex_property.value),
-                                                          "vertex": writer.to_dict(vertex_property.vertex.id)})
-
-
-class PropertySerializer(_GraphSONTypeIO):
-    python_type = Property
-    graphson_type = "g:Property"
-
-    @classmethod
-    def dictify(cls, property, writer):
-        elementDict = writer.to_dict(property.element)
-        if elementDict is not None:
-            valueDict = elementDict["@value"]
-            if "outVLabel" in valueDict:
-                del valueDict["outVLabel"]
-            if "inVLabel" in valueDict:
-                del valueDict["inVLabel"]
-            if "properties" in valueDict:
-                del valueDict["properties"]
-            if "value" in valueDict:
-                del valueDict["value"]
-        return GraphSONUtil.typed_value("Property", {"key": writer.to_dict(property.key),
-                                                    "value": writer.to_dict(property.value),
-                                                    "element": elementDict})
-
-
-class TraversalStrategySerializer(_GraphSONTypeIO):
-    python_type = TraversalStrategy
-
-    @classmethod
-    def dictify(cls, strategy, writer):
-        configuration = {}
-        for key in strategy.configuration:
-            configuration[key] = writer.to_dict(strategy.configuration[key])
-        return GraphSONUtil.typed_value(strategy.strategy_name, configuration)
-
-
-class TraverserIO(_GraphSONTypeIO):
-    python_type = Traverser
-    graphson_type = "g:Traverser"
-
-    @classmethod
-    def dictify(cls, traverser, writer):
-        return GraphSONUtil.typed_value("Traverser", {"value": writer.to_dict(traverser.object),
-                                                     "bulk": writer.to_dict(traverser.bulk)})
-
-    @classmethod
-    def objectify(cls, d, reader):
-        return Traverser(reader.to_object(d["value"]),
-                         reader.to_object(d["bulk"]))
-
-
-class EnumSerializer(_GraphSONTypeIO):
-    python_type = Enum
-
-    @classmethod
-    def dictify(cls, enum, _):
-        return GraphSONUtil.typed_value(SymbolUtil.to_camel_case(type(enum).__name__),
-                                        SymbolUtil.to_camel_case(str(enum.name)))
-
-
-class PSerializer(_GraphSONTypeIO):
-    python_type = P
-
-    @classmethod
-    def dictify(cls, p, writer):
-        out = {"predicate": p.operator,
-               "value": [writer.to_dict(p.value), writer.to_dict(p.other)] if p.other is not None else
-               writer.to_dict(p.value)}
-        return GraphSONUtil.typed_value("P", out)
-
-
-class TextPSerializer(_GraphSONTypeIO):
-    python_type = TextP
-
-    @classmethod
-    def dictify(cls, p, writer):
-        out = {"predicate": p.operator,
-               "value": [writer.to_dict(p.value), writer.to_dict(p.other)] if p.other is not None else
-               writer.to_dict(p.value)}
-        return GraphSONUtil.typed_value("TextP", out)
-
-
-class BindingSerializer(_GraphSONTypeIO):
-    python_type = Binding
-
-    @classmethod
-    def dictify(cls, binding, writer):
-        out = {"key": binding.key,
-               "value": writer.to_dict(binding.value)}
-        return GraphSONUtil.typed_value("Binding", out)
-
-
-class LambdaSerializer(_GraphSONTypeIO):
-    python_type = FunctionType
-
-    @classmethod
-    def dictify(cls, lambda_object, writer):
-        lambda_result = lambda_object()
-        script = lambda_result if isinstance(lambda_result, str) else lambda_result[0]
-        language = statics.default_lambda_language if isinstance(lambda_result, str) else lambda_result[1]
-        out = {"script": script,
-               "language": language}
-        if language == "gremlin-groovy" and "->" in script:
-            # if the user has explicitly added parameters to the groovy closure then we can easily detect one or two
-            # arg lambdas - if we can't detect 1 or 2 then we just go with "unknown"
-            args = script[0:script.find("->")]
-            out["arguments"] = 2 if "," in args else 1
-        else:
-            out["arguments"] = -1
-
-        return GraphSONUtil.typed_value("Lambda", out)
-
-
-class TypeSerializer(_GraphSONTypeIO):
-    python_type = TypeType
-
-    @classmethod
-    def dictify(cls, typ, writer):
-        return writer.to_dict(typ())
-
-
-class UUIDIO(_GraphSONTypeIO):
-    python_type = uuid.UUID
-    graphson_type = "g:UUID"
-    graphson_base_type = "UUID"
-
-    @classmethod
-    def dictify(cls, obj, writer):
-        return GraphSONUtil.typed_value(cls.graphson_base_type, str(obj))
-
-    @classmethod
-    def objectify(cls, d, reader):
-        return cls.python_type(d)
-
-
-class DateIO(_GraphSONTypeIO):
-    python_type = datetime.datetime
-    graphson_type = "g:Date"
-    graphson_base_type = "Date"
-
-    @classmethod
-    def dictify(cls, obj, writer):
-        try:
-            timestamp_seconds = calendar.timegm(obj.utctimetuple())
-            pts = timestamp_seconds * 1e3 + getattr(obj, 'microsecond', 0) / 1e3
-        except AttributeError:
-            pts = calendar.timegm(obj.timetuple()) * 1e3
-
-        ts = int(round(pts))
-        return GraphSONUtil.typed_value(cls.graphson_base_type, ts)
-
-    @classmethod
-    def objectify(cls, ts, reader):
-        # Python timestamp expects seconds
-        return datetime.datetime.utcfromtimestamp(ts / 1000.0)
-
-
-# Based on current implementation, this class must always be declared before FloatIO.
-# Seems pretty fragile for future maintainers. Maybe look into this.
-class TimestampIO(_GraphSONTypeIO):
-    """A timestamp in Python is type float"""
-    python_type = statics.timestamp
-    graphson_type = "g:Timestamp"
-    graphson_base_type = "Timestamp"
-
-    @classmethod
-    def dictify(cls, obj, writer):
-        # Java timestamp expects milliseconds integer
-        # Have to use int because of legacy Python
-        ts = int(round(obj * 1000))
-        return GraphSONUtil.typed_value(cls.graphson_base_type, ts)
-
-    @classmethod
-    def objectify(cls, ts, reader):
-        # Python timestamp expects seconds
-        return cls.python_type(ts / 1000.0)
-
-
-class _NumberIO(_GraphSONTypeIO):
-    @classmethod
-    def dictify(cls, n, writer):
-        if isinstance(n, bool):  # because isinstance(False, int) and isinstance(True, int)
-            return n
-        return GraphSONUtil.typed_value(cls.graphson_base_type, n)
-
-    @classmethod
-    def objectify(cls, v, _):
-        return cls.python_type(v)
-
-
-class ListIO(_GraphSONTypeIO):
-    python_type = ListType
-    graphson_type = "g:List"
-
-    @classmethod
-    def dictify(cls, l, writer):
-        new_list = []
-        for obj in l:
-            new_list.append(writer.to_dict(obj))
-        return GraphSONUtil.typed_value("List", new_list)
-
-    @classmethod
-    def objectify(cls, l, reader):
-        new_list = []
-        for obj in l:
-            new_list.append(reader.to_object(obj))
-        return new_list
-
-
-class SetIO(_GraphSONTypeIO):
-    python_type = SetType
-    graphson_type = "g:Set"
-
-    @classmethod
-    def dictify(cls, s, writer):
-        new_list = []
-        for obj in s:
-            new_list.append(writer.to_dict(obj))
-        return GraphSONUtil.typed_value("Set", new_list)
-
-    @classmethod
-    def objectify(cls, s, reader):
-        """
-        By default, returns a python set
-
-        In case Java returns numeric values of different types which
-        python don't recognize, coerce and return a list.
-        See comments of TINKERPOP-1844 for more details
-        """
-        new_list = [reader.to_object(obj) for obj in s]
-        new_set = set(new_list)
-        if len(new_list) != len(new_set):
-            log.warning("Coercing g:Set to list due to java numeric values. "
-                        "See TINKERPOP-1844 for more details.")
-            return new_list
-
-        return new_set
-
-
-class MapType(_GraphSONTypeIO):
-    python_type = DictType
-    graphson_type = "g:Map"
-
-    @classmethod
-    def dictify(cls, d, writer):
-        l = []
-        for key in d:
-            l.append(writer.to_dict(key))
-            l.append(writer.to_dict(d[key]))
-        return GraphSONUtil.typed_value("Map", l)
-
-    @classmethod
-    def objectify(cls, l, reader):
-        new_dict = {}
-        if len(l) > 0:
-            x = 0
-            while x < len(l):
-                new_dict[HashableDict.of(reader.to_object(l[x]))] = reader.to_object(l[x + 1])
-                x = x + 2
-        return new_dict
-
-
-class BulkSetIO(_GraphSONTypeIO):
-    graphson_type = "g:BulkSet"
-
-    @classmethod
-    def objectify(cls, l, reader):
-        new_list = []
-
-        # this approach basically mimics what currently existed in 3.3.4 and prior versions where BulkSet is
-        # basically just coerced to list. the limitation here is that if the value of a bulk exceeds the size of
-        # a list (into the long space) then stuff won't work nice.
-        if len(l) > 0:
-            x = 0
-            while x < len(l):
-                obj = reader.to_object(l[x])
-                bulk = reader.to_object(l[x + 1])
-                for y in range(bulk):
-                    new_list.append(obj)
-                x = x + 2
-        return new_list
-
-
-class FloatIO(_NumberIO):
-    python_type = FloatType
-    graphson_type = "g:Float"
-    graphson_base_type = "Float"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        if isinstance(n, bool):  # because isinstance(False, int) and isinstance(True, int)
-            return n
-        elif math.isnan(n):
-            return GraphSONUtil.typed_value(cls.graphson_base_type, "NaN")
-        elif math.isinf(n) and n > 0:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, "Infinity")
-        elif math.isinf(n) and n < 0:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, "-Infinity")
-        else:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, n)
-
-    @classmethod
-    def objectify(cls, v, _):
-        if isinstance(v, str):
-            if v == 'NaN':
-                return float('nan')
-            elif v == "Infinity":
-                return float('inf')
-            elif v == "-Infinity":
-                return float('-inf')
-
-        return cls.python_type(v)
-
-
-class BigDecimalIO(_NumberIO):
-    python_type = Decimal
-    graphson_type = "gx:BigDecimal"
-    graphson_base_type = "BigDecimal"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        if isinstance(n, bool):  # because isinstance(False, int) and isinstance(True, int)
-            return n
-        elif math.isnan(n):
-            return GraphSONUtil.typed_value(cls.graphson_base_type, "NaN", "gx")
-        elif math.isinf(n) and n > 0:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, "Infinity", "gx")
-        elif math.isinf(n) and n < 0:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, "-Infinity", "gx")
-        else:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, str(n), "gx")
-
-    @classmethod
-    def objectify(cls, v, _):
-        if isinstance(v, str):
-            if v == 'NaN':
-                return Decimal('nan')
-            elif v == "Infinity":
-                return Decimal('inf')
-            elif v == "-Infinity":
-                return Decimal('-inf')
-
-        return Decimal(v)
-
-
-class DoubleIO(FloatIO):
-    graphson_type = "g:Double"
-    graphson_base_type = "Double"
-
-
-class Int64IO(_NumberIO):
-    python_type = LongType
-    graphson_type = "g:Int64"
-    graphson_base_type = "Int64"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        # if we exceed Java long range then we need a BigInteger
-        if isinstance(n, bool):
-            return n
-        elif n < -9223372036854775808 or n > 9223372036854775807:
-            return GraphSONUtil.typed_value("BigInteger", str(n), "gx")
-        else:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, n)
-
-
-class BigIntegerIO(Int64IO):
-    graphson_type = "gx:BigInteger"
-
-
-class Int32IO(Int64IO):
-    python_type = IntType
-    graphson_type = "g:Int32"
-    graphson_base_type = "Int32"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        # if we exceed Java int range then we need a long
-        if isinstance(n, bool):
-            return n
-        elif n < -9223372036854775808 or n > 9223372036854775807:
-            return GraphSONUtil.typed_value("BigInteger", str(n), "gx")
-        elif n < -2147483648 or n > 2147483647:
-            return GraphSONUtil.typed_value("Int64", n)
-        else:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, n)
-
-
-class Int16IO(Int64IO):
-    python_type = ShortType
-    graphson_type = "gx:Int16"
-    graphson_base_type = "Int16"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        # if we exceed Java int range then we need a long
-        if isinstance(n, bool):
-            return n
-        elif n < -9223372036854775808 or n > 9223372036854775807:
-            return GraphSONUtil.typed_value("BigInteger", str(n), "gx")
-        elif n < -2147483648 or n > 2147483647:
-            return GraphSONUtil.typed_value("Int64", n)
-        elif n < -32768 or n > 32767:
-            return GraphSONUtil.typed_value("Int32", n)
-        else:
-            return GraphSONUtil.typed_value(cls.graphson_base_type, n, "gx")
-
-    @classmethod
-    def objectify(cls, v, _):
-        return int.__new__(ShortType, v)
-
-
-class ByteIO(_NumberIO):
-    python_type = SingleByte
-    graphson_type = "gx:Byte"
-    graphson_base_type = "Byte"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        if isinstance(n, bool):  # because isinstance(False, int) and isinstance(True, int)
-            return n
-        return GraphSONUtil.typed_value(cls.graphson_base_type, n, "gx")
-
-    @classmethod
-    def objectify(cls, v, _):
-        return int.__new__(SingleByte, v)
-
-
-class ByteBufferIO(_GraphSONTypeIO):
-    python_type = ByteBufferType
-    graphson_type = "gx:ByteBuffer"
-    graphson_base_type = "ByteBuffer"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        return GraphSONUtil.typed_value(cls.graphson_base_type, "".join(chr(x) for x in n), "gx")
-
-    @classmethod
-    def objectify(cls, v, _):
-        return cls.python_type(v, "utf8")
-
-
-class CharIO(_GraphSONTypeIO):
-    python_type = SingleChar
-    graphson_type = "gx:Char"
-    graphson_base_type = "Char"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        return GraphSONUtil.typed_value(cls.graphson_base_type, n, "gx")
-
-    @classmethod
-    def objectify(cls, v, _):
-        return str.__new__(SingleChar, v)
-
-
-class DurationIO(_GraphSONTypeIO):
-    python_type = timedelta
-    graphson_type = "gx:Duration"
-    graphson_base_type = "Duration"
-
-    @classmethod
-    def dictify(cls, n, writer):
-        return GraphSONUtil.typed_value(cls.graphson_base_type, duration_isoformat(n), "gx")
-
-    @classmethod
-    def objectify(cls, v, _):
-        return parse_duration(v)
-
-
-class VertexDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:Vertex"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        properties = None
-        if "properties" in d:
-            properties = reader.to_object(d["properties"])
-            if properties is not None:
-                properties = [item for sublist in properties.values() for item in sublist]
-        return Vertex(reader.to_object(d["id"]), d.get("label", "vertex"), properties)
-
-
-class EdgeDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:Edge"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        properties = None
-        if "properties" in d:
-            properties = reader.to_object(d["properties"])
-            if properties is not None:
-                properties = list(properties.values())
-        return Edge(reader.to_object(d["id"]),
-                    Vertex(reader.to_object(d["outV"]), d.get("outVLabel", "vertex")),
-                    d.get("label", "edge"),
-                    Vertex(reader.to_object(d["inV"]), d.get("inVLabel", "vertex")),
-                    properties)
-
-
-class VertexPropertyDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:VertexProperty"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        properties = None
-        if "properties" in d:
-            properties = reader.to_object(d["properties"])
-            if properties is not None:
-                properties = list(map(lambda x: Property(x[0], x[1], None), properties.items()))
-        vertex = Vertex(reader.to_object(d.get("vertex"))) if "vertex" in d else None
-        return VertexProperty(reader.to_object(d["id"]),
-                              d["label"],
-                              reader.to_object(d["value"]),
-                              vertex,
-                              properties)
-
-
-class PropertyDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:Property"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        element = reader.to_object(d["element"]) if "element" in d else None
-        return Property(d["key"], reader.to_object(d["value"]), element)
-
-
-class PathDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:Path"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        return Path(reader.to_object(d["labels"]), reader.to_object(d["objects"]))
-
-
-class TDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:T"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        return T[d]
-
-
-class DirectionIO(_GraphSONTypeIO):
-    graphson_type = "g:Direction"
-    graphson_base_type = "Direction"
-    python_type = Direction
-
-    @classmethod
-    def dictify(cls, d, writer):
-        return GraphSONUtil.typed_value(cls.graphson_base_type, d.name, "g")
-
-    @classmethod
-    def objectify(cls, d, reader):
-        return Direction[d]
-
-
-class TraversalMetricsDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:TraversalMetrics"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        return reader.to_object(d)
-
-
-class MetricsDeserializer(_GraphSONTypeIO):
-    graphson_type = "g:Metrics"
-
-    @classmethod
-    def objectify(cls, d, reader):
-        return reader.to_object(d)
diff --git a/gremlin-python/src/main/python/tests/conftest.py b/gremlin-python/src/main/python/tests/conftest.py
index c09237d608..f362a1f515 100644
--- a/gremlin-python/src/main/python/tests/conftest.py
+++ b/gremlin-python/src/main/python/tests/conftest.py
@@ -21,42 +21,23 @@ import concurrent.futures
 import os
 import ssl
 import pytest
-import socket
 import logging
 import queue
 
-import yaml
 
 from gremlin_python.driver.client import Client
 from gremlin_python.driver.connection import Connection
-from gremlin_python.driver import serializer
-from gremlin_python.driver.driver_remote_connection import (
-    DriverRemoteConnection)
-from gremlin_python.driver.protocol import GremlinServerWSProtocol, GremlinServerHTTPProtocol
-from gremlin_python.driver.serializer import (
-    GraphSONMessageSerializer, GraphSONSerializersV2d0, GraphSONSerializersV3d0,
-    GraphBinarySerializersV1, GraphBinarySerializersV4)
-from gremlin_python.driver.aiohttp.transport import AiohttpTransport, AiohttpHTTPTransport
+from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
+from gremlin_python.driver.protocol import GremlinServerHTTPProtocol
+from gremlin_python.driver.serializer import GraphBinarySerializersV4
+from gremlin_python.driver.aiohttp.transport import AiohttpHTTPTransport
 
 
-# TODO: update or remove once all implementations are finalized
-gremlin_server_url = os.environ.get('GREMLIN_SERVER_URL', 'ws://localhost:{}/gremlin')
-gremlin_basic_auth_url = os.environ.get('GREMLIN_SERVER_BASIC_AUTH_URL', 'wss://localhost:{}/gremlin')
-gremlin_socket_server_url = os.environ.get('GREMLIN_SOCKET_SERVER_URL', 'ws://localhost:{}/gremlin')
-gremlin_socket_server_config_path = os.environ.get("GREMLIN_SOCKET_SERVER_CONFIG_PATH",
-                                                   "../../../../../../gremlin-tools/gremlin-socket-server/conf/"
-                                                   "test-ws-gremlin.yaml")
-kerberos_hostname = os.environ.get('KRB_HOSTNAME', socket.gethostname())
+"""HTTP server testing variables"""
+gremlin_server_url = os.environ.get('GREMLIN_SERVER_URL_HTTP', 'http://localhost:{}/')
+gremlin_basic_auth_url = os.environ.get('GREMLIN_SERVER_BASIC_AUTH_URL_HTTP', 'https://localhost:{}/')
 anonymous_url = gremlin_server_url.format(45940)
 basic_url = gremlin_basic_auth_url.format(45941)
-kerberos_url = gremlin_server_url.format(45942)
-kerberized_service = 'test-service@{}'.format(kerberos_hostname)
-
-"""HTTP server testing variables"""
-gremlin_server_url_http = os.environ.get('GREMLIN_SERVER_URL_HTTP', 'http://localhost:{}/')
-gremlin_basic_auth_url_http = os.environ.get('GREMLIN_SERVER_BASIC_AUTH_URL_HTTP', 'https://localhost:{}/')
-anonymous_url_http = gremlin_server_url_http.format(45940)
-basic_url_http = gremlin_basic_auth_url_http.format(45941)
 
 verbose_logging = False
 
@@ -64,254 +45,18 @@ logging.basicConfig(format='%(asctime)s [%(levelname)8s] [%(filename)15s:%(linen
                     level=logging.DEBUG if verbose_logging else logging.INFO)
 
 
-@pytest.fixture
-def connection(request):
-    protocol = GremlinServerWSProtocol(
-        GraphSONMessageSerializer(),
-        username='stephen', password='password')
-    executor = concurrent.futures.ThreadPoolExecutor(5)
-    pool = queue.Queue()
-    try:
-        conn = Connection(anonymous_url, 'gmodern', protocol,
-                          lambda: AiohttpTransport(), executor, pool)
-    except OSError:
-        executor.shutdown()
-        pytest.skip('Gremlin Server is not running')
-    else:
-        def fin():
-            executor.shutdown()
-            conn.close()
-
-        request.addfinalizer(fin)
-        return conn
-
-
-@pytest.fixture
-def client(request):
-    try:
-        client = Client(anonymous_url, 'gmodern')
-    except OSError:
-        pytest.skip('Gremlin Server is not running')
-    else:
-        def fin():
-            client.close()
-
-        request.addfinalizer(fin)
-        return client
-
-
-@pytest.fixture
-def gremlin_socket_server_serializer(socket_server_settings):
-    if socket_server_settings["SERIALIZER"] == "GraphBinaryV1":
-        return serializer.GraphBinarySerializersV1()
-    elif socket_server_settings["SERIALIZER"] == "GraphSONV2":
-        return serializer.GraphSONSerializersV2d0()
-    elif socket_server_settings["SERIALIZER"] == "GraphSONV3":
-        return serializer.GraphSONSerializersV3d0()
-    else:
-        return serializer.GraphBinarySerializersV1()
-
-
-@pytest.fixture
-def socket_server_client(request, socket_server_settings, gremlin_socket_server_serializer):
-    url = gremlin_socket_server_url.format(socket_server_settings["PORT"])
-    try:
-        client = Client(url, 'g', pool_size=1, message_serializer=gremlin_socket_server_serializer)
-    except OSError:
-        pytest.skip('Gremlin Socket Server is not running')
-    else:
-        def fin():
-            client.close()
-
-        request.addfinalizer(fin)
-        return client
-
-
-@pytest.fixture
-def socket_server_client_no_user_agent(request, socket_server_settings, gremlin_socket_server_serializer):
-    url = gremlin_socket_server_url.format(socket_server_settings["PORT"])
-    try:
-        client = Client(url, 'g', pool_size=1, message_serializer=gremlin_socket_server_serializer,
-                        enable_user_agent_on_connect=False)
-    except OSError:
-        pytest.skip('Gremlin Socket Server is not running')
-    else:
-        def fin():
-            client.close()
-
-        request.addfinalizer(fin)
-        return client
-
-
-@pytest.fixture
-def socket_server_settings():
-    with open(gremlin_socket_server_config_path, mode="rb") as file:
-        settings = yaml.safe_load(file)
-    return settings
-
-@pytest.fixture(params=['basic', 'kerberos'])
-def authenticated_client(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
-            client = Client(basic_url, 'gmodern', username='stephen', password='password',
-                            transport_factory=lambda: AiohttpTransport(ssl_options=ssl_opts))
-        elif request.param == 'kerberos':
-            client = Client(kerberos_url, 'gmodern', kerberized_service=kerberized_service)
-        else:
-            raise ValueError("Invalid authentication option - " + request.param)
-    except OSError:
-        pytest.skip('Gremlin Server is not running')
-    else:
-        def fin():
-            client.close()
-
-        request.addfinalizer(fin)
-        return client
-
-
-@pytest.fixture(params=['graphsonv2', 'graphsonv3', 'graphbinaryv1'])
-def remote_connection(request):
-    try:
-        if request.param == 'graphbinaryv1':
-            remote_conn = DriverRemoteConnection(anonymous_url, 'gmodern',
-                                                 message_serializer=serializer.GraphBinarySerializersV1())
-        elif request.param == 'graphsonv2':
-            remote_conn = DriverRemoteConnection(anonymous_url, 'gmodern',
-                                                 message_serializer=serializer.GraphSONSerializersV2d0())
-        elif request.param == 'graphsonv3':
-            remote_conn = DriverRemoteConnection(anonymous_url, 'gmodern',
-                                                 message_serializer=serializer.GraphSONSerializersV3d0())
-        else:
-            raise ValueError("Invalid serializer option - " + request.param)
-    except OSError:
-        pytest.skip('Gremlin Server is not running')
-    else:
-        def fin():
-            remote_conn.close()
-
-        request.addfinalizer(fin)
-        return remote_conn
-
-
-@pytest.fixture(params=['graphsonv2', 'graphsonv3', 'graphbinaryv1'])
-def remote_connection_crew(request):
-    try:
-        if request.param == 'graphbinaryv1':
-            remote_conn = DriverRemoteConnection(anonymous_url, 'gcrew',
-                                                 message_serializer=serializer.GraphBinarySerializersV1())
-        elif request.param == 'graphsonv2':
-            remote_conn = DriverRemoteConnection(anonymous_url, 'gcrew',
-                                                 message_serializer=serializer.GraphSONSerializersV2d0())
-        elif request.param == 'graphsonv3':
-            remote_conn = DriverRemoteConnection(anonymous_url, 'gcrew',
-                                                 message_serializer=serializer.GraphSONSerializersV3d0())
-        else:
-            raise ValueError("Invalid serializer option - " + request.param)
-    except OSError:
-        pytest.skip('Gremlin Server is not running')
-    else:
-        def fin():
-            remote_conn.close()
-
-        request.addfinalizer(fin)
-        return remote_conn
-
-
-@pytest.fixture(params=['graphsonv2', 'graphsonv3', 'graphbinaryv1'])
-def remote_transaction_connection(request):
-    try:
-        if request.param == 'graphbinaryv1':
-            remote_conn = DriverRemoteConnection(anonymous_url, 'gtx',
-                                                 message_serializer=serializer.GraphBinarySerializersV1())
-        elif request.param == 'graphsonv2':
-            remote_conn = DriverRemoteConnection(anonymous_url, 'gtx',
-                                                 message_serializer=serializer.GraphSONSerializersV2d0())
-        elif request.param == 'graphsonv3':
-            remote_conn = DriverRemoteConnection(anonymous_url, 'gtx',
-                                                 message_serializer=serializer.GraphSONSerializersV3d0())
-        else:
-            raise ValueError("Invalid serializer option - " + request.param)
-    except OSError:
-        pytest.skip('Gremlin Server is not running')
-    else:
-        def fin():
-            remote_conn.close()
-
-        request.addfinalizer(fin)
-        return remote_conn
-
-
-@pytest.fixture(params=['basic', 'kerberos'])
-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(),
-                                                 transport_factory=lambda: AiohttpTransport(ssl_options=ssl_opts))
-        elif request.param == 'kerberos':
-            remote_conn = DriverRemoteConnection(kerberos_url, 'gmodern', kerberized_service=kerberized_service,
-                                                 message_serializer=serializer.GraphSONSerializersV2d0())
-        else:
-            raise ValueError("Invalid authentication option - " + request.param)
-    except OSError:
-        pytest.skip('Gremlin Server is not running')
-    else:
-        def fin():
-            remote_conn.close()
-
-        request.addfinalizer(fin)
-        return remote_conn
-
-
-@pytest.fixture
-def remote_connection_graphsonV2(request):
-    try:
-        remote_conn = DriverRemoteConnection(anonymous_url,
-                                             message_serializer=serializer.GraphSONSerializersV2d0())
-    except OSError:
-        pytest.skip('Gremlin Server is not running')
-    else:
-        def fin():
-            remote_conn.close()
-
-        request.addfinalizer(fin)
-        return remote_conn
-
-
-@pytest.fixture
-def graphson_serializer_v2(request):
-    return GraphSONSerializersV2d0()
-
-
-@pytest.fixture
-def graphson_serializer_v3(request):
-    return GraphSONSerializersV3d0()
-
-
-@pytest.fixture
-def graphbinary_serializer_v1(request):
-    return GraphBinarySerializersV1()
-
-
 """
 Tests below are for the HTTP server with GraphBinaryV4
 """
 @pytest.fixture
-def connection_http(request):
+def connection(request):
     protocol = GremlinServerHTTPProtocol(
         GraphBinarySerializersV4(),
         username='stephen', password='password')
     executor = concurrent.futures.ThreadPoolExecutor(5)
     pool = queue.Queue()
     try:
-        conn = Connection(anonymous_url_http, 'gmodern', protocol,
+        conn = Connection(anonymous_url, 'gmodern', protocol,
                           lambda: AiohttpHTTPTransport(), executor, pool)
     except OSError:
         executor.shutdown()
@@ -326,9 +71,9 @@ def connection_http(request):
 
 
 @pytest.fixture
-def client_http(request):
+def client(request):
     try:
-        client = Client(anonymous_url_http, 'gmodern')
+        client = Client(anonymous_url, 'gmodern')
     except OSError:
         pytest.skip('Gremlin Server is not running')
     else:
@@ -340,13 +85,13 @@ def client_http(request):
 
 
 @pytest.fixture(params=['basic'])
-def authenticated_client_http(request):
+def authenticated_client(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
-            client = Client(basic_url_http, 'gmodern', username='stephen', password='password',
+            client = Client(basic_url, 'gmodern', username='stephen', password='password',
                             transport_factory=lambda: AiohttpHTTPTransport(ssl_options=ssl_opts))
         else:
             raise ValueError("Invalid authentication option - " + request.param)
@@ -366,10 +111,10 @@ def graphbinary_serializer_v4(request):
 
 
 @pytest.fixture(params=['graphbinaryv4'])
-def remote_connection_http(request):
+def remote_connection(request):
     try:
         if request.param == 'graphbinaryv4':
-            remote_conn = DriverRemoteConnection(anonymous_url_http, 'gmodern')
+            remote_conn = DriverRemoteConnection(anonymous_url, 'gmodern')
         else:
             raise ValueError("Invalid serializer option - " + request.param)
     except OSError:
@@ -383,10 +128,10 @@ def remote_connection_http(request):
 
 
 @pytest.fixture(params=['graphbinaryv4'])
-def remote_connection_http_crew(request):
+def remote_connection_crew(request):
     try:
         if request.param == 'graphbinaryv4':
-            remote_conn = DriverRemoteConnection(anonymous_url_http, 'gcrew')
+            remote_conn = DriverRemoteConnection(anonymous_url, 'gcrew')
         else:
             raise ValueError("Invalid serializer option - " + request.param)
     except OSError:
@@ -401,13 +146,13 @@ def remote_connection_http_crew(request):
 
 # TODO: revisit once auth is updated
 @pytest.fixture(params=['basic'])
-def remote_connection_http_authenticated(request):
+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_http, 'gmodern',
+            remote_conn = DriverRemoteConnection(basic_url, 'gmodern',
                                                  username='stephen', password='password',
                                                  transport_factory=lambda: AiohttpHTTPTransport(ssl_options=ssl_opts))
         else:
@@ -423,10 +168,10 @@ def remote_connection_http_authenticated(request):
 
 
 @pytest.fixture(params=['graphbinaryv4'])
-def invalid_alias_remote_connection_http(request):
+def invalid_alias_remote_connection(request):
     try:
         if request.param == 'graphbinaryv4':
-            remote_conn = DriverRemoteConnection(anonymous_url_http, 'does_not_exist')
+            remote_conn = DriverRemoteConnection(anonymous_url, 'does_not_exist')
         else:
             raise ValueError("Invalid serializer option - " + request.param)
     except OSError:
diff --git a/gremlin-python/src/main/python/tests/driver/test_client.py b/gremlin-python/src/main/python/tests/driver/test_client.py
index d83788ed4c..560a08129a 100644
--- a/gremlin-python/src/main/python/tests/driver/test_client.py
+++ b/gremlin-python/src/main/python/tests/driver/test_client.py
@@ -22,7 +22,6 @@ import threading
 import uuid
 
 import pytest
-from gremlin_python.driver import serializer
 from gremlin_python.driver.client import Client
 from gremlin_python.driver.protocol import GremlinServerError
 from gremlin_python.driver.request import RequestMessageV4
@@ -30,142 +29,157 @@ from gremlin_python.process.graph_traversal import __, GraphTraversalSource
 from gremlin_python.process.traversal import TraversalStrategies
 from gremlin_python.process.strategies import OptionsStrategy
 from gremlin_python.structure.graph import Graph, Vertex
-from gremlin_python.driver.aiohttp.transport import AiohttpTransport, AiohttpHTTPTransport
+from gremlin_python.driver.aiohttp.transport import AiohttpHTTPTransport
 from gremlin_python.statics import *
 from asyncio import TimeoutError
 
 __author__ = 'David M. Brown (davebshow@gmail.com)'
 
-gremlin_server_url_http = os.environ.get('GREMLIN_SERVER_URL_HTTP', 'http://localhost:{}/')
-test_no_auth_http_url = gremlin_server_url_http.format(45940)
+gremlin_server_url = os.environ.get('GREMLIN_SERVER_URL_HTTP', 'http://localhost:{}/')
+test_no_auth_url = gremlin_server_url.format(45940)
 
 
 def create_basic_request_message(traversal, source='gmodern', type='bytecode'):
     return RequestMessageV4(fields={'g': source, 'gremlinType': type}, gremlin=traversal.bytecode)
 
 
-@pytest.mark.skip(reason="needs additional updates")
-def test_connection(connection_http):
+def test_connection(connection):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.V()
     message = create_basic_request_message(t)
-    results_set = connection_http.write(message).result()
+    results_set = connection.write(message).result()
     future = results_set.all()
     results = future.result()
     assert len(results) == 6
     assert isinstance(results, list)
     assert results_set.done.done()
-    assert 'host' in results_set.status_attributes
 
 
-@pytest.mark.skip(reason="needs additional updates")
-def test_client_message_too_big(client_http):
+def test_client_message_too_big(client):
     try:
-        client_http = Client(test_no_auth_http_url, 'g', max_content_length=4096)
-        client_http.submit("\" \"*8000").all().result()
+        client = Client(test_no_auth_url, 'g', max_content_length=4096)
+        client.submit("\" \"*8000").all().result()
         assert False
     except Exception as ex:
-        assert ex.args[0].startswith("Received error on read: 'Message size") \
-               and ex.args[0].endswith("exceeds limit 4096'")
+        assert ex.args[0].startswith('Response size') \
+               and ex.args[0].endswith('exceeds limit 4096 bytes')
 
         # confirm the client instance is still usable and not closed
-        assert ["test"] == client_http.submit("'test'").all().result()
+        assert ["test"] == client.submit("'test'").all().result()
     finally:
-        client_http.close()
+        client.close()
 
 
-def test_client_script_submission(client_http):
-    assert len(client_http.submit("new int[100]").all().result()) == 100
+def test_client_large_result(client):
+    result_set = client.submit("[\" \".repeat(200000), \" \".repeat(100000)]").all().result()
+    assert len(result_set[0]) == 200000
+    assert len(result_set[1]) == 100000
 
 
-def test_client_script_submission_inject(client_http):
-    assert len(client_http.submit("g.inject(new int[100])").all().result()) == 100
+def test_client_script_submission(client):
+    assert len(client.submit("new int[100]").all().result()) == 100
 
 
-def test_client_simple_eval(client_http):
-    assert client_http.submit('1 + 1').all().result()[0] == 2
+def test_client_script_submission_inject(client):
+    assert len(client.submit("g.inject(new int[100])").all().result()) == 100
 
 
-def test_client_simple_eval_bindings(client_http):
-    assert client_http.submit('x + x', {'x': 2}).all().result()[0] == 4
+def test_client_simple_eval(client):
+    assert client.submit('1 + 1').all().result()[0] == 2
 
 
-def test_client_eval_traversal(client_http):
-    assert len(client_http.submit('g.V()').all().result()) == 6
+def test_client_simple_eval_bindings(client):
+    assert client.submit('x + x', {'x': 2}).all().result()[0] == 4
 
 
-@pytest.mark.skip(reason="needs additional updates")
-def test_client_error(client_http):
+def test_client_eval_traversal(client):
+    assert len(client.submit('g.V()').all().result()) == 6
+
+
+def test_client_error(client):
     try:
         # should fire an exception
-        client_http.submit('1/0').all().result()
+        client.submit('1/0').all().result()
+        assert False
+    except GremlinServerError as ex:
+        assert ex.status_message.endswith('Division by zero')
+        assert ex.status_exception
+        assert str(ex) == f"{ex.status_code}: {ex.status_message}"
+
+    # still can submit after failure
+    assert client.submit('x + x', {'x': 2}).all().result()[0] == 4
+
+
+def test_bad_serialization(client):
+    try:
+        # should timeout
+        client.submit('java.awt.Color.RED').all().result()
         assert False
     except GremlinServerError as ex:
-        assert 'exceptions' in ex.status_attributes
-        assert 'stackTrace' in ex.status_attributes
+        assert ex.status_message
+        assert ex.status_exception
         assert str(ex) == f"{ex.status_code}: {ex.status_message}"
 
     # still can submit after failure
-    assert client_http.submit('x + x', {'x': 2}).all().result()[0] == 4
+    assert client.submit('x + x', {'x': 2}).all().result()[0] == 4
 
 
-@pytest.mark.skip(reason="needs additional updates")
-def test_client_connection_pool_after_error(client_http):
+def test_client_connection_pool_after_error(client):
     # Overwrite fixture with pool_size=1 client
-    client_http = Client(test_no_auth_http_url, 'gmodern', pool_size=1)
+    client = Client(test_no_auth_url, 'gmodern', pool_size=1)
 
     try:
         # should fire an exception
-        client_http.submit('1/0').all().result()
+        client.submit('1/0').all().result()
         assert False
     except GremlinServerError as gse:
         # expecting the pool size to be 1 again after query returned
-        assert gse.status_code == 597
-        assert client_http.available_pool_size == 1
+        assert gse.status_code == 500
+        assert client.available_pool_size == 1
 
     # still can submit after failure
-    assert client_http.submit('x + x', {'x': 2}).all().result()[0] == 4
+    assert client.submit('x + x', {'x': 2}).all().result()[0] == 4
 
 
-def test_client_no_hang_if_submit_on_closed(client_http):
-    assert client_http.submit('1 + 1').all().result()[0] == 2
-    client_http.close()
+def test_client_no_hang_if_submit_on_closed(client):
+    assert client.submit('1 + 1').all().result()[0] == 2
+    client.close()
     try:
         # should fail since not hang if closed
-        client_http.submit('1 + 1').all().result()
+        client.submit('1 + 1').all().result()
         assert False
     except Exception as ex:
         assert True
 
 
-def test_client_close_all_connection_in_pool(client_http):
-    client_http = Client(test_no_auth_http_url, 'g', pool_size=1)
-    assert client_http.available_pool_size == 1
-    client_http.submit('2+2').all().result()
-    client_http.close()
-    assert client_http.available_pool_size == 0
+def test_client_close_all_connection_in_pool(client):
+    client = Client(test_no_auth_url, 'g', pool_size=1)
+    assert client.available_pool_size == 1
+    client.submit('2+2').all().result()
+    client.close()
+    assert client.available_pool_size == 0
 
 
-def test_client_side_timeout_set_for_aiohttp(client_http):
-    client_http = Client(test_no_auth_http_url, 'gmodern',
-                         transport_factory=lambda: AiohttpHTTPTransport(read_timeout=1, write_timeout=1))
+def test_client_side_timeout_set_for_aiohttp(client):
+    client = Client(test_no_auth_url, 'gmodern',
+                    transport_factory=lambda: AiohttpHTTPTransport(read_timeout=1, write_timeout=1))
 
     try:
         # should fire an exception
-        client_http.submit('Thread.sleep(2000);1').all().result()
+        client.submit('Thread.sleep(2000);1').all().result()
         assert False
     except TimeoutError as err:
         # asyncio TimeoutError has no message.
         assert str(err) == ""
 
     # still can submit after failure
-    assert client_http.submit('x + x', {'x': 2}).all().result()[0] == 4
+    assert client.submit('x + x', {'x': 2}).all().result()[0] == 4
 
 
 async def async_connect(enable):
     try:
         transport = AiohttpHTTPTransport(call_from_event_loop=enable)
-        transport.connect(test_no_auth_http_url)
+        transport.connect(test_no_auth_url)
         transport.close()
         return True
     except RuntimeError:
@@ -177,8 +191,8 @@ def test_from_event_loop():
     assert asyncio.get_event_loop().run_until_complete(async_connect(True))
 
 
-def test_client_gremlin(client_http):
-    result_set = client_http.submit('g.V(1)')
+def test_client_gremlin(client):
+    result_set = client.submit('g.V(1)')
     result = result_set.all().result()
     assert 1 == len(result)
     vertex = result[0]
@@ -188,7 +202,7 @@ def test_client_gremlin(client_http):
     assert 'name' == vertex.properties[0].key
     assert 'marko' == vertex.properties[0].value
     ##
-    result_set = client_http.submit('g.with("materializeProperties", "tokens").V(1)')
+    result_set = client.submit('g.with("materializeProperties", "tokens").V(1)')
     result = result_set.all().result()
     assert 1 == len(result)
     vertex = result[0]
@@ -196,58 +210,58 @@ def test_client_gremlin(client_http):
     assert 0 == len(vertex.properties)
 
 
-def test_client_bytecode(client_http):
+def test_client_bytecode(client):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.V()
     message = create_basic_request_message(t)
-    result_set = client_http.submit(message)
+    result_set = client.submit(message)
     assert len(result_set.all().result()) == 6
 
 
-def test_client_bytecode_options(client_http):
+def test_client_bytecode_options(client):
     # smoke test to validate serialization of OptionsStrategy. no way to really validate this from an integration
     # test perspective because there's no way to access the internals of the strategy via bytecode
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.with_strategies(OptionsStrategy(options={"x": "test", "y": True})).V()
     message = create_basic_request_message(t)
-    result_set = client_http.submit(message)
+    result_set = client.submit(message)
     assert len(result_set.all().result()) == 6
     ##
     t = g.with_("x", "test").with_("y", True).V()
     message = create_basic_request_message(t)
-    result_set = client_http.submit(message)
+    result_set = client.submit(message)
     assert len(result_set.all().result()) == 6
 
 
-def test_iterate_result_set(client_http):
+def test_iterate_result_set(client):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.V()
     message = create_basic_request_message(t)
-    result_set = client_http.submit(message)
+    result_set = client.submit(message)
     results = []
     for result in result_set:
         results += result
     assert len(results) == 6
 
 
-def test_client_async(client_http):
+def test_client_async(client):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.V()
     message = create_basic_request_message(t)
-    future = client_http.submit_async(message)
+    future = client.submit_async(message)
     result_set = future.result()
     assert len(result_set.all().result()) == 6
 
 
-def test_connection_share(client_http):
+def test_connection_share(client):
     # Overwrite fixture with pool_size=1 client
-    client_http = Client(test_no_auth_http_url, 'gmodern', pool_size=1)
+    client = Client(test_no_auth_url, 'gmodern', pool_size=1)
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.V()
     message = create_basic_request_message(t)
     message2 = create_basic_request_message(t)
-    future = client_http.submit_async(message)
-    future2 = client_http.submit_async(message2)
+    future = client.submit_async(message)
+    future2 = client.submit_async(message2)
 
     result_set2 = future2.result()
     assert len(result_set2.all().result()) == 6
@@ -258,14 +272,14 @@ def test_connection_share(client_http):
     assert len(result_set.all().result()) == 6
 
 
-def test_multi_conn_pool(client_http):
+def test_multi_conn_pool(client):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.V()
     message = create_basic_request_message(t)
     message2 = create_basic_request_message(t)
-    client_http = Client(test_no_auth_http_url, 'g', pool_size=1)
-    future = client_http.submit_async(message)
-    future2 = client_http.submit_async(message2)
+    client = Client(test_no_auth_url, 'g', pool_size=1)
+    future = client.submit_async(message)
+    future2 = client.submit_async(message2)
 
     result_set2 = future2.result()
     assert len(result_set2.all().result()) == 6
@@ -275,7 +289,7 @@ def test_multi_conn_pool(client_http):
     assert len(result_set.all().result()) == 6
 
 
-def test_multi_thread_pool(client_http):
+def test_multi_thread_pool(client):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     traversals = [g.V(),
                   g.V().count(),
@@ -292,7 +306,7 @@ def test_multi_thread_pool(client_http):
         message = create_basic_request_message(tr)
         with condition:
             condition.wait(5)
-        result_set = client_http.submit(message)
+        result_set = client.submit(message)
         for result in result_set:
             result_list.append(result)
 
@@ -316,44 +330,44 @@ def test_multi_thread_pool(client_http):
     assert results[3][0][0].object == 6
 
 
-def test_client_bytecode_with_short(client_http):
+def test_client_bytecode_with_short(client):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.V().has('age', short(16)).count()
     message = create_basic_request_message(t)
-    result_set = client_http.submit(message)
+    result_set = client.submit(message)
     results = []
     for result in result_set:
         results += result
     assert len(results) == 1
 
 
-def test_client_bytecode_with_long(client_http):
+def test_client_bytecode_with_long(client):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.V().has('age', long(851401972585122)).count()
     message = create_basic_request_message(t)
-    result_set = client_http.submit(message)
+    result_set = client.submit(message)
     results = []
     for result in result_set:
         results += result
     assert len(results) == 1
 
 
-def test_client_bytecode_with_bigint(client_http):
+def test_client_bytecode_with_bigint(client):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.V().has('age', bigint(0x1000_0000_0000_0000_0000)).count()
     message = create_basic_request_message(t)
-    result_set = client_http.submit(message)
+    result_set = client.submit(message)
     results = []
     for result in result_set:
         results += result
     assert len(results) == 1
 
 
-def test_big_result_set(client_http):
+def test_big_result_set(client):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.inject(1).repeat(__.add_v('person').property('name', __.loops())).times(20000).count()
     message = create_basic_request_message(t, source='g')
-    result_set = client_http.submit(message)
+    result_set = client.submit(message)
     results = []
     for result in result_set:
         results += result
@@ -361,7 +375,7 @@ def test_big_result_set(client_http):
 
     t = g.V().limit(10)
     message = create_basic_request_message(t, source='g')
-    result_set = client_http.submit(message)
+    result_set = client.submit(message)
     results = []
     for result in result_set:
         results += result
@@ -369,7 +383,7 @@ def test_big_result_set(client_http):
 
     t = g.V().limit(100)
     message = create_basic_request_message(t, source='g')
-    result_set = client_http.submit(message)
+    result_set = client.submit(message)
     results = []
     for result in result_set:
         results += result
@@ -377,28 +391,27 @@ def test_big_result_set(client_http):
 
     t = g.V().limit(1000)
     message = create_basic_request_message(t, source='g')
-    result_set = client_http.submit(message)
+    result_set = client.submit(message)
     results = []
     for result in result_set:
         results += result
     assert len(results) == 1000
 
-    # TODO: enable after setting up docker for GitHub or cleaning up server-side locally
-    # t = g.V().limit(10000)
-    # message = create_basic_request_message(t, source='g')
-    # result_set = client_http.submit(message)
-    # results = []
-    # for result in result_set:
-    #     results += result
-    # assert len(results) == 10000
+    t = g.V().limit(10000)
+    message = create_basic_request_message(t, source='g')
+    result_set = client.submit(message)
+    results = []
+    for result in result_set:
+        results += result
+    assert len(results) == 10000
 
 
 @pytest.mark.skip(reason="enable after making sure authenticated testing server is set up in docker")
-def test_big_result_set_secure(authenticated_client_http):
+def test_big_result_set_secure(authenticated_client):
     g = GraphTraversalSource(Graph(), TraversalStrategies())
     t = g.inject(1).repeat(__.add_v('person').property('name', __.loops())).times(20000).count()
     message = create_basic_request_message(t, source='g')
-    result_set = authenticated_client_http.submit(message)
+    result_set = authenticated_client.submit(message)
     results = []
     for result in result_set:
         results += result
@@ -406,7 +419,7 @@ def test_big_result_set_secure(authenticated_client_http):
 
     t = g.V().limit(10)
     message = create_basic_request_message(t, source='g')
-    result_set = authenticated_client_http.submit(message)
+    result_set = authenticated_client.submit(message)
     results = []
     for result in result_set:
         results += result
@@ -414,7 +427,7 @@ def test_big_result_set_secure(authenticated_client_http):
 
     t = g.V().limit(100)
     message = create_basic_request_message(t, source='g')
-    result_set = authenticated_client_http.submit(message)
+    result_set = authenticated_client.submit(message)
     results = []
     for result in result_set:
         results += result
@@ -422,27 +435,26 @@ def test_big_result_set_secure(authenticated_client_http):
 
     t = g.V().limit(1000)
     message = create_basic_request_message(t, source='g')
-    result_set = authenticated_client_http.submit(message)
+    result_set = authenticated_client.submit(message)
     results = []
     for result in result_set:
         results += result
     assert len(results) == 1000
 
-    # TODO: enable after setting up docker for GitHub or cleaning up server-side locally
-    # t = g.V().limit(10000)
-    # message = create_basic_request_message(t, source='g')
-    # result_set = authenticated_client_http.submit(message)
-    # results = []
-    # for result in result_set:
-    #     results += result
-    # assert len(results) == 10000
+    t = g.V().limit(10000)
+    message = create_basic_request_message(t, source='g')
+    result_set = authenticated_client.submit(message)
+    results = []
+    for result in result_set:
+        results += result
+    assert len(results) == 10000
 
 
 async def asyncio_func():
     return 1
 
 
-def test_asyncio(client_http):
+def test_asyncio(client):
     try:
         asyncio.get_event_loop().run_until_complete(asyncio_func())
     except RuntimeError:
@@ -451,48 +463,48 @@ def test_asyncio(client_http):
 
 # TODO: tests pass because requestID is now generated on HTTP server and this option gets ignored, tests to be removed
 #  or updated depending on if we still want to use requestID or not
-def test_client_custom_invalid_request_id_graphson_script(client_http):
-    client = Client(test_no_auth_http_url, 'gmodern')
+def test_client_custom_invalid_request_id_graphson_script(client):
+    client = Client(test_no_auth_url, 'gmodern')
     try:
         client.submit('g.V()', request_options={"requestId": "malformed"}).all().result()
     except Exception as ex:
         assert "badly formed hexadecimal UUID string" in str(ex)
 
 
-def test_client_custom_invalid_request_id_graphbinary_script(client_http):
-    client_http = Client(test_no_auth_http_url, 'gmodern')
+def test_client_custom_invalid_request_id_graphbinary_script(client):
+    client = Client(test_no_auth_url, 'gmodern')
     try:
-        client_http.submit('g.V()', request_options={"requestId": "malformed"}).all().result()
+        client.submit('g.V()', request_options={"requestId": "malformed"}).all().result()
     except Exception as ex:
         assert "badly formed hexadecimal UUID string" in str(ex)
 
 
-def test_client_custom_valid_request_id_script_uuid(client_http):
-    assert len(client_http.submit('g.V()', request_options={"requestId": uuid.uuid4()}).all().result()) == 6
+def test_client_custom_valid_request_id_script_uuid(client):
+    assert len(client.submit('g.V()', request_options={"requestId": uuid.uuid4()}).all().result()) == 6
 
 
-def test_client_custom_valid_request_id_script_string(client_http):
-    assert len(client_http.submit('g.V()', request_options={"requestId": str(uuid.uuid4())}).all().result()) == 6
+def test_client_custom_valid_request_id_script_string(client):
+    assert len(client.submit('g.V()', request_options={"requestId": str(uuid.uuid4())}).all().result()) == 6
 
 
-def test_client_custom_invalid_request_id_graphson_bytecode(client_http):
-    client_http = Client(test_no_auth_http_url, 'gmodern')
+def test_client_custom_invalid_request_id_graphson_bytecode(client):
+    client = Client(test_no_auth_url, 'gmodern')
     query = GraphTraversalSource(Graph(), TraversalStrategies()).V().bytecode
     try:
-        client_http.submit(query, request_options={"requestId": "malformed"}).all().result()
+        client.submit(query, request_options={"requestId": "malformed"}).all().result()
     except Exception as ex:
         assert "badly formed hexadecimal UUID string" in str(ex)
 
 
-def test_client_custom_invalid_request_id_graphbinary_bytecode(client_http):
-    client_http = Client(test_no_auth_http_url, 'gmodern')
+def test_client_custom_invalid_request_id_graphbinary_bytecode(client):
+    client = Client(test_no_auth_url, 'gmodern')
     query = GraphTraversalSource(Graph(), TraversalStrategies()).V().bytecode
     try:
-        client_http.submit(query, request_options={"requestId": "malformed"}).all().result()
+        client.submit(query, request_options={"requestId": "malformed"}).all().result()
     except Exception as ex:
         assert "badly formed hexadecimal UUID string" in str(ex)
 
 
-def test_client_custom_valid_request_id_bytecode(client_http):
+def test_client_custom_valid_request_id_bytecode(client):
     query = GraphTraversalSource(Graph(), TraversalStrategies()).V().bytecode
-    assert len(client_http.submit(query).all().result()) == 6
+    assert len(client.submit(query).all().result()) == 6
diff --git a/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection.py b/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection.py
index 1e459297b8..19eac9eef2 100644
--- a/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection.py
+++ b/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection.py
@@ -20,7 +20,6 @@ import os
 
 import pytest
 from gremlin_python import statics
-from gremlin_python.driver.protocol import GremlinServerError
 from gremlin_python.statics import long
 from gremlin_python.process.traversal import Traverser
 from gremlin_python.process.traversal import TraversalStrategy
@@ -29,19 +28,16 @@ from gremlin_python.process.traversal import P, Order, T
 from gremlin_python.process.graph_traversal import __
 from gremlin_python.process.anonymous_traversal import traversal
 from gremlin_python.structure.graph import Vertex
-from gremlin_python.process.strategies import SubgraphStrategy, ReservedKeysVerificationStrategy, SeedStrategy
+from gremlin_python.process.strategies import SubgraphStrategy, SeedStrategy
 from gremlin_python.structure.io.util import HashableDict
-from gremlin_python.driver.serializer import GraphSONSerializersV2d0
-
-__author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'
+from gremlin_python.driver.protocol import GremlinServerError
 
-gremlin_server_url = os.environ.get('GREMLIN_SERVER_URL', 'ws://localhost:{}/gremlin')
+gremlin_server_url = os.environ.get('GREMLIN_SERVER_URL_HTTP', 'http://localhost:{}/')
 test_no_auth_url = gremlin_server_url.format(45940)
 
 
-# TODO: WS tests to be removed
-@pytest.mark.skip(reason="disabling all WS tests as we move to HTTP")
 class TestDriverRemoteConnection(object):
+
     def test_traversals(self, remote_connection):
         statics.load_statics(globals())
         g = traversal().with_(remote_connection)
@@ -66,7 +62,8 @@ class TestDriverRemoteConnection(object):
         assert 4 == g.V()[2:].count().next()
         assert 2 == g.V()[:2].count().next()
         # #
-        results = g.withSideEffect('a', ['josh', 'peter']).V(1).out('created').in_('created').values('name').where(P.within('a')).toList()
+        results = g.withSideEffect('a', ['josh', 'peter']).V(1).out('created').in_('created').values('name').where(
+            P.within('a')).toList()
         assert 2 == len(results)
         assert 'josh' in results
         assert 'peter' in results
@@ -77,7 +74,7 @@ class TestDriverRemoteConnection(object):
         assert 'dur' in results[0]
         # #
         results = g.V().has('name', 'peter').as_('a').out('created').as_('b').select('a', 'b').by(
-            __.valueMap()).toList()
+            __.value_map()).toList()
         assert 1 == len(results)
         assert 'peter' == results[0]['a']['name'][0]
         assert 35 == results[0]['a']['age'][0]
@@ -91,7 +88,8 @@ class TestDriverRemoteConnection(object):
         assert 'marko' in results
         assert 'vadas' in results
         # #
-        results = g.V().has('person', 'name', 'marko').map(lambda: ("it.get().value('name')", "gremlin-groovy")).toList()
+        results = g.V().has('person', 'name', 'marko').map(
+            lambda: ("it.get().value('name')", "gremlin-groovy")).toList()
         assert 1 == len(results)
         assert 'marko' in results
         # #
@@ -105,25 +103,12 @@ class TestDriverRemoteConnection(object):
         results = g.V().has('person', 'age', Bindings.of('x', P.lt(30))).count().next()
         assert 2 == results
         # #
-        # test dict keys which can only work on GraphBinary and GraphSON3 which include specific serialization
+        # test dict keys
         # types for dict
-        if not isinstance(remote_connection._client._message_serializer, GraphSONSerializersV2d0):
-            results = g.V().has('person', 'name', 'marko').elementMap("name").groupCount().next()
-            assert {HashableDict.of({T.id: 1, T.label: 'person', 'name': 'marko'}): 1} == results
-        if not isinstance(remote_connection._client._message_serializer, GraphSONSerializersV2d0):
-            results = g.V().has('person', 'name', 'marko').both('knows').groupCount().by(__.values('name').fold()).next()
-            assert {tuple(['vadas']): 1, tuple(['josh']): 1} == results
-
-    def test_lambda_traversals(self, remote_connection):
-        statics.load_statics(globals())
-        assert "remoteconnection[{},gmodern]".format(test_no_auth_url) == str(remote_connection)
-        g = traversal().with_(remote_connection)
-
-        assert 24.0 == g.withSack(1.0, lambda: ("x -> x + 1", "gremlin-groovy")).V().both().sack().sum_().next()
-        assert 24.0 == g.withSack(lambda: ("{1.0d}", "gremlin-groovy"), lambda: ("x -> x + 1", "gremlin-groovy")).V().both().sack().sum_().next()
-
-        assert 48.0 == g.withSack(1.0, lambda: ("x, y ->  x + y + 1", "gremlin-groovy")).V().both().sack().sum_().next()
-        assert 48.0 == g.withSack(lambda: ("{1.0d}", "gremlin-groovy"), lambda: ("x, y ->  x + y + 1", "gremlin-groovy")).V().both().sack().sum_().next()
+        results = g.V().has('person', 'name', 'marko').elementMap("name").groupCount().next()
+        assert {HashableDict.of({T.id: 1, T.label: 'person', 'name': 'marko'}): 1} == results
+        results = g.V().has('person', 'name', 'marko').both('knows').groupCount().by(__.values('name').fold()).next()
+        assert {tuple(['vadas']): 1, tuple(['josh']): 1} == results
 
     def test_iteration(self, remote_connection):
         statics.load_statics(globals())
@@ -136,11 +121,11 @@ class TestDriverRemoteConnection(object):
         assert t.hasNext()
         assert t.hasNext()
         assert 6 == t.next()
-        assert not(t.hasNext())
-        assert not(t.hasNext())
-        assert not(t.hasNext())
-        assert not(t.hasNext())
-        assert not(t.hasNext())
+        assert not (t.hasNext())
+        assert not (t.hasNext())
+        assert not (t.hasNext())
+        assert not (t.hasNext())
+        assert not (t.hasNext())
 
         t = g.V().has('name', P.within('marko', 'peter')).values('name').order()
         assert "marko" == t.next()
@@ -150,11 +135,11 @@ class TestDriverRemoteConnection(object):
         assert t.hasNext()
         assert t.hasNext()
         assert "peter" == t.next()
-        assert not(t.hasNext())
-        assert not(t.hasNext())
-        assert not(t.hasNext())
-        assert not(t.hasNext())
-        assert not(t.hasNext())
+        assert not (t.hasNext())
+        assert not (t.hasNext())
+        assert not (t.hasNext())
+        assert not (t.hasNext())
+        assert not (t.hasNext())
 
         try:
             t.next()
@@ -162,13 +147,26 @@ class TestDriverRemoteConnection(object):
         except StopIteration:
             assert True
 
+    def test_lambda_traversals(self, remote_connection):
+        statics.load_statics(globals())
+        assert "remoteconnection[{},gmodern]".format(test_no_auth_url) == str(remote_connection)
+        g = traversal().with_(remote_connection)
+
+        assert 24.0 == g.withSack(1.0, lambda: ("x -> x + 1", "gremlin-groovy")).V().both().sack().sum_().next()
+        assert 24.0 == g.withSack(lambda: ("{1.0d}", "gremlin-groovy"),
+                                  lambda: ("x -> x + 1", "gremlin-groovy")).V().both().sack().sum_().next()
+
+        assert 48.0 == g.withSack(1.0, lambda: ("x, y ->  x + y + 1", "gremlin-groovy")).V().both().sack().sum_().next()
+        assert 48.0 == g.withSack(lambda: ("{1.0d}", "gremlin-groovy"),
+                                  lambda: ("x, y ->  x + y + 1", "gremlin-groovy")).V().both().sack().sum_().next()
+
     def test_strategies(self, remote_connection):
         statics.load_statics(globals())
         g = traversal().with_(remote_connection). \
             withStrategies(TraversalStrategy("SubgraphStrategy",
-                                             {"vertices": __.hasLabel("person"),
-                                              "edges": __.hasLabel("created")},
-                                              "org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy"))
+                                             {"vertices": __.has_label("person"),
+                                              "edges": __.has_label("created")},
+                                             "org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy"))
         assert 4 == g.V().count().next()
         assert 0 == g.E().count().next()
         assert 1 == g.V().label().dedup().count().next()
@@ -176,14 +174,14 @@ class TestDriverRemoteConnection(object):
         assert "person" == g.V().label().dedup().next()
         #
         g = traversal().with_(remote_connection). \
-            withStrategies(SubgraphStrategy(vertices=__.hasLabel("person"), edges=__.hasLabel("created")))
+            withStrategies(SubgraphStrategy(vertices=__.has_label("person"), edges=__.has_label("created")))
         assert 4 == g.V().count().next()
         assert 0 == g.E().count().next()
         assert 1 == g.V().label().dedup().count().next()
         assert "person" == g.V().label().dedup().next()
         #
         g = traversal().with_(remote_connection). \
-            withStrategies(SubgraphStrategy(edges=__.hasLabel("created")))
+            withStrategies(SubgraphStrategy(edges=__.has_label("created")))
         assert 6 == g.V().count().next()
         assert 4 == g.E().count().next()
         assert 1 == g.E().label().dedup().count().next()
@@ -205,63 +203,6 @@ class TestDriverRemoteConnection(object):
         assert shuffledResult == g.V().values("name").order().by(Order.shuffle).toList()
         assert shuffledResult == g.V().values("name").order().by(Order.shuffle).toList()
         assert shuffledResult == g.V().values("name").order().by(Order.shuffle).toList()
-        #
-        g = traversal().with_(remote_connection). \
-            withStrategies(ReservedKeysVerificationStrategy(throw_exception=True))
-        try:
-            g.addV("person").property("id", "please-don't-use-id").iterate()
-            assert False
-        except GremlinServerError as gse:
-            assert gse.status_code == 500
-        #
-        g = traversal().with_(remote_connection).with_("x", True).with_('evaluationTimeout', 10)
-        try:
-            g.inject(1).sideEffect(lambda: ("Thread.sleep(1000)", "gremlin-groovy")).iterate()
-            assert False
-        except GremlinServerError as gse:
-            assert gse.status_code == 598
-
-    def test_close_sessions(self, remote_transaction_connection):
-        g = traversal().with_(remote_transaction_connection)
-        tx = g.tx()
-        gtx = tx.begin()
-        # session created for new transaction
-        assert 1 == len(remote_transaction_connection._DriverRemoteConnection__spawned_sessions)
-        gtx.addV("person").iterate()
-        tx.rollback()
-        # after closing transaction we should remove spawned_session
-        assert 0 == len(remote_transaction_connection._DriverRemoteConnection__spawned_sessions)
-
-    def test_tx_on_graph_without_tx_support(self, remote_connection):
-        g = traversal().withRemote(remote_connection)
-        tx = g.tx()
-        try:
-            # tx is just a session, so no exception here
-            gtx = tx.begin()
-            # read operation is ok for sessioned connection
-            assert 6 == gtx.V().count().next()
-            tx.commit().all().result()
-            assert False
-        except GremlinServerError as ex:
-            assert "500: Graph does not support transactions" == str(ex)
-
-    def test_tx_commit_on_graph_without_tx_support(self, remote_connection):
-        g = traversal().withRemote(remote_connection)
-        tx = g.tx()
-        try:
-            tx.commit()
-            assert False
-        except Exception as ex:
-            assert "Cannot commit a transaction that is not started." == str(ex)
-
-    def test_tx_rollback_on_graph_without_tx_support(self, remote_connection):
-        g = traversal().withRemote(remote_connection)
-        tx = g.tx()
-        try:
-            tx.rollback()
-            assert False
-        except Exception as ex:
-            assert "Cannot rollback a transaction that is not started." == str(ex)
 
     def test_clone(self, remote_connection):
         g = traversal().with_(remote_connection)
@@ -270,6 +211,18 @@ class TestDriverRemoteConnection(object):
         assert 5 == t.clone().limit(5).count().next()
         assert 10 == t.clone().limit(10).count().next()
 
+    def test_receive_error(self, invalid_alias_remote_connection):
+        g = traversal().with_(invalid_alias_remote_connection)
+
+        try:
+            g.V().next()
+            assert False
+        except GremlinServerError as err:
+            assert err.status_code == 400
+            assert 'The traversal source [does_not_exist] for alias [g] is not configured on the server.' \
+                   in err.status_message
+
+    @pytest.mark.skip(reason="enable after making sure authenticated testing server is set up in docker")
     def test_authenticated(self, remote_connection_authenticated):
         statics.load_statics(globals())
         g = traversal().with_(remote_connection_authenticated)
diff --git a/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection_http.py b/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection_http.py
deleted file mode 100644
index 7b6d324559..0000000000
--- a/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection_http.py
+++ /dev/null
@@ -1,229 +0,0 @@
-#
-# 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.
-#
-import os
-
-import pytest
-from gremlin_python import statics
-from gremlin_python.statics import long
-from gremlin_python.process.traversal import Traverser
-from gremlin_python.process.traversal import TraversalStrategy
-from gremlin_python.process.traversal import Bindings
-from gremlin_python.process.traversal import P, Order, T
-from gremlin_python.process.graph_traversal import __
-from gremlin_python.process.anonymous_traversal import traversal
-from gremlin_python.structure.graph import Vertex
-from gremlin_python.process.strategies import SubgraphStrategy, SeedStrategy
-from gremlin_python.structure.io.util import HashableDict
-from gremlin_python.driver.protocol import GremlinServerError
-
-gremlin_server_url_http = os.environ.get('GREMLIN_SERVER_URL_HTTP', 'http://localhost:{}/')
-test_no_auth_http_url = gremlin_server_url_http.format(45940)
-
-
-class TestDriverRemoteConnectionHttp(object):
-    def test_traversals(self, remote_connection_http):
-        statics.load_statics(globals())
-        g = traversal().with_(remote_connection_http)
-
-        assert long(6) == g.V().count().toList()[0]
-        # #
-        assert Vertex(1) == g.V(1).next()
-        assert Vertex(1) == g.V(Vertex(1)).next()
-        assert 1 == g.V(1).id_().next()
-        assert Traverser(Vertex(1)) == g.V(1).nextTraverser()
-        assert 1 == len(g.V(1).toList())
-        assert isinstance(g.V(1).toList(), list)
-        results = g.V().repeat(__.out()).times(2).name
-        results = results.toList()
-        assert 2 == len(results)
-        assert "lop" in results
-        assert "ripple" in results
-        # #
-        assert 10 == g.V().repeat(__.both()).times(5)[0:10].count().next()
-        assert 1 == g.V().repeat(__.both()).times(5)[0:1].count().next()
-        assert 0 == g.V().repeat(__.both()).times(5)[0:0].count().next()
-        assert 4 == g.V()[2:].count().next()
-        assert 2 == g.V()[:2].count().next()
-        # #
-        results = g.withSideEffect('a', ['josh', 'peter']).V(1).out('created').in_('created').values('name').where(
-            P.within('a')).toList()
-        assert 2 == len(results)
-        assert 'josh' in results
-        assert 'peter' in results
-        # #
-        results = g.V().out().profile().toList()
-        assert 1 == len(results)
-        assert 'metrics' in results[0]
-        assert 'dur' in results[0]
-        # #
-        results = g.V().has('name', 'peter').as_('a').out('created').as_('b').select('a', 'b').by(
-            __.value_map()).toList()
-        assert 1 == len(results)
-        assert 'peter' == results[0]['a']['name'][0]
-        assert 35 == results[0]['a']['age'][0]
-        assert 'lop' == results[0]['b']['name'][0]
-        assert 'java' == results[0]['b']['lang'][0]
-        assert 2 == len(results[0]['a'])
-        assert 2 == len(results[0]['b'])
-        # #
-        results = g.V(1).inject(g.V(2).next()).values('name').toList()
-        assert 2 == len(results)
-        assert 'marko' in results
-        assert 'vadas' in results
-        # #
-        results = g.V().has('person', 'name', 'marko').map(
-            lambda: ("it.get().value('name')", "gremlin-groovy")).toList()
-        assert 1 == len(results)
-        assert 'marko' in results
-        # #
-        # this test just validates that the underscored versions of steps conflicting with Gremlin work
-        # properly and can be removed when the old steps are removed - TINKERPOP-2272
-        results = g.V().filter_(__.values('age').sum_().and_(
-            __.max_().is_(P.gt(0)), __.min_().is_(P.gt(0)))).range_(0, 1).id_().next()
-        assert 1 == results
-        # #
-        # test binding in P
-        results = g.V().has('person', 'age', Bindings.of('x', P.lt(30))).count().next()
-        assert 2 == results
-        # #
-        # test dict keys
-        # types for dict
-        results = g.V().has('person', 'name', 'marko').elementMap("name").groupCount().next()
-        assert {HashableDict.of({T.id: 1, T.label: 'person', 'name': 'marko'}): 1} == results
-        results = g.V().has('person', 'name', 'marko').both('knows').groupCount().by(__.values('name').fold()).next()
-        assert {tuple(['vadas']): 1, tuple(['josh']): 1} == results
-
-    def test_iteration(self, remote_connection_http):
-        statics.load_statics(globals())
-        g = traversal().with_(remote_connection_http)
-
-        t = g.V().count()
-        assert t.hasNext()
-        assert t.hasNext()
-        assert t.hasNext()
-        assert t.hasNext()
-        assert t.hasNext()
-        assert 6 == t.next()
-        assert not (t.hasNext())
-        assert not (t.hasNext())
-        assert not (t.hasNext())
-        assert not (t.hasNext())
-        assert not (t.hasNext())
-
-        t = g.V().has('name', P.within('marko', 'peter')).values('name').order()
-        assert "marko" == t.next()
-        assert t.hasNext()
-        assert t.hasNext()
-        assert t.hasNext()
-        assert t.hasNext()
-        assert t.hasNext()
-        assert "peter" == t.next()
-        assert not (t.hasNext())
-        assert not (t.hasNext())
-        assert not (t.hasNext())
-        assert not (t.hasNext())
-        assert not (t.hasNext())
-
-        try:
-            t.next()
-            assert False
-        except StopIteration:
-            assert True
-
-    def test_lambda_traversals(self, remote_connection_http):
-        statics.load_statics(globals())
-        assert "remoteconnection[{},gmodern]".format(test_no_auth_http_url) == str(remote_connection_http)
-        g = traversal().with_(remote_connection_http)
-
-        assert 24.0 == g.withSack(1.0, lambda: ("x -> x + 1", "gremlin-groovy")).V().both().sack().sum_().next()
-        assert 24.0 == g.withSack(lambda: ("{1.0d}", "gremlin-groovy"),
-                                  lambda: ("x -> x + 1", "gremlin-groovy")).V().both().sack().sum_().next()
-
-        assert 48.0 == g.withSack(1.0, lambda: ("x, y ->  x + y + 1", "gremlin-groovy")).V().both().sack().sum_().next()
-        assert 48.0 == g.withSack(lambda: ("{1.0d}", "gremlin-groovy"),
-                                  lambda: ("x, y ->  x + y + 1", "gremlin-groovy")).V().both().sack().sum_().next()
-
-    def test_strategies(self, remote_connection_http):
-        statics.load_statics(globals())
-        g = traversal().with_(remote_connection_http). \
-            withStrategies(TraversalStrategy("SubgraphStrategy",
-                                             {"vertices": __.has_label("person"),
-                                              "edges": __.has_label("created")},
-                                             "org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy"))
-        assert 4 == g.V().count().next()
-        assert 0 == g.E().count().next()
-        assert 1 == g.V().label().dedup().count().next()
-        assert 4 == g.V().filter_(lambda: ("x -> true", "gremlin-groovy")).count().next()
-        assert "person" == g.V().label().dedup().next()
-        #
-        g = traversal().with_(remote_connection_http). \
-            withStrategies(SubgraphStrategy(vertices=__.has_label("person"), edges=__.has_label("created")))
-        assert 4 == g.V().count().next()
-        assert 0 == g.E().count().next()
-        assert 1 == g.V().label().dedup().count().next()
-        assert "person" == g.V().label().dedup().next()
-        #
-        g = traversal().with_(remote_connection_http). \
-            withStrategies(SubgraphStrategy(edges=__.has_label("created")))
-        assert 6 == g.V().count().next()
-        assert 4 == g.E().count().next()
-        assert 1 == g.E().label().dedup().count().next()
-        assert "created" == g.E().label().dedup().next()
-        #
-        g = g.withoutStrategies(SubgraphStrategy). \
-            withComputer(vertices=__.has("name", "marko"), edges=__.limit(0))
-        assert 1 == g.V().count().next()
-        assert 0 == g.E().count().next()
-        assert "person" == g.V().label().next()
-        assert "marko" == g.V().name.next()
-        #
-        g = traversal().with_(remote_connection_http).withComputer()
-        assert 6 == g.V().count().next()
-        assert 6 == g.E().count().next()
-        #
-        g = traversal().with_(remote_connection_http).withStrategies(SeedStrategy(12345))
-        shuffledResult = g.V().values("name").order().by(Order.shuffle).toList()
-        assert shuffledResult == g.V().values("name").order().by(Order.shuffle).toList()
-        assert shuffledResult == g.V().values("name").order().by(Order.shuffle).toList()
-        assert shuffledResult == g.V().values("name").order().by(Order.shuffle).toList()
-
-    def test_clone(self, remote_connection_http):
-        g = traversal().with_(remote_connection_http)
-        t = g.V().both()
-        assert 12 == len(t.toList())
-        assert 5 == t.clone().limit(5).count().next()
-        assert 10 == t.clone().limit(10).count().next()
-
-    def test_receive_error(self, invalid_alias_remote_connection_http):
-        g = traversal().with_(invalid_alias_remote_connection_http)
-
-        try:
-            g.V().next()
-            assert False
-        except GremlinServerError as err:
-            assert err.status_code == 400
-            assert 'The traversal source [does_not_exist] for alias [g] is not configured on the server.' \
-                   in err.status_message
-
-    @pytest.mark.skip(reason="enable after making sure authenticated testing server is set up in docker")
-    def test_authenticated(self, remote_connection_http_authenticated):
-        statics.load_statics(globals())
-        g = traversal().with_(remote_connection_http_authenticated)
-
-        assert long(6) == g.V().count().toList()[0]
diff --git a/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection_threaded.py b/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection_threaded.py
index ec1a118509..3f016a739d 100644
--- a/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection_threaded.py
+++ b/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection_threaded.py
@@ -27,11 +27,11 @@ from gremlin_python.process.anonymous_traversal import traversal
 
 __author__ = 'David M. Brown (davebshow@gmail.com)'
 
-gremlin_server_url_http = 'http://localhost:{}'
-test_no_auth_http_url = gremlin_server_url_http.format(45940)
+gremlin_server_url = 'http://localhost:{}'
+test_no_auth_url = gremlin_server_url.format(45940)
 
 
-def test_conns_in_threads(remote_connection_http):
+def test_conns_in_threads(remote_connection):
     q = queue.Queue()
     child = Thread(target=_executor, args=(q, None))
     child2 = Thread(target=_executor, args=(q, None))
@@ -44,10 +44,10 @@ def test_conns_in_threads(remote_connection_http):
     child2.join()
 
 
-def test_conn_in_threads(remote_connection_http):
+def test_conn_in_threads(remote_connection):
     q = queue.Queue()
-    child = Thread(target=_executor, args=(q, remote_connection_http))
-    child2 = Thread(target=_executor, args=(q, remote_connection_http))
+    child = Thread(target=_executor, args=(q, remote_connection))
+    child2 = Thread(target=_executor, args=(q, remote_connection))
     child.start()
     child2.start()
     for x in range(2):
@@ -62,7 +62,7 @@ def _executor(q, conn):
     if not conn:
         # This isn't a fixture so close manually
         close = True
-        conn = DriverRemoteConnection(test_no_auth_http_url, 'gmodern', pool_size=4)
+        conn = DriverRemoteConnection(test_no_auth_url, 'gmodern', pool_size=4)
     try:
         g = traversal().with_(conn)
         future = g.V().promise()
@@ -79,7 +79,7 @@ def _executor(q, conn):
 
 def handle_request():
     try:
-        remote_connection = DriverRemoteConnection(test_no_auth_http_url, "gmodern")
+        remote_connection = DriverRemoteConnection(test_no_auth_url, "gmodern")
         g = traversal().with_(remote_connection)
         g.V().limit(1).toList()
         remote_connection.close()
diff --git a/gremlin-python/src/main/python/tests/driver/test_serializer.py b/gremlin-python/src/main/python/tests/driver/test_serializer.py
index bff69c941e..16e4371c16 100644
--- a/gremlin-python/src/main/python/tests/driver/test_serializer.py
+++ b/gremlin-python/src/main/python/tests/driver/test_serializer.py
@@ -25,5 +25,3 @@ __author__ = 'David M. Brown'
 def test_graphbinary_serializer_v4(graphbinary_serializer_v4):
     assert graphbinary_serializer_v4.version == b"application/vnd.graphbinary-v4.0"
     assert isinstance(graphbinary_serializer_v4._graphbinary_reader, graphbinaryV4.GraphBinaryReader)
-    assert isinstance(graphbinary_serializer_v4.standard._writer, graphbinaryV4.GraphBinaryWriter)
-    assert isinstance(graphbinary_serializer_v4.traversal._writer, graphbinaryV4.GraphBinaryWriter)
diff --git a/gremlin-python/src/main/python/tests/structure/io/test_functionalityio.py b/gremlin-python/src/main/python/tests/structure/io/test_functionalityio.py
index 38c3c3602b..7c0be29c1d 100644
--- a/gremlin-python/src/main/python/tests/structure/io/test_functionalityio.py
+++ b/gremlin-python/src/main/python/tests/structure/io/test_functionalityio.py
@@ -25,8 +25,8 @@ from gremlin_python.process.anonymous_traversal import traversal
 from gremlin_python.statics import *
 
 
-def test_vertex(remote_connection_http):
-    g = traversal().with_(remote_connection_http)
+def test_vertex(remote_connection):
+    g = traversal().with_(remote_connection)
     vertex = g.V(1).next()
     assert vertex.id == 1
     assert vertex.label == 'person'
@@ -37,8 +37,8 @@ def test_vertex(remote_connection_http):
     assert vertex.properties[1].value == 29
 
 
-def test_vertex_without_properties(remote_connection_http):
-    g = traversal().with_(remote_connection_http)
+def test_vertex_without_properties(remote_connection):
+    g = traversal().with_(remote_connection)
     vertex = g.with_('materializeProperties', 'tokens').V(1).next()
     assert vertex.id == 1
     assert vertex.label == 'person'
@@ -46,8 +46,8 @@ def test_vertex_without_properties(remote_connection_http):
     assert vertex.properties is None or len(vertex.properties) == 0
 
 
-def test_edge(remote_connection_http):
-    g = traversal().with_(remote_connection_http)
+def test_edge(remote_connection):
+    g = traversal().with_(remote_connection)
     edge = g.E(7).next()
     assert edge.id == 7
     assert edge.label == 'knows'
@@ -56,8 +56,8 @@ def test_edge(remote_connection_http):
     assert edge.properties[0].value == 0.5
 
 
-def test_edge_without_properties(remote_connection_http):
-    g = traversal().with_(remote_connection_http)
+def test_edge_without_properties(remote_connection):
+    g = traversal().with_(remote_connection)
     edge = g.with_('materializeProperties', 'tokens').E(7).next()
     assert edge.id == 7
     assert edge.label == 'knows'
@@ -65,8 +65,8 @@ def test_edge_without_properties(remote_connection_http):
     assert edge.properties is None or len(edge.properties) == 0
 
 
-def test_vertex_vertex_properties(remote_connection_http_crew):
-    g = traversal().with_(remote_connection_http_crew)
+def test_vertex_vertex_properties(remote_connection_crew):
+    g = traversal().with_(remote_connection_crew)
     vertex = g.V(7).next()
     assert vertex.id == 7
     assert vertex.label == 'person'
@@ -80,8 +80,8 @@ def test_vertex_vertex_properties(remote_connection_http_crew):
     assert vertex.properties[1].properties[1].value == 2000
 
 
-def test_timestamp(remote_connection_http):
-    g = traversal().with_(remote_connection_http)
+def test_timestamp(remote_connection):
+    g = traversal().with_(remote_connection)
     ts = timestamp(1481750076295 / 1000)
     resp = g.addV('test_vertex').property('ts', ts)
     resp = resp.toList()
@@ -94,8 +94,8 @@ def test_timestamp(remote_connection_http):
         g.V(vid).drop().iterate()
 
 
-def test_datetime(remote_connection_http):
-    g = traversal().with_(remote_connection_http)
+def test_datetime(remote_connection):
+    g = traversal().with_(remote_connection)
     dt = datetime.datetime.utcfromtimestamp(1481750076295 / 1000)
     resp = g.addV('test_vertex').property('dt', dt).toList()
     vid = resp[0].id
@@ -107,8 +107,8 @@ def test_datetime(remote_connection_http):
         g.V(vid).drop().iterate()
 
 
-def test_uuid(remote_connection_http):
-    g = traversal().with_(remote_connection_http)
+def test_uuid(remote_connection):
+    g = traversal().with_(remote_connection)
     uid = uuid.UUID("41d2e28a-20a4-4ab0-b379-d810dede3786")
     resp = g.addV('test_vertex').property('uuid', uid).toList()
     vid = resp[0].id
@@ -120,11 +120,11 @@ def test_uuid(remote_connection_http):
         g.V(vid).drop().iterate()
 
 
-def test_short(remote_connection_http):
-    if not isinstance(remote_connection_http._client._message_serializer, GraphBinarySerializersV4):
+def test_short(remote_connection):
+    if not isinstance(remote_connection._client._message_serializer, GraphBinarySerializersV4):
         return
 
-    g = traversal().with_(remote_connection_http)
+    g = traversal().with_(remote_connection)
     num = short(1111)
     resp = g.addV('test_vertex').property('short', num).toList()
     vid = resp[0].id
@@ -136,11 +136,11 @@ def test_short(remote_connection_http):
         g.V(vid).drop().iterate()
 
 
-def test_bigint_positive(remote_connection_http):
-    if not isinstance(remote_connection_http._client._message_serializer, GraphBinarySerializersV4):
+def test_bigint_positive(remote_connection):
+    if not isinstance(remote_connection._client._message_serializer, GraphBinarySerializersV4):
         return
 
-    g = traversal().with_(remote_connection_http)
+    g = traversal().with_(remote_connection)
     big = bigint(0x1000_0000_0000_0000_0000)
     resp = g.addV('test_vertex').property('bigint', big).toList()
     vid = resp[0].id
@@ -152,11 +152,11 @@ def test_bigint_positive(remote_connection_http):
         g.V(vid).drop().iterate()
 
 
-def test_bigint_negative(remote_connection_http):
-    if not isinstance(remote_connection_http._client._message_serializer, GraphBinarySerializersV4):
+def test_bigint_negative(remote_connection):
+    if not isinstance(remote_connection._client._message_serializer, GraphBinarySerializersV4):
         return
 
-    g = traversal().with_(remote_connection_http)
+    g = traversal().with_(remote_connection)
     big = bigint(-0x1000_0000_0000_0000_0000)
     resp = g.addV('test_vertex').property('bigint', big).toList()
     vid = resp[0].id
@@ -168,11 +168,11 @@ def test_bigint_negative(remote_connection_http):
         g.V(vid).drop().iterate()
 
 
-def test_bigdecimal(remote_connection_http):
-    if not isinstance(remote_connection_http._client._message_serializer, GraphBinarySerializersV4):
+def test_bigdecimal(remote_connection):
+    if not isinstance(remote_connection._client._message_serializer, GraphBinarySerializersV4):
         return
 
-    g = traversal().with_(remote_connection_http)
+    g = traversal().with_(remote_connection)
     bigdecimal = BigDecimal(101, 235)
     resp = g.addV('test_vertex').property('bigdecimal', bigdecimal).toList()
     vid = resp[0].id
@@ -185,8 +185,8 @@ def test_bigdecimal(remote_connection_http):
         g.V(vid).drop().iterate()
 
 
-def test_odd_bits(remote_connection_http):
-    g = traversal().with_(remote_connection_http)
+def test_odd_bits(remote_connection):
+    g = traversal().with_(remote_connection)
     char_lower = str.__new__(SingleChar, chr(78))
     resp = g.addV('test_vertex').property('char_lower', char_lower).toList()
     vid = resp[0].id
diff --git a/gremlin-python/src/main/python/tests/structure/io/test_graphbinaryV1.py b/gremlin-python/src/main/python/tests/structure/io/test_graphbinaryV1.py
deleted file mode 100644
index e3f678ebab..0000000000
--- a/gremlin-python/src/main/python/tests/structure/io/test_graphbinaryV1.py
+++ /dev/null
@@ -1,235 +0,0 @@
-"""
-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.
-"""
-
-import datetime
-import uuid
-import math
-
-from gremlin_python.statics import timestamp, long, bigint, BigDecimal, SingleByte, SingleChar, ByteBufferType
-from gremlin_python.structure.graph import Vertex, Edge, Property, VertexProperty, Path
-from gremlin_python.structure.io.graphbinaryV1 import GraphBinaryWriter, GraphBinaryReader
-from gremlin_python.process.traversal import Barrier, Binding, Bytecode, Merge, Direction
-
-
-# TODO: to be removed
-class TestGraphBinaryV1(object):
-    graphbinary_writer = GraphBinaryWriter()
-    graphbinary_reader = GraphBinaryReader()
-
-    def test_null(self):
-        c = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(None))
-        assert c is None
-
-    def test_int(self):
-        x = 100
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_long(self):
-        x = long(100)
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_bigint(self):
-        x = bigint(0x1000_0000_0000_0000_0000)
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_float(self):
-        x = float(100.001)
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-        x = float('nan')
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert math.isnan(output)
-
-        x = float('-inf')
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert math.isinf(output) and output < 0
-
-        x = float('inf')
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert math.isinf(output) and output > 0
-
-    def test_double(self):
-        x = 100.001
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_bigdecimal(self):
-        x = BigDecimal(100, 234)
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x.scale == output.scale
-        assert x.unscaled_value == output.unscaled_value
-
-    def test_date(self):
-        x = datetime.datetime(2016, 12, 14, 16, 14, 36, 295000)
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_timestamp(self):
-        x = timestamp(1481750076295 / 1000)
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_string(self):
-        x = "serialize this!"
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_homogeneous_list(self):
-        x = ["serialize this!", "serialize that!", "serialize that!","stop telling me what to serialize"]
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_heterogeneous_list(self):
-        x = ["serialize this!", 0, "serialize that!", "serialize that!", 1, "stop telling me what to serialize", 2]
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_heterogeneous_list_with_none(self):
-        x = ["serialize this!", 0, "serialize that!", "serialize that!", 1, "stop telling me what to serialize", 2, None]
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_homogeneous_set(self):
-        x = {"serialize this!", "serialize that!", "stop telling me what to serialize"}
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_heterogeneous_set(self):
-        x = {"serialize this!", 0, "serialize that!", 1, "stop telling me what to serialize", 2}
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_dict(self):
-        x = {"yo": "what?",
-             "go": "no!",
-             "number": 123,
-             321: "crazy with the number for a key",
-             987: ["go", "deep", {"here": "!"}]}
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-        x = {"marko": [666], "noone": ["blah"]}
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-        x = {"ripple": [], "peter": ["created"], "noone": ["blah"], "vadas": [],
-             "josh": ["created", "created"], "lop": [], "marko": [666, "created", "knows", "knows"]}
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_uuid(self):
-        x = uuid.UUID("41d2e28a-20a4-4ab0-b379-d810dede3786")
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_edge(self):
-        x = Edge(123, Vertex(1, 'person'), "developed", Vertex(10, "software"))
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-        assert x.inV == output.inV
-        assert x.outV == output.outV
-
-    def test_path(self):
-        x = Path(["x", "y", "z"], [1, 2, 3])
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_property(self):
-        x = Property("name", "stephen", None)
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_vertex(self):
-        x = Vertex(123, "person")
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_vertexproperty(self):
-        x = VertexProperty(123, "name", "stephen", None)
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-        
-    def test_barrier(self):
-        x = Barrier.norm_sack
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_merge(self):
-        x = Merge.on_match
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_direction(self):
-        x = Direction.OUT
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-        x = Direction.from_
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_binding(self):
-        x = Binding("name", "marko")
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_bytecode(self):
-        x = Bytecode()
-        x.source_instructions.append(["withStrategies", "SubgraphStrategy"])
-        x.step_instructions.append(["V", 1, 2, 3])
-        x.step_instructions.append(["out"])
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_byte(self):
-        x = int.__new__(SingleByte, 1)
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_bytebuffer(self):
-        x = ByteBufferType("c29tZSBieXRlcyBmb3IgeW91", "utf8")
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_boolean(self):
-        x = True
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-        x = False
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_char(self):
-        x = str.__new__(SingleChar, chr(76))
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-        x = str.__new__(SingleChar, chr(57344))
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
-
-    def test_duration(self):
-        x = datetime.timedelta(seconds=1000, microseconds=1000)
-        output = self.graphbinary_reader.read_object(self.graphbinary_writer.write_object(x))
-        assert x == output
diff --git a/gremlin-python/src/main/python/tests/structure/io/test_graphsonV2d0.py b/gremlin-python/src/main/python/tests/structure/io/test_graphsonV2d0.py
deleted file mode 100644
index 013fcf8a25..0000000000
--- a/gremlin-python/src/main/python/tests/structure/io/test_graphsonV2d0.py
+++ /dev/null
@@ -1,538 +0,0 @@
-#
-# 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.
-#
-
-__author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'
-
-import datetime
-import calendar
-import json
-import uuid
-import math
-from decimal import *
-
-from mock import Mock
-
-from gremlin_python.statics import *
-from gremlin_python.structure.graph import Vertex, Edge, Property, VertexProperty, Graph, Path
-from gremlin_python.structure.io.graphsonV2d0 import GraphSONWriter, GraphSONReader, GraphSONUtil
-import gremlin_python.structure.io.graphsonV2d0
-from gremlin_python.process.traversal import P, Merge, Operator, Order, Barrier, Direction
-from gremlin_python.process.strategies import SubgraphStrategy
-from gremlin_python.process.graph_traversal import __
-from gremlin_python.process.anonymous_traversal import traversal
-
-
-# TODO: to be removed
-class TestGraphSONReader(object):
-    graphson_reader = GraphSONReader()
-
-    def test_number_input(self):
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:Byte",
-            "@value": 1
-        }))
-        assert isinstance(x, SingleByte)
-        assert 1 == x
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:Int16",
-            "@value": 16
-        }))
-        assert isinstance(x, short)
-        assert 16 == x
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "g:Int32",
-            "@value": 31
-        }))
-        assert isinstance(x, int)
-        assert 31 == x
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "g:Int64",
-            "@value": 31
-        }))
-        assert isinstance(x, long)
-        assert long(31) == x
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "g:Float",
-            "@value": 31.3
-        }))
-        assert isinstance(x, float)
-        assert 31.3 == x
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "g:Double",
-            "@value": 31.2
-        }))
-        assert isinstance(x, float)
-        assert 31.2 == x
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "g:Double",
-            "@value": "NaN"
-        }))
-        assert isinstance(x, float)
-        assert math.isnan(x)
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "g:Double",
-            "@value": "Infinity"
-        }))
-        assert isinstance(x, float)
-        assert math.isinf(x) and x > 0
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "g:Double",
-            "@value": "-Infinity"
-        }))
-        assert isinstance(x, float)
-        assert math.isinf(x) and x < 0
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:BigDecimal",
-            "@value": 31.2
-        }))
-        assert isinstance(x, Decimal)
-        assert Decimal(31.2) == x
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:BigDecimal",
-            "@value": 123456789987654321123456789987654321
-        }))
-        assert isinstance(x, Decimal)
-        assert Decimal('123456789987654321123456789987654321') == x
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:BigDecimal",
-            "@value": "NaN"
-        }))
-        assert isinstance(x, Decimal)
-        assert math.isnan(x)
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:BigDecimal",
-            "@value": "Infinity"
-        }))
-        assert isinstance(x, Decimal)
-        assert math.isinf(x) and x > 0
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:BigDecimal",
-            "@value": "-Infinity"
-        }))
-        assert isinstance(x, Decimal)
-        assert math.isinf(x) and x < 0
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:BigInteger",
-            "@value": 31
-        }))
-        assert isinstance(x, long)
-        assert 31 == x
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:BigInteger",
-            "@value": 123456789987654321123456789987654321
-        }))
-        assert isinstance(x, long)
-        assert 123456789987654321123456789987654321 == x
-
-    def test_graph(self):
-        vertex = self.graphson_reader.read_object("""
-        {"@type":"g:Vertex", "@value":{"id":{"@type":"g:Int32","@value":1},"label":"person","outE":{"created":[{"id":{"@type":"g:Int32","@value":9},"inV":{"@type":"g:Int32","@value":3},"properties":{"weight":{"@type":"g:Double","@value":0.4}}}],"knows":[{"id":{"@type":"g:Int32","@value":7},"inV":{"@type":"g:Int32","@value":2},"properties":{"weight":{"@type":"g:Double","@value":0.5}}},{"id":{"@type":"g:Int32","@value":8},"inV":{"@type":"g:Int32","@value":4},"properties":{"weight":{"@type" [...]
-        assert isinstance(vertex, Vertex)
-        assert "person" == vertex.label
-        assert 1 == vertex.id
-        assert isinstance(vertex.id, int)
-        assert vertex == Vertex(1)
-        assert 2 == len(vertex.properties)
-        ##
-        vertex = self.graphson_reader.read_object("""
-        {"@type":"g:Vertex", "@value":{"id":{"@type":"g:Float","@value":45.23}}}""")
-        assert isinstance(vertex, Vertex)
-        assert 45.23 == vertex.id
-        assert isinstance(vertex.id, FloatType)
-        assert "vertex" == vertex.label
-        assert vertex == Vertex(45.23)
-        ##
-        vertex_property = self.graphson_reader.read_object("""
-        {"@type":"g:VertexProperty", "@value":{"id":"anId","label":"aKey","value":true,"vertex":{"@type":"g:Int32","@value":9}}}""")
-        assert isinstance(vertex_property, VertexProperty)
-        assert "anId" == vertex_property.id
-        assert "aKey" == vertex_property.label
-        assert vertex_property.value
-        assert vertex_property.vertex == Vertex(9)
-        ##
-        vertex_property = self.graphson_reader.read_object("""
-        {"@type":"g:VertexProperty", "@value":{"id":{"@type":"g:Int32","@value":1},"label":"name","value":"marko"}}""")
-        assert isinstance(vertex_property, VertexProperty)
-        assert 1 == vertex_property.id
-        assert "name" == vertex_property.label
-        assert "marko" == vertex_property.value
-        assert vertex_property.vertex is None
-        ##
-        edge = self.graphson_reader.read_object("""
-        {"@type":"g:Edge", "@value":{"id":{"@type":"g:Int64","@value":17},"label":"knows","inV":"x","outV":"y","inVLabel":"xLab","properties":{"aKey":"aValue","bKey":true}}}""")
-        # print edge
-        assert isinstance(edge, Edge)
-        assert 17 == edge.id
-        assert "knows" == edge.label
-        assert edge.inV == Vertex("x", "xLabel")
-        assert edge.outV == Vertex("y", "vertex")
-        ##
-        property = self.graphson_reader.read_object("""
-        {"@type":"g:Property", "@value":{"key":"aKey","value":{"@type":"g:Int64","@value":17},"element":{"@type":"g:Edge","@value":{"id":{"@type":"g:Int64","@value":122},"label":"knows","inV":"x","outV":"y","inVLabel":"xLab"}}}}""")
-        # print property
-        assert isinstance(property, Property)
-        assert "aKey" == property.key
-        assert 17 == property.value
-        assert Edge(122, Vertex("x"), "knows", Vertex("y")) == property.element
-
-    def test_path(self):
-        path = self.graphson_reader.read_object(
-            """{"@type":"g:Path","@value":{"labels":[["a"],["b","c"],[]],"objects":[{"@type":"g:Vertex","@value":{"id":{"@type":"g:Int32","@value":1},"label":"person","properties":{"name":[{"@type":"g:VertexProperty","@value":{"id":{"@type":"g:Int64","@value":0},"value":"marko","label":"name"}}],"age":[{"@type":"g:VertexProperty","@value":{"id":{"@type":"g:Int64","@value":1},"value":{"@type":"g:Int32","@value":29},"label":"age"}}]}}},{"@type":"g:Vertex","@value":{"id":{"@type":"g:Int32", [...]
-        )
-        assert isinstance(path, Path)
-        assert "path[v[1], v[3], lop]" == str(path)
-        assert Vertex(1) == path[0]
-        assert Vertex(1) == path["a"]
-        assert "lop" == path[2]
-        assert 3 == len(path)
-
-    def test_custom_mapping(self):
-
-        # extended mapping
-        class X(object):
-            pass
-
-        type_string = "test:Xtype"
-        override_string = "g:Int64"
-        serdes = Mock()
-
-        reader = GraphSONReader(deserializer_map={type_string: serdes})
-        assert type_string in reader.deserializers
-
-        # base dicts are not modified
-        assert type_string not in gremlin_python.structure.io.graphsonV2d0._deserializers
-
-        x = X()
-        o = reader.to_object({GraphSONUtil.TYPE_KEY: type_string, GraphSONUtil.VALUE_KEY: x})
-        serdes.objectify.assert_called_once_with(x, reader)
-        assert o is serdes.objectify()
-
-        # overridden mapping
-        type_string = "g:Int64"
-        serdes = Mock()
-        reader = GraphSONReader(deserializer_map={type_string: serdes, override_string: serdes})
-        assert gremlin_python.structure.io.graphsonV2d0._deserializers[type_string] is not reader.deserializers[type_string]
-
-        value = 3
-        o = reader.to_object({GraphSONUtil.TYPE_KEY: type_string, GraphSONUtil.VALUE_KEY: value})
-        serdes.objectify.assert_called_once_with(value, reader)
-        assert o is serdes.objectify()
-
-    def test_datetime(self):
-        expected = datetime.datetime(2016, 12, 14, 16, 14, 36, 295000)
-        pts = calendar.timegm(expected.utctimetuple()) + expected.microsecond / 1e6
-        ts = int(round(pts * 1000))
-        dt = self.graphson_reader.read_object(json.dumps({"@type": "g:Date", "@value": ts}))
-        assert isinstance(dt, datetime.datetime)
-        # TINKERPOP-1848
-        assert dt == expected
-
-    def test_timestamp(self):
-        dt = self.graphson_reader.read_object(json.dumps({"@type": "g:Timestamp", "@value": 1481750076295}))
-        assert isinstance(dt, timestamp)
-        assert float(dt) == 1481750076.295
-
-    def test_duration(self):
-        d = self.graphson_reader.read_object(json.dumps({"@type": "gx:Duration", "@value": "PT120H"}))
-        assert isinstance(d, datetime.timedelta)
-        assert d == datetime.timedelta(hours=120)
-
-    def test_uuid(self):
-        prop = self.graphson_reader.read_object(
-            json.dumps({'@type': 'g:UUID', '@value': "41d2e28a-20a4-4ab0-b379-d810dede3786"}))
-        assert isinstance(prop, uuid.UUID)
-        assert str(prop) == '41d2e28a-20a4-4ab0-b379-d810dede3786'
-
-    def test_metrics(self):
-        prop = self.graphson_reader.read_object(
-            json.dumps([{'@type': 'g:TraversalMetrics', '@value': {'dur': 1.468594, 'metrics': [
-                {'@type': 'g:Metrics', '@value': {'dur': 1.380957, 'counts': {}, 'name': 'GraphStep(__.V())', 'annotations': {'percentDur': 94.03259171697556}, 'id': '4.0.0()'}},
-                {'@type': 'g:Metrics', '@value': {'dur': 0.087637, 'counts': {}, 'name': 'ReferenceElementStep', 'annotations': {'percentDur': 5.967408283024444}, 'id': '3.0.0()'}}
-            ]}}]))
-        assert isinstance(prop, list)
-        assert prop == [{'dur': 1.468594, 'metrics': [
-                {'dur': 1.380957, 'counts': {}, 'name': 'GraphStep(__.V())', 'annotations': {'percentDur': 94.03259171697556}, 'id': '4.0.0()'},
-                {'dur': 0.087637, 'counts': {}, 'name': 'ReferenceElementStep', 'annotations': {'percentDur': 5.967408283024444}, 'id': '3.0.0()'}
-                ]}]
-
-    def test_bytebuffer(self):
-        bb = self.graphson_reader.read_object(
-            json.dumps({"@type": "gx:ByteBuffer", "@value": "c29tZSBieXRlcyBmb3IgeW91"}))
-        assert isinstance(bb, ByteBufferType)
-        assert ByteBufferType("c29tZSBieXRlcyBmb3IgeW91", "utf8") == bb
-
-    def test_char(self):
-        c = self.graphson_reader.read_object(json.dumps({"@type": "gx:Char", "@value": "L"}))
-        assert isinstance(c, SingleChar)
-        assert chr(76) == c
-
-    def test_null(self):
-        c = self.graphson_reader.read_object(json.dumps(None))
-        assert c is None
-
-
-class TestGraphSONWriter(object):
-    graphson_writer = GraphSONWriter()
-    graphson_reader = GraphSONReader()
-
-    def test_numbers(self):
-        assert {"@type": "gx:Byte", "@value": 1} == json.loads(self.graphson_writer.write_object(int.__new__(SingleByte, 1)))
-        assert {"@type": "gx:Int16", "@value": 16} == json.loads(self.graphson_writer.write_object(short(16)))
-        assert {"@type": "gx:Int16", "@value": -16} == json.loads(self.graphson_writer.write_object(short(-16)))
-        assert {"@type": "g:Int64", "@value": 2} == json.loads(self.graphson_writer.write_object(long(2)))
-        assert {"@type": "g:Int64", "@value": 851401972585122} == json.loads(self.graphson_writer.write_object(long(851401972585122)))
-        assert {"@type": "g:Int64", "@value": -2} == json.loads(self.graphson_writer.write_object(long(-2)))
-        assert {"@type": "g:Int64", "@value": -851401972585122} == json.loads(self.graphson_writer.write_object(long(-851401972585122)))
-        assert {"@type": "g:Int32", "@value": 1} == json.loads(self.graphson_writer.write_object(1))
-        assert {"@type": "g:Int32", "@value": -1} == json.loads(self.graphson_writer.write_object(-1))
-        assert {"@type": "g:Int64", "@value": 851401972585122} == json.loads(self.graphson_writer.write_object(851401972585122))
-        assert {"@type": "g:Double", "@value": 3.2} == json.loads(self.graphson_writer.write_object(3.2))
-        assert {"@type": "g:Double", "@value": "NaN"} == json.loads(self.graphson_writer.write_object(float('nan')))
-        assert {"@type": "g:Double", "@value": "Infinity"} == json.loads(self.graphson_writer.write_object(float('inf')))
-        assert {"@type": "g:Double", "@value": "-Infinity"} == json.loads(self.graphson_writer.write_object(float('-inf')))
-        assert {"@type": "gx:BigDecimal", "@value": "123456789987654321123456789987654321"} == json.loads(self.graphson_writer.write_object(Decimal('123456789987654321123456789987654321')))
-        assert {"@type": "gx:BigDecimal", "@value": "NaN"} == json.loads(self.graphson_writer.write_object(Decimal('nan')))
-        assert {"@type": "gx:BigDecimal", "@value": "Infinity"} == json.loads(self.graphson_writer.write_object(Decimal('inf')))
-        assert {"@type": "gx:BigDecimal", "@value": "-Infinity"} == json.loads(self.graphson_writer.write_object(Decimal('-inf')))
-        assert {"@type": "gx:BigInteger", "@value": "123456789987654321123456789987654321"} == json.loads(self.graphson_writer.write_object(long(123456789987654321123456789987654321)))
-        assert {"@type": "gx:BigInteger", "@value": "123456789987654321123456789987654321"} == json.loads(self.graphson_writer.write_object(123456789987654321123456789987654321))
-        assert """true""" == self.graphson_writer.write_object(True)
-
-    def test_enum(self):
-        assert {"@type": "g:Merge", "@value": "onMatch"} == json.loads(self.graphson_writer.write_object(Merge.on_match))
-        assert {"@type": "g:Order", "@value": "shuffle"} == json.loads(self.graphson_writer.write_object(Order.shuffle))
-        assert {"@type": "g:Barrier", "@value": "normSack"} == json.loads(self.graphson_writer.write_object(Barrier.norm_sack))
-        assert {"@type": "g:Operator", "@value": "sum"} == json.loads(self.graphson_writer.write_object(Operator.sum_))
-        assert {"@type": "g:Operator", "@value": "sumLong"} == json.loads(self.graphson_writer.write_object(Operator.sum_long))
-        assert {"@type": "g:Direction", "@value": "OUT"} == json.loads(self.graphson_writer.write_object(Direction.OUT))
-        assert {"@type": "g:Direction", "@value": "OUT"} == json.loads(self.graphson_writer.write_object(Direction.from_))
-
-    def test_P(self):
-        result = {'@type': 'g:P',
-                  '@value': {
-                      'predicate': 'and',
-                      'value': [{
-                          '@type': 'g:P',
-                          '@value': {
-                              'predicate': 'or',
-                              'value': [{
-                                  '@type': 'g:P',
-                                  '@value': {'predicate': 'lt', 'value': 'b'}
-                              },
-                                  {'@type': 'g:P', '@value': {'predicate': 'gt', 'value': 'c'}}
-                              ]
-                          }
-                      },
-                          {'@type': 'g:P', '@value': {'predicate': 'neq', 'value': 'd'}}]}}
-
-        assert result == json.loads(
-            self.graphson_writer.write_object(P.lt("b").or_(P.gt("c")).and_(P.neq("d"))))
-
-        result = {'@type': 'g:P', '@value': {'predicate':'within','value': [{"@type": "g:Int32", "@value": 1},{"@type": "g:Int32", "@value": 2}]}}
-        assert result == json.loads(self.graphson_writer.write_object(P.within([1, 2])))
-        assert result == json.loads(self.graphson_writer.write_object(P.within(1, 2)))
-
-        result = {'@type': 'g:P', '@value': {'predicate':'within','value': [{"@type": "g:Int32", "@value": 1}]}}
-        assert result == json.loads(self.graphson_writer.write_object(P.within([1])))
-        assert result == json.loads(self.graphson_writer.write_object(P.within(1)))
-
-    def test_strategies(self):
-        # we have a proxy model for now given that we don't want to have to have g:XXX all registered on the Gremlin traversal machine (yet)
-        assert {"@type": "g:SubgraphStrategy", "@value": {}} == json.loads(
-            self.graphson_writer.write_object(SubgraphStrategy))
-        assert {"@type": "g:SubgraphStrategy", "@value": {
-            "vertices": {"@type": "g:Bytecode", "@value": {"step": [["has", "name", "marko"]]}}}} == json.loads(
-            self.graphson_writer.write_object(SubgraphStrategy(vertices=__.has("name", "marko"))))
-
-    def test_graph(self):
-        # TODO: this assert is not compatible with python 3 and now that we test with both 2 and 3 it fails
-        assert {"@type": "g:Vertex", "@value": {"id": {"@type": "g:Int64", "@value": 12}, "label": "person"}} == json.loads(self.graphson_writer.write_object(Vertex(long(12), "person")))
-
-        assert {"@type": "g:Edge", "@value": {"id": {"@type": "g:Int32", "@value": 7},
-                                              "outV": {"@type": "g:Int32", "@value": 0},
-                                              "outVLabel": "person",
-                                              "label": "knows",
-                                              "inV": {"@type": "g:Int32", "@value": 1},
-                                              "inVLabel": "dog"}} == json.loads(
-            self.graphson_writer.write_object(Edge(7, Vertex(0, "person"), "knows", Vertex(1, "dog"))))
-        assert {"@type": "g:VertexProperty", "@value": {"id": "blah", "label": "keyA", "value": True,
-                                                        "vertex": "stephen"}} == json.loads(
-            self.graphson_writer.write_object(VertexProperty("blah", "keyA", True, Vertex("stephen"))))
-
-        assert {"@type": "g:Property",
-                "@value": {"key": "name", "value": "marko", "element": {"@type": "g:VertexProperty",
-                                                                        "@value": {
-                                                                            "vertex": "vertexId",
-                                                                            "id": {"@type": "g:Int32", "@value": 1234},
-                                                                            "label": "aKey"}}}} == json.loads(
-            self.graphson_writer.write_object(
-                Property("name", "marko", VertexProperty(1234, "aKey", 21345, Vertex("vertexId")))))
-
-        vertex = self.graphson_reader.read_object(self.graphson_writer.write_object(Vertex(1, "person")))
-        assert 1 == vertex.id
-        assert "person" == vertex.label
-
-        edge = self.graphson_reader.read_object(
-            self.graphson_writer.write_object(Edge(3, Vertex(1, "person"), "knows", Vertex(2, "dog"))))
-        assert "knows" == edge.label
-        assert 3 == edge.id
-        assert 1 == edge.outV.id
-        assert 2 == edge.inV.id
-
-        vertex_property = self.graphson_reader.read_object(
-            self.graphson_writer.write_object(VertexProperty(1, "age", 32, Vertex(1))))
-        assert 1 == vertex_property.id
-        assert "age" == vertex_property.key
-        assert 32 == vertex_property.value
-
-        property = self.graphson_reader.read_object(self.graphson_writer.write_object(Property("age", 32.2, Edge(1, Vertex(2), "knows", Vertex(3)))))
-        assert "age" == property.key
-        assert 32.2 == property.value
-
-    def test_custom_mapping(self):
-        # extended mapping
-        class X(object):
-            pass
-
-        serdes = Mock()
-        writer = GraphSONWriter(serializer_map={X: serdes})
-        assert X in writer.serializers
-
-        # base dicts are not modified
-        assert X not in gremlin_python.structure.io.graphsonV2d0._serializers
-
-        obj = X()
-        d = writer.to_dict(obj)
-        serdes.dictify.assert_called_once_with(obj, writer)
-        assert d is serdes.dictify()
-
-        # overridden mapping
-        serdes = Mock()
-        writer = GraphSONWriter(serializer_map={int: serdes})
-        assert gremlin_python.structure.io.graphsonV2d0._serializers[int] is not writer.serializers[int]
-
-        value = 3
-        d = writer.to_dict(value)
-        serdes.dictify.assert_called_once_with(value, writer)
-        assert d is serdes.dictify()
-
-    def test_write_long(self):
-        mapping = self.graphson_writer.to_dict(1)
-        assert mapping['@type'] == 'g:Int32'
-        assert mapping['@value'] == 1
-
-        mapping = self.graphson_writer.to_dict(long(1))
-        assert mapping['@type'] == 'g:Int64'
-        assert mapping['@value'] == 1
-
-    def test_datetime(self):
-        expected = json.dumps({"@type": "g:Date", "@value": 1481750076295}, separators=(',', ':'))
-        dt = datetime.datetime.utcfromtimestamp(1481750076295 / 1000.0)
-        output = self.graphson_writer.write_object(dt)
-        assert expected == output
-
-    def test_timestamp(self):
-        expected = json.dumps({"@type": "g:Timestamp", "@value": 1481750076295}, separators=(',', ':'))
-        ts = timestamp(1481750076295 / 1000.0)
-        output = self.graphson_writer.write_object(ts)
-        assert expected == output
-
-    def test_duration(self):
-        expected = json.dumps({"@type": "gx:Duration", "@value": "P5D"}, separators=(',', ':'))
-        d = datetime.timedelta(hours=120)
-        output = self.graphson_writer.write_object(d)
-        assert expected == output
-
-    def test_uuid(self):
-        expected = json.dumps({'@type': 'g:UUID', '@value': "41d2e28a-20a4-4ab0-b379-d810dede3786"}, separators=(',', ':'))
-        prop = uuid.UUID("41d2e28a-20a4-4ab0-b379-d810dede3786")
-        output = self.graphson_writer.write_object(prop)
-        assert expected == output
-
-    def test_bytebuffer(self):
-        expected = json.dumps({'@type': 'gx:ByteBuffer', '@value': 'c29tZSBieXRlcyBmb3IgeW91'}, separators=(',', ':'))
-        bb = ByteBufferType("c29tZSBieXRlcyBmb3IgeW91", "utf8")
-        output = self.graphson_writer.write_object(bb)
-        assert expected == output
-
-    def test_char(self):
-        expected = json.dumps({'@type': 'gx:Char', '@value': 'L'}, separators=(',', ':'))
-        c = str.__new__(SingleChar, chr(76))
-        output = self.graphson_writer.write_object(c)
-        assert expected == output
-
-
-class TestFunctionalGraphSONIO(object):
-    """Functional IO tests"""
-
-    def test_timestamp(self, remote_connection_graphsonV2):
-        g = traversal().with_(remote_connection_graphsonV2)
-        ts = timestamp(1481750076295 / 1000)
-        resp = g.addV('test_vertex').property('ts', ts)
-        resp = resp.toList()
-        vid = resp[0].id
-        try:
-            ts_prop = g.V(vid).properties('ts').toList()[0]
-            assert isinstance(ts_prop.value, timestamp)
-            assert ts_prop.value == ts
-        except OSError:
-            assert False, "Error making request"
-        finally:
-            g.V(vid).drop().iterate()
-
-    def test_datetime(self, remote_connection_graphsonV2):
-        g = traversal().with_(remote_connection_graphsonV2)
-        dt = datetime.datetime.utcfromtimestamp(1481750076295 / 1000)
-        resp = g.addV('test_vertex').property('dt', dt).toList()
-        vid = resp[0].id
-        try:
-            dt_prop = g.V(vid).properties('dt').toList()[0]
-            assert isinstance(dt_prop.value, datetime.datetime)
-            assert dt_prop.value == dt
-        except OSError:
-            assert False, "Error making request"
-        finally:
-            g.V(vid).drop().iterate()
-
-    def test_uuid(self, remote_connection_graphsonV2):
-        g = traversal().with_(remote_connection_graphsonV2)
-        uid = uuid.UUID("41d2e28a-20a4-4ab0-b379-d810dede3786")
-        resp = g.addV('test_vertex').property('uuid', uid).toList()
-        vid = resp[0].id
-        try:
-            uid_prop = g.V(vid).properties('uuid').toList()[0]
-            assert isinstance(uid_prop.value, uuid.UUID)
-            assert uid_prop.value == uid
-        except OSError:
-            assert False, "Error making request"
-        finally:
-            g.V(vid).drop().iterate()
diff --git a/gremlin-python/src/main/python/tests/structure/io/test_graphsonV3d0.py b/gremlin-python/src/main/python/tests/structure/io/test_graphsonV3d0.py
deleted file mode 100644
index 88837a0d2e..0000000000
--- a/gremlin-python/src/main/python/tests/structure/io/test_graphsonV3d0.py
+++ /dev/null
@@ -1,556 +0,0 @@
-#
-# 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.
-#
-
-__author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'
-
-import datetime
-import calendar
-import json
-import uuid
-import math
-from decimal import *
-
-from mock import Mock
-
-from gremlin_python.statics import *
-from gremlin_python.structure.graph import Vertex, Edge, Property, VertexProperty, Path
-from gremlin_python.structure.io.graphsonV3d0 import GraphSONWriter, GraphSONReader, GraphSONUtil
-import gremlin_python.structure.io.graphsonV3d0
-from gremlin_python.process.traversal import P, Merge, Barrier, Order, Operator, Direction
-from gremlin_python.process.strategies import SubgraphStrategy
-from gremlin_python.process.graph_traversal import __
-
-
-# TODO: to be removed
-class TestGraphSONReader(object):
-    graphson_reader = GraphSONReader()
-
-    def test_collections(self):
-        x = self.graphson_reader.read_object(
-            json.dumps({"@type": "g:List", "@value": [{"@type": "g:Int32", "@value": 1},
-                                                      {"@type": "g:Int32", "@value": 2},
-                                                      "3"]}))
-        assert isinstance(x, list)
-        assert x[0] == 1
-        assert x[1] == 2
-        assert x[2] == "3"
-        ##
-
-        x = self.graphson_reader.read_object(
-            json.dumps({"@type": "g:Set", "@value": [{"@type": "g:Int32", "@value": 1},
-                                                     {"@type": "g:Int32", "@value": 2},
-                                                     "3"]}))
-        # return a set as normal
-        assert isinstance(x, set)
-        assert x == set([1, 2, "3"])
-
-        x = self.graphson_reader.read_object(
-            json.dumps({"@type": "g:Set", "@value": [{"@type": "g:Int32", "@value": 1},
-                                                    {"@type": "g:Int32", "@value": 2},
-                                                    {"@type": "g:Float", "@value": 2.0},
-                                                    "3"]}))
-        # coerce to list here because Java might return numerics of different types which python won't recognize
-        # see comments of TINKERPOP-1844 for more details
-        assert isinstance(x, list)
-        assert x == list([1, 2, 2.0, "3"])
-        ##
-        x = self.graphson_reader.read_object(
-            json.dumps({"@type": "g:Map",
-                        "@value": ['a', {"@type": "g:Int32", "@value": 1}, 'b', "marko"]}))
-        assert isinstance(x, dict)
-        assert x['a'] == 1
-        assert x['b'] == "marko"
-        assert len(x) == 2
-
-        # BulkSet gets coerced to a List - both have the same behavior
-        x = self.graphson_reader.read_object(
-            json.dumps({"@type": "g:BulkSet",
-                        "@value": ["marko", {"@type": "g:Int64", "@value": 1}, "josh", {"@type": "g:Int64", "@value": 3}]}))
-        assert isinstance(x, list)
-        assert len(x) == 4
-        assert x.count("marko") == 1
-        assert x.count("josh") == 3
-
-    def test_number_input(self):
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:Byte",
-            "@value": 1
-        }))
-        assert isinstance(x, SingleByte)
-        assert 1 == x
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:Int16",
-            "@value": 16
-        }))
-        assert isinstance(x, short)
-        assert 16 == x
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "g:Int32",
-            "@value": 31
-        }))
-        assert isinstance(x, int)
-        assert 31 == x
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "g:Int64",
-            "@value": 31
-        }))
-        assert isinstance(x, long)
-        assert long(31) == x
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "g:Float",
-            "@value": 31.3
-        }))
-        assert isinstance(x, float)
-        assert 31.3 == x
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "g:Double",
-            "@value": 31.2
-        }))
-        assert isinstance(x, float)
-        assert 31.2 == x
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "g:Double",
-            "@value": "NaN"
-        }))
-        assert isinstance(x, float)
-        assert math.isnan(x)
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "g:Double",
-            "@value": "Infinity"
-        }))
-        assert isinstance(x, float)
-        assert math.isinf(x) and x > 0
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "g:Double",
-            "@value": "-Infinity"
-        }))
-        assert isinstance(x, float)
-        assert math.isinf(x) and x < 0
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:BigDecimal",
-            "@value": 31.2
-        }))
-        assert isinstance(x, Decimal)
-        assert Decimal(31.2) == x
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:BigDecimal",
-            "@value": 123456789987654321123456789987654321
-        }))
-        assert isinstance(x, Decimal)
-        assert Decimal('123456789987654321123456789987654321') == x
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:BigDecimal",
-            "@value": "NaN"
-        }))
-        assert isinstance(x, Decimal)
-        assert math.isnan(x)
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:BigDecimal",
-            "@value": "Infinity"
-        }))
-        assert isinstance(x, Decimal)
-        assert math.isinf(x) and x > 0
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:BigDecimal",
-            "@value": "-Infinity"
-        }))
-        assert isinstance(x, Decimal)
-        assert math.isinf(x) and x < 0
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:BigInteger",
-            "@value": 31
-        }))
-        assert isinstance(x, long)
-        assert 31 == x
-        ##
-        x = self.graphson_reader.read_object(json.dumps({
-            "@type": "gx:BigInteger",
-            "@value": 123456789987654321123456789987654321
-        }))
-        assert isinstance(x, long)
-        assert 123456789987654321123456789987654321 == x
-
-    def test_graph(self):
-        vertex = self.graphson_reader.read_object("""
-        {"@type":"g:Vertex", "@value":{"id":{"@type":"g:Int32","@value":1},"label":"person","outE":{"created":[{"id":{"@type":"g:Int32","@value":9},"inV":{"@type":"g:Int32","@value":3},"properties":{"weight":{"@type":"g:Double","@value":0.4}}}],"knows":[{"id":{"@type":"g:Int32","@value":7},"inV":{"@type":"g:Int32","@value":2},"properties":{"weight":{"@type":"g:Double","@value":0.5}}},{"id":{"@type":"g:Int32","@value":8},"inV":{"@type":"g:Int32","@value":4},"properties":{"weight":{"@type" [...]
-        assert isinstance(vertex, Vertex)
-        assert "person" == vertex.label
-        assert 1 == vertex.id
-        assert isinstance(vertex.id, int)
-        assert vertex == Vertex(1)
-        ##
-        vertex = self.graphson_reader.read_object("""
-        {"@type":"g:Vertex", "@value":{"id":{"@type":"g:Float","@value":45.23}}}""")
-        assert isinstance(vertex, Vertex)
-        assert 45.23 == vertex.id
-        assert isinstance(vertex.id, FloatType)
-        assert "vertex" == vertex.label
-        assert vertex == Vertex(45.23)
-        ##
-        vertex_property = self.graphson_reader.read_object("""
-        {"@type":"g:VertexProperty", "@value":{"id":"anId","label":"aKey","value":true,"vertex":{"@type":"g:Int32","@value":9}}}""")
-        assert isinstance(vertex_property, VertexProperty)
-        assert "anId" == vertex_property.id
-        assert "aKey" == vertex_property.label
-        assert vertex_property.value
-        assert vertex_property.vertex == Vertex(9)
-        ##
-        vertex_property = self.graphson_reader.read_object("""
-        {"@type":"g:VertexProperty", "@value":{"id":{"@type":"g:Int32","@value":1},"label":"name","value":"marko"}}""")
-        assert isinstance(vertex_property, VertexProperty)
-        assert 1 == vertex_property.id
-        assert "name" == vertex_property.label
-        assert "marko" == vertex_property.value
-        assert vertex_property.vertex is None
-        ##
-        edge = self.graphson_reader.read_object("""
-        {"@type":"g:Edge", "@value":{"id":{"@type":"g:Int64","@value":17},"label":"knows","inV":"x","outV":"y","inVLabel":"xLab","properties":{"aKey":"aValue","bKey":true}}}""")
-        # print edge
-        assert isinstance(edge, Edge)
-        assert 17 == edge.id
-        assert "knows" == edge.label
-        assert edge.inV == Vertex("x", "xLabel")
-        assert edge.outV == Vertex("y", "vertex")
-        ##
-        property = self.graphson_reader.read_object("""
-        {"@type":"g:Property", "@value":{"key":"aKey","value":{"@type":"g:Int64","@value":17},"element":{"@type":"g:Edge","@value":{"id":{"@type":"g:Int64","@value":122},"label":"knows","inV":"x","outV":"y","inVLabel":"xLab"}}}}""")
-        # print property
-        assert isinstance(property, Property)
-        assert "aKey" == property.key
-        assert 17 == property.value
-        assert Edge(122, Vertex("x"), "knows", Vertex("y")) == property.element
-
-    def test_path(self):
-        path = self.graphson_reader.read_object(
-            """{"@type":"g:Path","@value":{"labels":{"@type":"g:List","@value":[{"@type":"g:Set","@value":["a"]},{"@type":"g:Set","@value":["b","c"]},{"@type":"g:Set","@value":[]}]},"objects":{"@type":"g:List","@value":[{"@type":"g:Vertex","@value":{"id":{"@type":"g:Int32","@value":1},"label":"person","properties":{"name":[{"@type":"g:VertexProperty","@value":{"id":{"@type":"g:Int64","@value":0},"value":"marko","label":"name"}}],"age":[{"@type":"g:VertexProperty","@value":{"id":{"@type": [...]
-        )
-        assert isinstance(path, Path)
-        assert "path[v[1], v[3], lop]" == str(path)
-        assert Vertex(1) == path[0]
-        assert Vertex(1) == path["a"]
-        assert "lop" == path[2]
-        assert 3 == len(path)
-
-    def test_custom_mapping(self):
-
-        # extended mapping
-        class X(object):
-            pass
-
-        type_string = "test:Xtype"
-        override_string = "g:Int64"
-        serdes = Mock()
-
-        reader = GraphSONReader(deserializer_map={type_string: serdes})
-        assert type_string in reader.deserializers
-
-        # base dicts are not modified
-        assert type_string not in gremlin_python.structure.io.graphsonV3d0._deserializers
-
-        x = X()
-        o = reader.to_object({GraphSONUtil.TYPE_KEY: type_string, GraphSONUtil.VALUE_KEY: x})
-        serdes.objectify.assert_called_once_with(x, reader)
-        assert o is serdes.objectify()
-
-        # overridden mapping
-        type_string = "g:Int64"
-        serdes = Mock()
-        reader = GraphSONReader(deserializer_map={type_string: serdes, override_string: serdes})
-        assert gremlin_python.structure.io.graphsonV3d0._deserializers[type_string] is not reader.deserializers[
-            type_string]
-
-        value = 3
-        o = reader.to_object({GraphSONUtil.TYPE_KEY: type_string, GraphSONUtil.VALUE_KEY: value})
-        serdes.objectify.assert_called_once_with(value, reader)
-        assert o is serdes.objectify()
-
-    def test_datetime(self):
-        expected = datetime.datetime(2016, 12, 14, 16, 14, 36, 295000)
-        pts = calendar.timegm(expected.utctimetuple()) + expected.microsecond / 1e6
-        ts = int(round(pts * 1000))
-        dt = self.graphson_reader.read_object(json.dumps({"@type": "g:Date", "@value": ts}))
-        assert isinstance(dt, datetime.datetime)
-        # TINKERPOP-1848
-        assert dt == expected
-
-    def test_timestamp(self):
-        dt = self.graphson_reader.read_object(json.dumps({"@type": "g:Timestamp", "@value": 1481750076295}))
-        assert isinstance(dt, timestamp)
-        assert float(dt) == 1481750076.295
-
-    def test_duration(self):
-        d = self.graphson_reader.read_object(json.dumps({"@type": "gx:Duration", "@value": "PT120H"}))
-        assert isinstance(d, datetime.timedelta)
-        assert d == datetime.timedelta(hours=120)
-
-    def test_uuid(self):
-        prop = self.graphson_reader.read_object(
-            json.dumps({'@type': 'g:UUID', '@value': "41d2e28a-20a4-4ab0-b379-d810dede3786"}))
-        assert isinstance(prop, uuid.UUID)
-        assert str(prop) == '41d2e28a-20a4-4ab0-b379-d810dede3786'
-
-    def test_metrics(self):
-        prop = self.graphson_reader.read_object(
-            json.dumps([{'@type': 'g:TraversalMetrics', '@value': {'dur': 1.468594, 'metrics': [
-                {'@type': 'g:Metrics', '@value': {'dur': 1.380957, 'counts': {}, 'name': 'GraphStep(__.V())', 'annotations': {'percentDur': 94.03259171697556}, 'id': '4.0.0()'}},
-                {'@type': 'g:Metrics', '@value': {'dur': 0.087637, 'counts': {}, 'name': 'ReferenceElementStep', 'annotations': {'percentDur': 5.967408283024444}, 'id': '3.0.0()'}}
-            ]}}]))
-        assert isinstance(prop, list)
-        assert prop == [{'dur': 1.468594, 'metrics': [
-                {'dur': 1.380957, 'counts': {}, 'name': 'GraphStep(__.V())', 'annotations': {'percentDur': 94.03259171697556}, 'id': '4.0.0()'},
-                {'dur': 0.087637, 'counts': {}, 'name': 'ReferenceElementStep', 'annotations': {'percentDur': 5.967408283024444}, 'id': '3.0.0()'}
-                ]}]
-
-    def test_bytebuffer(self):
-        bb = self.graphson_reader.read_object(
-            json.dumps({"@type": "gx:ByteBuffer", "@value": "c29tZSBieXRlcyBmb3IgeW91"}))
-        assert isinstance(bb, ByteBufferType)
-        assert ByteBufferType("c29tZSBieXRlcyBmb3IgeW91", "utf8") == bb
-
-    def test_char(self):
-        c = self.graphson_reader.read_object(json.dumps({"@type": "gx:Char", "@value": "L"}))
-        assert isinstance(c, SingleChar)
-        assert chr(76) == c
-
-    def test_null(self):
-        c = self.graphson_reader.read_object(json.dumps(None))
-        assert c is None
-
-
-class TestGraphSONWriter(object):
-    graphson_writer = GraphSONWriter()
-    graphson_reader = GraphSONReader()
-
-    def test_collections(self):
-        assert {"@type": "g:List", "@value": [{"@type": "g:Int32", "@value": 1},
-                                              {"@type": "g:Int32", "@value": 2},
-                                              {"@type": "g:Int32", "@value": 3}]} == json.loads(
-            self.graphson_writer.write_object([1, 2, 3]))
-        assert {"@type": "g:Set", "@value": [{"@type": "g:Int32", "@value": 1},
-                                             {"@type": "g:Int32", "@value": 2},
-                                             {"@type": "g:Int32", "@value": 3}]} == json.loads(
-            self.graphson_writer.write_object(set([1, 2, 3, 3])))
-        assert {"@type": "g:Map",
-                "@value": ['a', {"@type": "g:Int32", "@value": 1}]} == json.loads(
-            self.graphson_writer.write_object({'a': 1}))
-
-    def test_numbers(self):
-        assert {"@type": "gx:Byte", "@value": 1} == json.loads(self.graphson_writer.write_object(int.__new__(SingleByte, 1)))
-        assert {"@type": "gx:Int16", "@value": 16} == json.loads(self.graphson_writer.write_object(short(16)))
-        assert {"@type": "gx:Int16", "@value": -16} == json.loads(self.graphson_writer.write_object(short(-16)))
-        assert {"@type": "g:Int64", "@value": 2} == json.loads(self.graphson_writer.write_object(long(2)))
-        assert {"@type": "g:Int64", "@value": 851401972585122} == json.loads(self.graphson_writer.write_object(long(851401972585122)))
-        assert {"@type": "g:Int64", "@value": -2} == json.loads(self.graphson_writer.write_object(long(-2)))
-        assert {"@type": "g:Int64", "@value": -851401972585122} == json.loads(self.graphson_writer.write_object(long(-851401972585122)))
-        assert {"@type": "g:Int32", "@value": 1} == json.loads(self.graphson_writer.write_object(1))
-        assert {"@type": "g:Int32", "@value": -1} == json.loads(self.graphson_writer.write_object(-1))
-        assert {"@type": "g:Int64", "@value": 851401972585122} == json.loads(self.graphson_writer.write_object(851401972585122))
-        assert {"@type": "g:Double", "@value": 3.2} == json.loads(self.graphson_writer.write_object(3.2))
-        assert {"@type": "g:Double", "@value": "NaN"} == json.loads(self.graphson_writer.write_object(float('nan')))
-        assert {"@type": "g:Double", "@value": "Infinity"} == json.loads(self.graphson_writer.write_object(float('inf')))
-        assert {"@type": "g:Double", "@value": "-Infinity"} == json.loads(self.graphson_writer.write_object(float('-inf')))
-        assert {"@type": "gx:BigDecimal", "@value": "123456789987654321123456789987654321"} == json.loads(self.graphson_writer.write_object(Decimal('123456789987654321123456789987654321')))
-        assert {"@type": "gx:BigDecimal", "@value": "NaN"} == json.loads(self.graphson_writer.write_object(Decimal('nan')))
-        assert {"@type": "gx:BigDecimal", "@value": "Infinity"} == json.loads(self.graphson_writer.write_object(Decimal('inf')))
-        assert {"@type": "gx:BigDecimal", "@value": "-Infinity"} == json.loads(self.graphson_writer.write_object(Decimal('-inf')))
-        assert {"@type": "gx:BigInteger", "@value": "123456789987654321123456789987654321"} == json.loads(self.graphson_writer.write_object(long(123456789987654321123456789987654321)))
-        assert {"@type": "gx:BigInteger", "@value": "123456789987654321123456789987654321"} == json.loads(self.graphson_writer.write_object(123456789987654321123456789987654321))
-        assert """true""" == self.graphson_writer.write_object(True)
-
-    def test_enum(self):
-        assert {"@type": "g:Merge", "@value": "onMatch"} == json.loads(self.graphson_writer.write_object(Merge.on_match))
-        assert {"@type": "g:Order", "@value": "shuffle"} == json.loads(self.graphson_writer.write_object(Order.shuffle))
-        assert {"@type": "g:Barrier", "@value": "normSack"} == json.loads(self.graphson_writer.write_object(Barrier.norm_sack))
-        assert {"@type": "g:Operator", "@value": "sum"} == json.loads(self.graphson_writer.write_object(Operator.sum_))
-        assert {"@type": "g:Operator", "@value": "sumLong"} == json.loads(self.graphson_writer.write_object(Operator.sum_long))
-        assert {"@type": "g:Direction", "@value": "OUT"} == json.loads(self.graphson_writer.write_object(Direction.OUT))
-        assert {"@type": "g:Direction", "@value": "OUT"} == json.loads(self.graphson_writer.write_object(Direction.from_))
-
-    def test_P(self):
-        result = {'@type': 'g:P',
-                  '@value': {
-                      'predicate': 'and',
-                      'value': [{
-                          '@type': 'g:P',
-                          '@value': {
-                              'predicate': 'or',
-                              'value': [{
-                                  '@type': 'g:P',
-                                  '@value': {'predicate': 'lt', 'value': 'b'}
-                              },
-                                  {'@type': 'g:P', '@value': {'predicate': 'gt', 'value': 'c'}}
-                              ]
-                          }
-                      },
-                          {'@type': 'g:P', '@value': {'predicate': 'neq', 'value': 'd'}}]}}
-
-        assert result == json.loads(
-            self.graphson_writer.write_object(P.lt("b").or_(P.gt("c")).and_(P.neq("d"))))
-
-        result = {'@type': 'g:P', '@value': {'predicate': 'within', 'value': {'@type': 'g:List', '@value': [
-            {"@type": "g:Int32", "@value": 1}, {"@type": "g:Int32", "@value": 2}]}}}
-        assert result == json.loads(self.graphson_writer.write_object(P.within([1, 2])))
-        assert result == json.loads(self.graphson_writer.write_object(P.within({1, 2})))
-        assert result == json.loads(self.graphson_writer.write_object(P.within(1, 2)))
-
-        result = {'@type': 'g:P', '@value': {'predicate': 'within', 'value': {'@type': 'g:List', '@value': [
-            {"@type": "g:Int32", "@value": 1}]}}}
-        assert result == json.loads(self.graphson_writer.write_object(P.within([1])))
-        assert result == json.loads(self.graphson_writer.write_object(P.within({1})))
-        assert result == json.loads(self.graphson_writer.write_object(P.within(1)))
-
-    def test_strategies(self):
-        # we have a proxy model for now given that we don't want to have to have g:XXX all registered on the 
-        # Gremlin traversal machine (yet)
-        assert {"@type": "g:SubgraphStrategy", "@value": {}} == json.loads(
-            self.graphson_writer.write_object(SubgraphStrategy))
-        assert {"@type": "g:SubgraphStrategy", "@value": {
-            "vertices": {"@type": "g:Bytecode", "@value": {"step": [["has", "name", "marko"]]}}}} == json.loads(
-            self.graphson_writer.write_object(SubgraphStrategy(vertices=__.has("name", "marko"))))
-
-    def test_graph(self):
-        # TODO: this assert is not compatible with python 3 and now that we test with both 2 and 3 it fails
-        assert {"@type": "g:Vertex",
-                "@value": {"id": {"@type": "g:Int64", "@value": 12}, "label": "person"}} == json.loads(
-            self.graphson_writer.write_object(Vertex(long(12), "person")))
-
-        assert {"@type": "g:Edge", "@value": {"id": {"@type": "g:Int32", "@value": 7},
-                                              "outV": {"@type": "g:Int32", "@value": 0},
-                                              "outVLabel": "person",
-                                              "label": "knows",
-                                              "inV": {"@type": "g:Int32", "@value": 1},
-                                              "inVLabel": "dog"}} == json.loads(
-            self.graphson_writer.write_object(Edge(7, Vertex(0, "person"), "knows", Vertex(1, "dog"))))
-        assert {"@type": "g:VertexProperty", "@value": {"id": "blah", "label": "keyA", "value": True,
-                                                        "vertex": "stephen"}} == json.loads(
-            self.graphson_writer.write_object(VertexProperty("blah", "keyA", True, Vertex("stephen"))))
-
-        assert {"@type": "g:Property",
-                "@value": {"key": "name", "value": "marko", "element": {"@type": "g:VertexProperty",
-                                                                        "@value": {
-                                                                            "vertex": "vertexId",
-                                                                            "id": {"@type": "g:Int32", "@value": 1234},
-                                                                            "label": "aKey"}}}} == json.loads(
-            self.graphson_writer.write_object(
-                Property("name", "marko", VertexProperty(1234, "aKey", 21345, Vertex("vertexId")))))
-
-        vertex = self.graphson_reader.read_object(self.graphson_writer.write_object(Vertex(1, "person")))
-        assert 1 == vertex.id
-        assert "person" == vertex.label
-
-        edge = self.graphson_reader.read_object(
-            self.graphson_writer.write_object(Edge(3, Vertex(1, "person"), "knows", Vertex(2, "dog"))))
-        assert "knows" == edge.label
-        assert 3 == edge.id
-        assert 1 == edge.outV.id
-        assert 2 == edge.inV.id
-
-        vertex_property = self.graphson_reader.read_object(
-            self.graphson_writer.write_object(VertexProperty(1, "age", 32, Vertex(1))))
-        assert 1 == vertex_property.id
-        assert "age" == vertex_property.key
-        assert 32 == vertex_property.value
-
-        property = self.graphson_reader.read_object(self.graphson_writer.write_object(Property("age", 32.2, Edge(1, Vertex(2), "knows", Vertex(3)))))
-        assert "age" == property.key
-        assert 32.2 == property.value
-
-    def test_custom_mapping(self):
-        # extended mapping
-        class X(object):
-            pass
-
-        serdes = Mock()
-        writer = GraphSONWriter(serializer_map={X: serdes})
-        assert X in writer.serializers
-
-        # base dicts are not modified
-        assert X not in gremlin_python.structure.io.graphsonV3d0._serializers
-
-        obj = X()
-        d = writer.to_dict(obj)
-        serdes.dictify.assert_called_once_with(obj, writer)
-        assert d is serdes.dictify()
-
-        # overridden mapping
-        serdes = Mock()
-        writer = GraphSONWriter(serializer_map={int: serdes})
-        assert gremlin_python.structure.io.graphsonV3d0._serializers[int] is not writer.serializers[int]
-
-        value = 3
-        d = writer.to_dict(value)
-        serdes.dictify.assert_called_once_with(value, writer)
-        assert d is serdes.dictify()
-
-    def test_write_long(self):
-        mapping = self.graphson_writer.to_dict(1)
-        assert mapping['@type'] == 'g:Int32'
-        assert mapping['@value'] == 1
-
-        mapping = self.graphson_writer.to_dict(long(1))
-        assert mapping['@type'] == 'g:Int64'
-        assert mapping['@value'] == 1
-
-    def test_datetime(self):
-        expected = json.dumps({"@type": "g:Date", "@value": 1481750076295}, separators=(',', ':'))
-        dt = datetime.datetime.utcfromtimestamp(1481750076295 / 1000.0)
-        output = self.graphson_writer.write_object(dt)
-        assert expected == output
-
-    def test_timestamp(self):
-        expected = json.dumps({"@type": "g:Timestamp", "@value": 1481750076295}, separators=(',', ':'))
-        ts = timestamp(1481750076295 / 1000.0)
-        output = self.graphson_writer.write_object(ts)
-        assert expected == output
-
-    def test_duration(self):
-        expected = json.dumps({"@type": "gx:Duration", "@value": "P5D"}, separators=(',', ':'))
-        d = datetime.timedelta(hours=120)
-        output = self.graphson_writer.write_object(d)
-        assert expected == output
-
-    def test_uuid(self):
-        expected = json.dumps({'@type': 'g:UUID', '@value': "41d2e28a-20a4-4ab0-b379-d810dede3786"}, separators=(',', ':'))
-        prop = uuid.UUID("41d2e28a-20a4-4ab0-b379-d810dede3786")
-        output = self.graphson_writer.write_object(prop)
-        assert expected == output
-
-    def test_bytebuffer(self):
-        expected = json.dumps({'@type': 'gx:ByteBuffer', '@value': 'c29tZSBieXRlcyBmb3IgeW91'}, separators=(',', ':'))
-        bb = ByteBufferType("c29tZSBieXRlcyBmb3IgeW91", "utf8")
-        output = self.graphson_writer.write_object(bb)
-        assert expected == output
-
-    def test_char(self):
-        expected = json.dumps({'@type': 'gx:Char', '@value': 'L'}, separators=(',', ':'))
-        c = str.__new__(SingleChar, chr(76))
-        output = self.graphson_writer.write_object(c)
-        assert expected == output