Merge branch '3.6-dev'
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 8cea5be..4db0a9a 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -57,9 +57,11 @@
 
 [[release-3-6-5]]
 === TinkerPop 3.6.5 (Release Date: NOT OFFICIALLY RELEASED YET)
+
 This release also includes changes from <<release-3-5-7, 3.5.7>>.
 
-
+* Added `text/plain` MIME type to the HTTP endpoint to return a Gremlin Console-like representation of the data.
+* Added GraphBinary serialization option to the HTTP endpoint.
 
 [[release-3-6-4]]
 === TinkerPop 3.6.4 (Release Date: May 12, 2023)
diff --git a/docs/src/recipes/olap-spark-yarn.asciidoc b/docs/src/recipes/olap-spark-yarn.asciidoc
index aeb99a2..94d2071 100644
--- a/docs/src/recipes/olap-spark-yarn.asciidoc
+++ b/docs/src/recipes/olap-spark-yarn.asciidoc
@@ -87,26 +87,46 @@
 $ . bin/spark-yarn.sh
 ----
 
-[gremlin-groovy]
+[source]
 ----
-hadoop = System.getenv('HADOOP_HOME')
-hadoopConfDir = System.getenv('HADOOP_CONF_DIR')
-archive = 'spark-gremlin.zip'
-archivePath = "/tmp/$archive"
-['bash', '-c', "rm -f $archivePath; cd ext/spark-gremlin/lib && zip $archivePath *.jar"].execute().waitFor()
-conf = new Configurations().properties(new File('conf/hadoop/hadoop-gryo.properties'))
-conf.setProperty('spark.master', 'yarn')
-conf.setProperty('spark.submit.deployMode', 'client')
-conf.setProperty('spark.yarn.archive', "$archivePath")
-conf.setProperty('spark.yarn.appMasterEnv.CLASSPATH', "./__spark_libs__/*:$hadoopConfDir")
-conf.setProperty('spark.executor.extraClassPath', "./__spark_libs__/*:$hadoopConfDir")
-conf.setProperty('spark.driver.extraLibraryPath', "$hadoop/lib/native:$hadoop/lib/native/Linux-amd64-64")
-conf.setProperty('spark.executor.extraLibraryPath', "$hadoop/lib/native:$hadoop/lib/native/Linux-amd64-64")
-conf.setProperty('gremlin.spark.persistContext', 'true')
-hdfs.copyFromLocal('data/tinkerpop-modern.kryo', 'tinkerpop-modern.kryo')
-graph = GraphFactory.open(conf)
-g = traversal().withEmbedded(graph).withComputer(SparkGraphComputer)
-g.V().group().by(values('name')).by(both().count())
+gremlin> hadoop = System.getenv('HADOOP_HOME')
+==>/home/xiazcy/.sdkman/candidates/hadoop/current
+gremlin> hadoopConfDir = System.getenv('HADOOP_CONF_DIR')
+==>/home/xiazcy/.sdkman/candidates/hadoop/current/etc/hadoop
+gremlin> archive = 'spark-gremlin.zip'
+==>spark-gremlin.zip
+gremlin> archivePath = "/tmp/$archive"
+==>/tmp/spark-gremlin.zip
+gremlin> ['bash', '-c', "rm -f $archivePath; cd ext/spark-gremlin/lib && zip $archivePath *.jar"].execute().waitFor()
+==>0
+gremlin> conf = new Configurations().properties(new File('conf/hadoop/hadoop-gryo.properties'))
+==>org.apache.commons.configuration2.PropertiesConfiguration@6c8d8b60
+gremlin> conf.setProperty('spark.master', 'yarn')
+==>null
+gremlin> conf.setProperty('spark.submit.deployMode', 'client')
+==>null
+gremlin> conf.setProperty('spark.yarn.archive', "$archivePath")
+==>null
+gremlin> conf.setProperty('spark.yarn.appMasterEnv.CLASSPATH', "./__spark_libs__/*:$hadoopConfDir")
+==>null
+gremlin> conf.setProperty('spark.executor.extraClassPath', "./__spark_libs__/*:$hadoopConfDir")
+==>null
+gremlin> conf.setProperty('spark.driver.extraLibraryPath', "$hadoop/lib/native:$hadoop/lib/native/Linux-amd64-64")
+==>null
+gremlin> conf.setProperty('spark.executor.extraLibraryPath', "$hadoop/lib/native:$hadoop/lib/native/Linux-amd64-64")
+==>null
+gremlin> conf.setProperty('gremlin.spark.persistContext', 'true')
+==>null
+gremlin> hdfs.copyFromLocal('data/tinkerpop-modern.kryo', 'tinkerpop-modern.kryo')
+==>null
+gremlin> graph = GraphFactory.open(conf)
+==>hadoopgraph[gryoinputformat->gryooutputformat]
+gremlin> g = traversal().withEmbedded(graph).withComputer(SparkGraphComputer)
+==>graphtraversalsource[hadoopgraph[gryoinputformat->gryooutputformat], sparkgraphcomputer]
+gremlin> g.V().group().by(values('name')).by(both().count())
+[WARN] o.a.s.i.Logging - Your hostname, ubuntu-22 resolves to a loopback address: 127.0.1.1; using 10.0.2.15 instead (on interface enp0s3)
+[WARN] o.a.s.i.Logging - Set SPARK_LOCAL_IP if you need to bind to another address
+==>[ripple:1,peter:1,vadas:1,josh:3,lop:3,marko:3]
 ----
 
 If you run into exceptions, you will have to dig into the logs. You can do this from the command line with
diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index 6516c77..6d70cf3 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -901,6 +901,21 @@
 types are preserved or to pass complex objects such as lists or maps, use `POST` which will at least support the
 allowed JSON data types.
 
+Passing the `Accept` header with a valid MIME type will trigger the server to return the result in a particular format.
+Note that in addition to the formats available given the server's `serializers` configuration, there is also a basic
+`text/plain` format which produces a text representation of results similar to the Gremlin Console:
+
+[source,text]
+----
+$ curl -H "Accept:text/plain" -X POST -d "{\"gremlin\":\"g.V()\"}" "http://localhost:8182"
+==>v[1]
+==>v[2]
+==>v[3]
+==>v[4]
+==>v[5]
+==>v[6]
+----
+
 Finally, as Gremlin Server can host multiple `ScriptEngine` instances (e.g. `gremlin-groovy`, `nashorn`), it is
 possible to define the language to utilize to process the request:
 
diff --git a/docs/src/upgrade/release-3.6.x.asciidoc b/docs/src/upgrade/release-3.6.x.asciidoc
index e416aa2..d54ad7a 100644
--- a/docs/src/upgrade/release-3.6.x.asciidoc
+++ b/docs/src/upgrade/release-3.6.x.asciidoc
@@ -29,7 +29,24 @@
 
 === Upgrading for Users
 
+==== HTTP Plain Text
 
+A `text/plain` MIME type has been added to the HTTP endpoint to return Gremlin Console formatted results in plain text.
+This format can be helpful for a variety of reasons. Reading JSON formatted results can be difficult sometimes and
+`text/plain` is a more simple, readable representation for when that is helpful.
+
+[source,text]
+----
+$ curl -H "Accept:text/plain" -X POST -d "{\"gremlin\":\"g.V()\"}" "http://localhost:8182"
+==>v[1]
+==>v[2]
+==>v[3]
+==>v[4]
+==>v[5]
+==>v[6]
+----
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-2947[TINKERPOP-2947]
 
 == TinkerPop 3.6.4
 
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/WebSocketGremlinRequestEncoder.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/WebSocketGremlinRequestEncoder.java
index 042980c..05226f7 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/WebSocketGremlinRequestEncoder.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/handler/WebSocketGremlinRequestEncoder.java
@@ -54,7 +54,7 @@
                 objects.add(new BinaryWebSocketFrame(encodedMessage));
             } else {
                 final MessageTextSerializer<?> textSerializer = (MessageTextSerializer<?>) serializer;
-                objects.add(new TextWebSocketFrame(textSerializer.serializeRequestAsString(requestMessage)));
+                objects.add(new TextWebSocketFrame(textSerializer.serializeRequestAsString(requestMessage, channelHandlerContext.alloc())));
             }
         } catch (Exception ex) {
             throw new ResponseException(ResponseStatusCode.REQUEST_ERROR_SERIALIZATION, String.format(
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/AbstractSession.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/AbstractSession.java
index 2587bea..7c04e9e 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/AbstractSession.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/AbstractSession.java
@@ -752,7 +752,7 @@
                         .code(code)
                         .statusAttributes(statusAttributes)
                         .responseMetaData(responseMetaData)
-                        .result(aggregate).create()));
+                        .result(aggregate).create(), nettyContext.alloc()));
             }
         } catch (Exception ex) {
             logger.warn("The result [{}] in the request {} could not be serialized and returned.", aggregate, msg.getRequestId(), ex);
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/GremlinResponseFrameEncoder.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/GremlinResponseFrameEncoder.java
index fa70e5f..879b44f 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/GremlinResponseFrameEncoder.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/GremlinResponseFrameEncoder.java
@@ -83,9 +83,9 @@
                 // if the request came in on a session then the serialization must occur that same thread except
                 // in the case of errors for reasons described above.
                 if (null == session || !o.getStatus().getCode().isSuccess())
-                    serialized = new Frame(textSerializer.serializeResponseAsString(o));
+                    serialized = new Frame(textSerializer.serializeResponseAsString(o, ctx.alloc()));
                 else
-                    serialized = new Frame(session.getExecutor().submit(() -> textSerializer.serializeResponseAsString(o)).get());
+                    serialized = new Frame(session.getExecutor().submit(() -> textSerializer.serializeResponseAsString(o, ctx.alloc())).get());
 
                 objects.add(serialized);
             }
@@ -101,7 +101,7 @@
                 objects.add(serializer.serializeResponseAsBinary(error, ctx.alloc()));
             } else {
                 final MessageTextSerializer<?> textSerializer = (MessageTextSerializer<?>) serializer;
-                objects.add(textSerializer.serializeResponseAsString(error));
+                objects.add(textSerializer.serializeResponseAsString(error, ctx.alloc()));
             }
         }
     }
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
index 6e0217b..7eda645 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
@@ -19,12 +19,14 @@
 package org.apache.tinkerpop.gremlin.server.handler;
 
 import com.codahale.metrics.Timer;
+import org.apache.tinkerpop.gremlin.util.message.RequestMessage;
 import org.apache.tinkerpop.gremlin.jsr223.GremlinScriptChecker;
 import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.AbstractTraverser;
 import org.apache.tinkerpop.gremlin.structure.Element;
 import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceFactory;
 import org.apache.tinkerpop.gremlin.util.Tokens;
 import org.apache.tinkerpop.gremlin.util.ser.SerializationException;
+import org.apache.tinkerpop.gremlin.server.util.TextPlainMessageSerializer;
 import org.javatuples.Pair;
 import org.javatuples.Quartet;
 import org.slf4j.Logger;
@@ -65,10 +67,12 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Function;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
@@ -104,6 +108,11 @@
      */
     private final Map<String, MessageSerializer<?>> serializers;
 
+    /**
+     * Serializer for {@code text/plain} which is a serializer exclusive to HTTP.
+     */
+    private static final TextPlainMessageSerializer textPlainSerializer = new TextPlainMessageSerializer();
+
     private final GremlinExecutor gremlinExecutor;
     private final GraphManager graphManager;
     private final Settings settings;
@@ -244,7 +253,7 @@
                             attemptCommit(requestArguments.getValue3(), graphManager, settings.strictTransactionManagement);
 
                             try {
-                                return Unpooled.wrappedBuffer(serializer.getValue1().serializeResponseAsString(responseMessage).getBytes(UTF8));
+                                return Unpooled.wrappedBuffer(serializer.getValue1().serializeResponseAsString(responseMessage, ctx.alloc()).getBytes(UTF8));
                             } catch (Exception ex) {
                                 logger.warn(String.format("Error during serialization for %s", responseMessage), ex);
 
@@ -352,6 +361,9 @@
             final String accept = p.getValue0().equals("*/*") ? "application/json" : p.getValue0();
             if (serializers.containsKey(accept))
                 return Pair.with(accept, (MessageTextSerializer<?>) serializers.get(accept));
+            else if (accept.equals("text/plain")) {
+                return Pair.with(accept, textPlainSerializer);
+            }
         }
 
         return null;
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
index e3d38b9..49b9f6f 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
@@ -299,7 +299,7 @@
                         .code(code)
                         .statusAttributes(statusAttributes)
                         .responseMetaData(responseMetaData)
-                        .result(aggregate).create()));
+                        .result(aggregate).create(), nettyContext.alloc()));
             }
         } catch (Exception ex) {
             logger.warn("The result [{}] in the request {} could not be serialized and returned.", aggregate, msg.getRequestId(), ex);
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/TextPlainMessageSerializer.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/TextPlainMessageSerializer.java
new file mode 100644
index 0000000..fe6cdbf
--- /dev/null
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/TextPlainMessageSerializer.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.server.util;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufAllocator;
+import org.apache.tinkerpop.gremlin.util.message.RequestMessage;
+import org.apache.tinkerpop.gremlin.util.message.ResponseMessage;
+import org.apache.tinkerpop.gremlin.util.ser.MessageTextSerializer;
+import org.apache.tinkerpop.gremlin.util.ser.SerializationException;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * A highly use-case specific serializer that only has context for HTTP where results simply need to be converted
+ * to string in a line by line fashion for text based returns.
+ */
+public class TextPlainMessageSerializer implements MessageTextSerializer<Function<Object, String>> {
+
+    @Override
+    public Function<Object, String> getMapper() {
+        return Objects::toString;
+    }
+
+    @Override
+    public ByteBuf serializeResponseAsBinary(final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException {
+        throw new UnsupportedOperationException("text/plain does not produce binary");
+    }
+
+    @Override
+    public ByteBuf serializeRequestAsBinary(final RequestMessage requestMessage, final ByteBufAllocator allocator) throws SerializationException {
+        throw new UnsupportedOperationException("text/plain does not produce binary");
+    }
+
+    @Override
+    public RequestMessage deserializeRequest(final ByteBuf msg) throws SerializationException {
+        throw new UnsupportedOperationException("text/plain does not have deserialization functions");
+    }
+
+    @Override
+    public ResponseMessage deserializeResponse(final ByteBuf msg) throws SerializationException {
+        throw new UnsupportedOperationException("text/plain does not have deserialization functions");
+    }
+
+    @Override
+    public String[] mimeTypesSupported() {
+        return new String[] { "text/plain" };
+    }
+
+    @Override
+    public String serializeResponseAsString(final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException {
+        final StringBuilder sb = new StringBuilder();
+
+        // this should only serialize success conditions so all should have data in List form
+        final List<Object> data = (List<Object>) responseMessage.getResult().getData();
+        for (int ix = 0; ix < data.size(); ix ++) {
+            sb.append("==>");
+            sb.append(data.get(ix));
+            if (ix < data.size() - 1)
+                sb.append(System.lineSeparator());
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public String serializeRequestAsString(final RequestMessage requestMessage, final ByteBufAllocator allocator) throws SerializationException {
+        throw new UnsupportedOperationException("text/plain does not have any need to serialize requests");
+    }
+
+    @Override
+    public RequestMessage deserializeRequest(final String msg) throws SerializationException {
+        throw new UnsupportedOperationException("text/plain does not have deserialization functions");
+    }
+
+    @Override
+    public ResponseMessage deserializeResponse(final String msg) throws SerializationException {
+        throw new UnsupportedOperationException("text/plain does not have deserialization functions");
+    }
+}
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
index 028583f..b52bda0 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
@@ -20,6 +20,8 @@
 
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.http.HttpHeaders;
+import org.apache.tinkerpop.gremlin.util.message.ResponseMessage;
+import org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1;
 import org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV1d0;
 import org.apache.tinkerpop.gremlin.util.Tokens;
 import org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV2d0;
@@ -36,15 +38,17 @@
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;
 import org.apache.tinkerpop.gremlin.server.handler.SaslAndHttpBasicAuthenticationHandler;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.io.binary.TypeSerializerRegistry;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
 import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
 import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
 import org.junit.Test;
 
-import java.io.File;
 import java.time.Instant;
 import java.util.Base64;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executors;
@@ -54,7 +58,9 @@
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
 import static org.hamcrest.core.StringContains.containsString;
+import static org.hamcrest.core.StringRegularExpression.matchesRegex;
 import static org.hamcrest.core.StringStartsWith.startsWith;
 import static org.junit.Assert.assertEquals;
 
@@ -366,6 +372,68 @@
     }
 
     @Test
+    public void should200OnGETWithGremlinQueryStringArgumentWithIteratorResultGraphBinary() throws Exception {
+        final CloseableHttpClient httpclient = HttpClients.createDefault();
+        final HttpGet httpget = new HttpGet(TestClientFactory.createURLString("?gremlin=gclassic.V()"));
+        final String mime = SerTokens.MIME_GRAPHBINARY_V1D0;
+        httpget.addHeader("Accept", mime);
+
+        try (final CloseableHttpResponse response = httpclient.execute(httpget)) {
+            assertEquals(200, response.getStatusLine().getStatusCode());
+            assertEquals(mime, response.getEntity().getContentType().getValue());
+            final String base64 = EntityUtils.toString(response.getEntity());
+            final GraphBinaryMessageSerializerV1 serializer = new GraphBinaryMessageSerializerV1(TypeSerializerRegistry.INSTANCE);
+            final ResponseMessage msg = serializer.deserializeResponse(base64);
+            final List<Object> data = (List<Object>) msg.getResult().getData();
+            assertEquals(6, data.size());
+            for (Object o : data) {
+                assertThat(o, instanceOf(Vertex.class));
+            }
+        }
+    }
+
+    @Test
+    public void should200OnGETWithGremlinQueryStringArgumentWithIteratorResultGraphBinaryToString() throws Exception {
+        final CloseableHttpClient httpclient = HttpClients.createDefault();
+        final HttpGet httpget = new HttpGet(TestClientFactory.createURLString("?gremlin=gclassic.V()"));
+        final String mime = SerTokens.MIME_GRAPHBINARY_V1D0 + "-stringd";
+        httpget.addHeader("Accept", mime);
+
+        try (final CloseableHttpResponse response = httpclient.execute(httpget)) {
+            assertEquals(200, response.getStatusLine().getStatusCode());
+            assertEquals(mime, response.getEntity().getContentType().getValue());
+            final String base64 = EntityUtils.toString(response.getEntity());
+            final GraphBinaryMessageSerializerV1 serializer = new GraphBinaryMessageSerializerV1(TypeSerializerRegistry.INSTANCE);
+            final ResponseMessage msg = serializer.deserializeResponse(base64);
+            final List<Object> data = (List<Object>) msg.getResult().getData();
+            assertEquals(6, data.size());
+            for (Object o : data) {
+                assertThat(o, instanceOf(String.class));
+                assertThat((String) o, matchesRegex("v\\[\\d\\]"));
+            }
+        }
+    }
+
+    @Test
+    public void should200OnGETWithGremlinQueryStringArgumentWithIteratorResultTextPlain() throws Exception {
+        final CloseableHttpClient httpclient = HttpClients.createDefault();
+        final HttpGet httpget = new HttpGet(TestClientFactory.createURLString("?gremlin=gclassic.V()"));
+        final String mime = "text/plain";
+        httpget.addHeader("Accept", mime);
+
+        try (final CloseableHttpResponse response = httpclient.execute(httpget)) {
+            assertEquals(200, response.getStatusLine().getStatusCode());
+            assertEquals(mime, response.getEntity().getContentType().getValue());
+            final String text = EntityUtils.toString(response.getEntity());
+            final String[] split = text.split(System.lineSeparator());
+            assertEquals(6, split.length);
+            for (String line : split) {
+                assertThat(line, matchesRegex("==>v\\[\\d\\]"));
+            }
+        }
+    }
+
+    @Test
     public void should200OnGETWithGremlinQueryStringArgument() throws Exception {
         final CloseableHttpClient httpclient = HttpClients.createDefault();
         final HttpGet httpget = new HttpGet(TestClientFactory.createURLString("?gremlin=2-1"));
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/TextPlainMessageSerializerTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/TextPlainMessageSerializerTest.java
new file mode 100644
index 0000000..b88daaf
--- /dev/null
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/util/TextPlainMessageSerializerTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.server.util;
+
+import io.netty.buffer.ByteBufAllocator;
+import org.apache.tinkerpop.gremlin.util.message.ResponseMessage;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import static org.junit.Assert.assertEquals;
+
+public class TextPlainMessageSerializerTest {
+
+    @Test
+    public void shouldProducePlainText() throws Exception {
+        final Map<String, Object> m = new HashMap<>();
+        final ResponseMessage msg = ResponseMessage.build(UUID.randomUUID()).
+                result(Arrays.asList(1, new DetachedVertex(100, "person", m), java.awt.Color.RED)).create();
+
+        final TextPlainMessageSerializer messageSerializer = new TextPlainMessageSerializer();
+        final String output = messageSerializer.serializeResponseAsString(msg, ByteBufAllocator.DEFAULT);
+        final String exp = "==>1" + System.lineSeparator() +
+                           "==>v[100]" + System.lineSeparator() +
+                           "==>java.awt.Color[r=255,g=0,b=0]";
+        assertEquals(exp, output);
+    }
+}
diff --git a/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/socket/server/TestWSGremlinInitializer.java b/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/socket/server/TestWSGremlinInitializer.java
index 489d835..f8f48e2 100644
--- a/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/socket/server/TestWSGremlinInitializer.java
+++ b/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/socket/server/TestWSGremlinInitializer.java
@@ -19,6 +19,7 @@
 package org.apache.tinkerpop.gremlin.socket.server;
 
 import io.netty.buffer.ByteBufAllocator;
+import io.netty.buffer.UnpooledByteBufAllocator;
 import io.netty.handler.codec.http.HttpHeaders;
 import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
 import org.apache.tinkerpop.gremlin.util.ser.AbstractMessageSerializer;
@@ -63,6 +64,7 @@
      * Gremlin serializer used for serializing/deserializing the request/response. This should be same as client.
      */
     private static AbstractMessageSerializer SERIALIZER;
+    private final static ByteBufAllocator allocator = UnpooledByteBufAllocator.DEFAULT;
 
     public TestWSGremlinInitializer(final SocketServerSettings settings) {
         this.settings = settings;
@@ -131,7 +133,7 @@
                 final ResponseMessage responseMessage = ResponseMessage.build(msg)
                         .code(ResponseStatusCode.SERVER_ERROR)
                         .statusAttributeException(new RuntimeException()).create();
-                ctx.channel().writeAndFlush(new BinaryWebSocketFrame(SERIALIZER.serializeResponseAsBinary(responseMessage, ByteBufAllocator.DEFAULT)));
+                ctx.channel().writeAndFlush(new BinaryWebSocketFrame(SERIALIZER.serializeResponseAsBinary(responseMessage, allocator)));
             } else if (msg.getRequestId().equals(settings.CLOSE_CONNECTION_REQUEST_ID) || msg.getRequestId().equals(settings.CLOSE_CONNECTION_REQUEST_ID_2)) {
                 Thread.sleep(1000);
                 ctx.channel().writeAndFlush(new CloseWebSocketFrame());
@@ -159,7 +161,7 @@
             final List<Vertex> t = new ArrayList<>(1);
             t.add(g.V().limit(1).next());
 
-            return SERIALIZER.serializeResponseAsBinary(ResponseMessage.build(requestID).result(t).create(), ByteBufAllocator.DEFAULT);
+            return SERIALIZER.serializeResponseAsBinary(ResponseMessage.build(requestID).result(t).create(), allocator);
         }
 
         /**
@@ -170,7 +172,7 @@
             //Need to package message in a list of size 1 as some GLV's serializers require all messages to be in a list
             final List<String> messageList = new ArrayList<>(1);
             messageList.add(message);
-            return SERIALIZER.serializeResponseAsBinary(ResponseMessage.build(requestID).result(messageList).create(), ByteBufAllocator.DEFAULT);
+            return SERIALIZER.serializeResponseAsBinary(ResponseMessage.build(requestID).result(messageList).create(), allocator);
         }
 
         /**
diff --git a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphBinaryMessageSerializerV1.java b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphBinaryMessageSerializerV1.java
index 876dd45..28adcf3 100644
--- a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphBinaryMessageSerializerV1.java
+++ b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphBinaryMessageSerializerV1.java
@@ -20,6 +20,7 @@
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufAllocator;
+import io.netty.buffer.Unpooled;
 import org.apache.tinkerpop.gremlin.util.message.RequestMessage;
 import org.apache.tinkerpop.gremlin.util.message.ResponseMessage;
 import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryIo;
@@ -36,6 +37,7 @@
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
+import java.util.Base64;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -43,7 +45,7 @@
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 
-public class GraphBinaryMessageSerializerV1 extends AbstractMessageSerializer<GraphBinaryMapper> {
+public class GraphBinaryMessageSerializerV1 extends AbstractMessageSerializer<GraphBinaryMapper> implements MessageTextSerializer<GraphBinaryMapper> {
 
     public static final String TOKEN_CUSTOM = "custom";
     public static final String TOKEN_BUILDER = "builder";
@@ -52,6 +54,9 @@
     private static final String MIME_TYPE = SerTokens.MIME_GRAPHBINARY_V1D0;
     private static final String MIME_TYPE_STRINGD = SerTokens.MIME_GRAPHBINARY_V1D0 + "-stringd";
 
+    private static final Base64.Encoder base64Encoder = Base64.getEncoder();
+    private static final Base64.Decoder base64Decoder = Base64.getDecoder();
+
     private byte[] header = MIME_TYPE.getBytes(UTF_8);
     private boolean serializeToString = false;
     private GraphBinaryReader reader;
@@ -185,6 +190,41 @@
         return new String[]{serializeToString ? MIME_TYPE_STRINGD : MIME_TYPE};
     }
 
+    @Override
+    public String serializeResponseAsString(final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException {
+        final ByteBuf bb = serializeResponseAsBinary(responseMessage, allocator);
+        return base64Encoder.encodeToString(convertToBytes(bb));
+    }
+
+    @Override
+    public String serializeRequestAsString(final RequestMessage requestMessage, final ByteBufAllocator allocator) throws SerializationException {
+        final ByteBuf bb = serializeRequestAsBinary(requestMessage, allocator);
+        return base64Encoder.encodeToString(convertToBytes(bb));
+    }
+
+    @Override
+    public RequestMessage deserializeRequest(final String msg) throws SerializationException {
+        return deserializeRequest(convertToByteBuf(msg));
+    }
+
+    @Override
+    public ResponseMessage deserializeResponse(final String msg) throws SerializationException {
+        return deserializeResponse(convertToByteBuf(msg));
+    }
+
+    private byte[] convertToBytes(final ByteBuf bb) {
+        byte[] bytes = new byte[bb.readableBytes()];
+        bb.getBytes(bb.readerIndex(), bytes);
+        return bytes;
+    }
+
+    private ByteBuf convertToByteBuf(final String msg) {
+        final byte[] b = base64Decoder.decode(msg);
+        final ByteBuf bb = Unpooled.buffer(b.length);
+        bb.writeBytes(b);
+        return bb;
+    }
+
     private void addCustomClasses(final Map<String, Object> config, final TypeSerializerRegistry.Builder builder) {
         final List<String> classNameList = getListStringFromConfig(TOKEN_CUSTOM, config);
 
diff --git a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV1d0.java b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV1d0.java
index ff08eef..c1291bf 100644
--- a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV1d0.java
+++ b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV1d0.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.util.ser;
 
+import io.netty.buffer.ByteBufAllocator;
 import org.apache.tinkerpop.gremlin.util.message.RequestMessage;
 import org.apache.tinkerpop.gremlin.util.message.ResponseMessage;
 import org.apache.tinkerpop.gremlin.util.message.ResponseStatusCode;
@@ -95,7 +96,7 @@
     }
 
     @Override
-    public String serializeResponseAsString(final ResponseMessage responseMessage) throws SerializationException {
+    public String serializeResponseAsString(final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException {
         try {
             return mapper.writeValueAsString(responseMessage);
         } catch (Exception ex) {
@@ -115,7 +116,7 @@
     }
 
     @Override
-    public String serializeRequestAsString(final RequestMessage requestMessage) throws SerializationException {
+    public String serializeRequestAsString(final RequestMessage requestMessage, final ByteBufAllocator allocator) throws SerializationException {
         try {
             return mapper.writeValueAsString(requestMessage);
         } catch (Exception ex) {
diff --git a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV2d0.java b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV2d0.java
index 89efc47..d0a434a 100644
--- a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV2d0.java
+++ b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV2d0.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.util.ser;
 
+import io.netty.buffer.ByteBufAllocator;
 import org.apache.tinkerpop.gremlin.util.message.RequestMessage;
 import org.apache.tinkerpop.gremlin.util.message.ResponseMessage;
 import org.apache.tinkerpop.gremlin.util.message.ResponseStatusCode;
@@ -108,7 +109,7 @@
     }
 
     @Override
-    public String serializeResponseAsString(final ResponseMessage responseMessage) throws SerializationException {
+    public String serializeResponseAsString(final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException {
         try {
             return mapper.writeValueAsString(responseMessage);
         } catch (Exception ex) {
@@ -128,7 +129,7 @@
     }
 
     @Override
-    public String serializeRequestAsString(final RequestMessage requestMessage) throws SerializationException {
+    public String serializeRequestAsString(final RequestMessage requestMessage, final ByteBufAllocator allocator) throws SerializationException {
         try {
             return mapper.writeValueAsString(requestMessage);
         } catch (Exception ex) {
diff --git a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV3d0.java b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV3d0.java
index acdbffd..8021392 100644
--- a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV3d0.java
+++ b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV3d0.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.util.ser;
 
+import io.netty.buffer.ByteBufAllocator;
 import org.apache.tinkerpop.gremlin.util.message.RequestMessage;
 import org.apache.tinkerpop.gremlin.util.message.ResponseMessage;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper;
@@ -106,7 +107,7 @@
     }
 
     @Override
-    public String serializeResponseAsString(final ResponseMessage responseMessage) throws SerializationException {
+    public String serializeResponseAsString(final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException {
         try {
             return mapper.writeValueAsString(responseMessage);
         } catch (Exception ex) {
@@ -126,7 +127,7 @@
     }
 
     @Override
-    public String serializeRequestAsString(final RequestMessage requestMessage) throws SerializationException {
+    public String serializeRequestAsString(final RequestMessage requestMessage, final ByteBufAllocator allocator) throws SerializationException {
         try {
             return mapper.writeValueAsString(requestMessage);
         } catch (Exception ex) {
diff --git a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/MessageTextSerializer.java b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/MessageTextSerializer.java
index d81af2b..7d46aab 100644
--- a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/MessageTextSerializer.java
+++ b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/MessageTextSerializer.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.util.ser;
 
+import io.netty.buffer.ByteBufAllocator;
 import org.apache.tinkerpop.gremlin.util.MessageSerializer;
 import org.apache.tinkerpop.gremlin.util.message.RequestMessage;
 import org.apache.tinkerpop.gremlin.util.message.ResponseMessage;
@@ -31,9 +32,9 @@
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public interface MessageTextSerializer<M> extends MessageSerializer<M> {
-    public String serializeResponseAsString(final ResponseMessage responseMessage) throws SerializationException;
+    public String serializeResponseAsString(final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException;
 
-    public String serializeRequestAsString(final RequestMessage requestMessage) throws SerializationException;
+    public String serializeRequestAsString(final RequestMessage requestMessage, final ByteBufAllocator allocator) throws SerializationException;
 
     public RequestMessage deserializeRequest(final String msg) throws SerializationException;
 
diff --git a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV1d0Test.java b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV1d0Test.java
index 8e45448..d5d3d24 100644
--- a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV1d0Test.java
+++ b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV1d0Test.java
@@ -18,6 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.util.ser;
 
+import io.netty.buffer.ByteBufAllocator;
 import org.apache.tinkerpop.gremlin.util.message.RequestMessage;
 import org.apache.tinkerpop.gremlin.util.message.ResponseMessage;
 import org.apache.tinkerpop.gremlin.util.message.ResponseStatusCode;
@@ -74,6 +75,7 @@
     private static final RequestMessage msg = RequestMessage.build("op")
             .overrideRequestId(UUID.fromString("2D62161B-9544-4F39-AF44-62EC49F9A595")).create();
     private static final ObjectMapper mapper = new ObjectMapper();
+    private static final ByteBufAllocator allocator = ByteBufAllocator.DEFAULT;
 
     @Test
     public void shouldConfigureIoRegistry() throws Exception {
@@ -86,7 +88,7 @@
 
         final ResponseMessage toSerialize = ResponseMessage.build(UUID.fromString("2D62161B-9544-4F39-AF44-62EC49F9A595"))
                 .result(Color.RED).create();
-        final String results = serializer.serializeResponseAsString(toSerialize);
+        final String results = serializer.serializeResponseAsString(toSerialize, allocator);
         final JsonNode json = mapper.readTree(results);
         assertNotNull(json);
         assertThat(json.get(SerTokens.TOKEN_RESULT).get(SerTokens.TOKEN_DATA).booleanValue(), is(true));
@@ -95,7 +97,7 @@
     @Test
     public void shouldSerializeToJsonNullResultReturnsNull() throws Exception {
         final ResponseMessage message = ResponseMessage.build(msg).create();
-        final String results = SERIALIZER.serializeResponseAsString(message);
+        final String results = SERIALIZER.serializeResponseAsString(message, allocator);
         final JsonNode json = mapper.readTree(results);
         assertNotNull(json);
         assertEquals(msg.getRequestId().toString(), json.path(SerTokens.TOKEN_REQUEST).asText());
@@ -108,7 +110,7 @@
         funList.add(new FunObject("x"));
         funList.add(new FunObject("y"));
 
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(funList).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(funList).create(), allocator);
         final JsonNode json = mapper.readTree(results);
 
         assertNotNull(json);
@@ -127,7 +129,7 @@
         funList.add(new FunObject("x"));
         funList.add(new FunObject("y"));
 
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(funList.iterator()).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(funList.iterator()).create(), allocator);
         final JsonNode json = mapper.readTree(results);
 
         assertNotNull(json);
@@ -148,7 +150,7 @@
         funList.add(null);
         funList.add(new FunObject("y"));
 
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(funList.iterator()).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(funList.iterator()).create(), allocator);
         final JsonNode json = mapper.readTree(results);
 
         assertNotNull(json);
@@ -172,7 +174,7 @@
         map.put("y", "some");
         map.put("z", innerMap);
 
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(map).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(map).create(), allocator);
         final JsonNode json = mapper.readTree(results);
 
         assertNotNull(json);
@@ -199,7 +201,7 @@
         map.put(v1, 100);
         map.put(d, "test");
 
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(IteratorUtils.asList(map)).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(IteratorUtils.asList(map)).create(), allocator);
         final JsonNode json = mapper.readTree(results);
 
         assertNotNull(json);
@@ -226,7 +228,7 @@
         e.property("abc", 123);
 
         final Iterable<Edge> iterable = IteratorUtils.list(g.edges());
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(iterable).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(iterable).create(), allocator);
 
         final JsonNode json = mapper.readTree(results);
 
@@ -260,7 +262,7 @@
         e.property("abc", 123);
 
         final Iterable<Property<Object>> iterable = IteratorUtils.list(e.properties("abc"));
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(iterable).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(iterable).create(), allocator);
 
         final JsonNode json = mapper.readTree(results);
 
@@ -293,7 +295,7 @@
         v.property(VertexProperty.Cardinality.single, "friends", friends);
 
         final Iterable iterable = IteratorUtils.list(g.vertices());
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(iterable).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(iterable).create(), allocator);
         final JsonNode json = mapper.readTree(results);
 
         assertNotNull(json);
@@ -334,7 +336,7 @@
         final Map<Vertex, Integer> map = new HashMap<>();
         map.put(g.V().has("name", "marko").next(), 1000);
 
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(map).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(map).create(), allocator);
         final JsonNode json = mapper.readTree(results);
 
         assertNotNull(json);
@@ -393,7 +395,7 @@
                 .statusMessage("worked")
                 .create();
 
-        final String results = SERIALIZER.serializeResponseAsString(response);
+        final String results = SERIALIZER.serializeResponseAsString(response, allocator);
         final ResponseMessage deserialized = SERIALIZER.deserializeResponse(results);
 
         assertEquals(id, deserialized.getRequestId());
@@ -423,7 +425,7 @@
                 .statusMessage(null)
                 .create();
 
-        final String results = SERIALIZER.serializeResponseAsString(response);
+        final String results = SERIALIZER.serializeResponseAsString(response, allocator);
         final ResponseMessage deserialized = SERIALIZER.deserializeResponse(results);
         Assert.assertNotNull(SERIALIZER.getClass().getSimpleName() + " should be able to deserialize ResponseMessage "
                         + "with null message field", deserialized);
@@ -436,7 +438,7 @@
         final Tree t = g.V(1).out().properties("name").tree().next();
 
         
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(t).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(t).create(), allocator);
 
         final JsonNode json = mapper.readTree(results);
 
diff --git a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV2d0Test.java b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV2d0Test.java
index a091006..2a0bf47 100644
--- a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV2d0Test.java
+++ b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV2d0Test.java
@@ -104,7 +104,7 @@
 
         final ResponseMessage toSerialize = ResponseMessage.build(UUID.fromString("2D62161B-9544-4F39-AF44-62EC49F9A595"))
                 .result(Color.RED).create();
-        final String results = serializer.serializeResponseAsString(toSerialize);
+        final String results = serializer.serializeResponseAsString(toSerialize, allocator);
         final JsonNode json = mapper.readTree(results);
         assertNotNull(json);
         assertThat(json.get(SerTokens.TOKEN_RESULT).get(SerTokens.TOKEN_DATA).booleanValue(), is(true));
@@ -113,7 +113,7 @@
     @Test
     public void shouldSerializeToJsonNullResultReturnsNull() throws Exception {
         final ResponseMessage message = ResponseMessage.build(msg).create();
-        final String results = SERIALIZER.serializeResponseAsString(message);
+        final String results = SERIALIZER.serializeResponseAsString(message, allocator);
         final JsonNode json = mapper.readTree(results);
         assertNotNull(json);
         assertEquals(msg.getRequestId().toString(), json.path(SerTokens.TOKEN_REQUEST).asText());
@@ -126,7 +126,7 @@
         funList.add(new FunObject("x"));
         funList.add(new FunObject("y"));
 
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(funList).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(funList).create(), allocator);
         final JsonNode json = mapper.readTree(results);
 
         assertNotNull(json);
@@ -145,7 +145,7 @@
         funList.add(new FunObject("x"));
         funList.add(new FunObject("y"));
 
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(funList).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(funList).create(), allocator);
         final JsonNode json = mapper.readTree(results);
 
         assertNotNull(json);
@@ -166,7 +166,7 @@
         funList.add(null);
         funList.add(new FunObject("y"));
 
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(funList.iterator()).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(funList.iterator()).create(), allocator);
         final JsonNode json = mapper.readTree(results);
 
         assertNotNull(json);
@@ -190,7 +190,7 @@
         map.put("y", "some");
         map.put("z", innerMap);
 
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(map).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(map).create(), allocator);
         final JsonNode json = mapper.readTree(results);
 
         assertNotNull(json);
@@ -217,7 +217,7 @@
         map.put(v1, 100);
         map.put(d, "test");
 
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(IteratorUtils.asList(map)).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(IteratorUtils.asList(map)).create(), allocator);
         final JsonNode json = mapper.readTree(results);
 
         assertNotNull(json);
@@ -244,7 +244,7 @@
         e.property("abc", 123);
 
         final Iterable<Edge> iterable = IteratorUtils.list(g.edges());
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(iterable).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(iterable).create(), allocator);
 
         final JsonNode json = mapper.readTree(results);
 
@@ -277,7 +277,7 @@
         e.property("abc", 123);
 
         final Iterable<Property<Object>> iterable = IteratorUtils.list(e.properties("abc"));
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(iterable).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(iterable).create(), allocator);
 
         final JsonNode json = mapper.readTree(results);
 
@@ -310,7 +310,7 @@
         v.property(VertexProperty.Cardinality.single, "friends", friends);
 
         final Iterable iterable = IteratorUtils.list(g.vertices());
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(iterable).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(iterable).create(), allocator);
         final JsonNode json = mapper.readTree(results);
 
         assertNotNull(json);
@@ -351,7 +351,7 @@
         final Map<Vertex, Integer> map = new HashMap<>();
         map.put(g.V().has("name", "marko").next(), 1000);
 
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(map).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(map).create(), allocator);
         final JsonNode json = mapper.readTree(results);
 
         assertNotNull(json);
@@ -410,7 +410,7 @@
                 .statusMessage("worked")
                 .create();
 
-        final String results = SERIALIZER.serializeResponseAsString(response);
+        final String results = SERIALIZER.serializeResponseAsString(response, allocator);
         final ResponseMessage deserialized = SERIALIZER.deserializeResponse(results);
 
         assertEquals(id, deserialized.getRequestId());
@@ -429,7 +429,7 @@
         final GraphTraversalSource g = graph.traversal();
         final Tree t = g.V(1).out().properties("name").tree().next();
 
-        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(t).create());
+        final String results = SERIALIZER.serializeResponseAsString(ResponseMessage.build(msg).result(t).create(), allocator);
 
         final JsonNode json = mapper.readTree(results);
 
diff --git a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/GraphBinaryMessageSerializerV1Test.java b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/GraphBinaryMessageSerializerV1Test.java
index 8813491..c4b486f 100644
--- a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/GraphBinaryMessageSerializerV1Test.java
+++ b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/GraphBinaryMessageSerializerV1Test.java
@@ -175,6 +175,43 @@
         assertEquals(java.awt.Color.RED.toString(), deserialized.getResult().getData());
     }
 
+    @Test
+    public void shouldToStringSerializeAsText() throws SerializationException {
+        final GraphBinaryMessageSerializerV1 serializer = new GraphBinaryMessageSerializerV1();
+        final Map<String,Object> conf = new HashMap<String,Object>() {{
+            put(GraphBinaryMessageSerializerV1.TOKEN_SERIALIZE_RESULT_TO_STRING, true);
+        }};
+        serializer.configure(conf, Collections.emptyMap());
+
+        final ResponseMessage messageWithUnexpectedType = ResponseMessage.build(UUID.randomUUID()).
+                result(java.awt.Color.RED).create();
+        final String base64 = serializer.serializeResponseAsString(messageWithUnexpectedType, allocator);
+        final ResponseMessage deserialized = serializer.deserializeResponse(base64);
+
+        assertEquals(java.awt.Color.RED.toString(), deserialized.getResult().getData());
+    }
+
+    @Test
+    public void shouldSerializeAndDeserializeRequestAsText() throws SerializationException {
+        final GraphBinaryMessageSerializerV1 serializer = new GraphBinaryMessageSerializerV1();
+        final Map<String,Object> conf = new HashMap<String,Object>() {{
+            put(GraphBinaryMessageSerializerV1.TOKEN_SERIALIZE_RESULT_TO_STRING, true);
+        }};
+        serializer.configure(conf, Collections.emptyMap());
+
+        final RequestMessage request = RequestMessage.build("op1")
+                .processor("proc1")
+                .overrideRequestId(UUID.randomUUID())
+                .addArg("arg1", "value1")
+                .create();
+
+        final ByteBuf buffer = serializer.serializeRequestAsBinary(request, allocator);
+        final int mimeLen = buffer.readByte();
+        buffer.readBytes(new byte[mimeLen]);
+        final RequestMessage deserialized = serializer.deserializeRequest(buffer);
+        assertThat(request, reflectionEquals(deserialized));
+    }
+
     private static void assertResponseEquals(ResponseMessage expected, ResponseMessage actual) {
         assertEquals(expected.getRequestId(), actual.getRequestId());
         // Status