Add back serializer for TraversalMetrics.

TraversalMetrics should serialize to String because profile() should be
flexible enough that a provider can return a custom String.
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/TypeSerializerRegistry.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/TypeSerializerRegistry.java
index a5b9f79..8190009 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/TypeSerializerRegistry.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/TypeSerializerRegistry.java
@@ -23,6 +23,7 @@
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
 import org.apache.tinkerpop.gremlin.structure.Direction;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Graph;
@@ -52,6 +53,7 @@
 import org.apache.tinkerpop.gremlin.structure.io.binary.types.StringSerializer;
 import org.apache.tinkerpop.gremlin.structure.io.binary.types.TransformSerializer;
 import org.apache.tinkerpop.gremlin.structure.io.binary.types.TraversalExplanationSerializer;
+import org.apache.tinkerpop.gremlin.structure.io.binary.types.TraversalMetricsSerializer;
 import org.apache.tinkerpop.gremlin.structure.io.binary.types.TreeSerializer;
 import org.apache.tinkerpop.gremlin.structure.io.binary.types.UUIDSerializer;
 import org.apache.tinkerpop.gremlin.structure.io.binary.types.VertexPropertySerializer;
@@ -87,6 +89,7 @@
     private static final RegistryEntry[] defaultEntries = new RegistryEntry[] {
             new RegistryEntry<>(Integer.class, SingleTypeSerializer.IntSerializer),
             new RegistryEntry<>(Long.class, SingleTypeSerializer.LongSerializer),
+            new RegistryEntry<>(TraversalMetrics.class, new TraversalMetricsSerializer()), // needs to register before String so StringSerializer is mapped to STRING datatype
             new RegistryEntry<>(String.class, new StringSerializer()),
             new RegistryEntry<>(Double.class, SingleTypeSerializer.DoubleSerializer),
             new RegistryEntry<>(Float.class, SingleTypeSerializer.FloatSerializer),
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/types/TraversalMetricsSerializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/types/TraversalMetricsSerializer.java
new file mode 100644
index 0000000..eb4eb0e8
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/types/TraversalMetricsSerializer.java
@@ -0,0 +1,50 @@
+/*
+ * 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.structure.io.binary.types;
+
+import org.apache.tinkerpop.gremlin.structure.io.binary.DataType;
+import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader;
+import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter;
+import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalMetrics;
+import org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
+import org.apache.tinkerpop.gremlin.structure.io.Buffer;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+public class TraversalMetricsSerializer extends SimpleTypeSerializer<TraversalMetrics> {
+    private static final StringSerializer stringSerializer = new StringSerializer();
+
+    public TraversalMetricsSerializer() {
+        super(DataType.STRING); // TraversalMetrics serializes into a String.
+    }
+
+    @Override
+    protected TraversalMetrics readValue(Buffer buffer, GraphBinaryReader context) throws IOException {
+        throw new UnsupportedOperationException("TraversalMetrics deserialization is not supported");
+    }
+
+    @Override
+    protected void writeValue(TraversalMetrics value, Buffer buffer, GraphBinaryWriter context) throws IOException {
+        stringSerializer.writeValue(value.toString(), buffer, context);
+    }
+}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
index c18f3b0..127f347 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
@@ -182,6 +182,7 @@
             addSerializer(Vertex.class, new GraphSONSerializersV4.VertexJacksonSerializer(normalize, typeInfo));
             addSerializer(VertexProperty.class, new GraphSONSerializersV4.VertexPropertyJacksonSerializer(normalize, true));
             addSerializer(Property.class, new GraphSONSerializersV4.PropertyJacksonSerializer());
+            addSerializer(TraversalMetrics.class, new GraphSONSerializersV4.TraversalMetricsJacksonSerializer());
             addSerializer(Path.class, new GraphSONSerializersV4.PathJacksonSerializer());
             addSerializer(DirectionalStarGraph.class, new StarGraphGraphSONSerializerV4(normalize));
             addSerializer(Tree.class, new GraphSONSerializersV4.TreeJacksonSerializer());
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV4.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV4.java
index f462579..34bb32a 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV4.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV4.java
@@ -350,6 +350,26 @@
         }
     }
 
+    final static class TraversalMetricsJacksonSerializer extends StdScalarSerializer<TraversalMetrics> {
+        public TraversalMetricsJacksonSerializer() {
+            super(TraversalMetrics.class);
+        }
+
+        @Override
+        public void serialize(final TraversalMetrics traversalMetrics, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeString(traversalMetrics.toString());
+        }
+
+        @Override
+        public void serializeWithType(final TraversalMetrics traversalMetrics, final JsonGenerator jsonGenerator,
+                                      final SerializerProvider serializerProvider, final TypeSerializer typeSerializer)
+                throws IOException {
+            // Don't include type information as it should be a plain string.
+            jsonGenerator.writeString(traversalMetrics.toString());
+        }
+    }
+
     /**
      * Maps in the JVM can have {@link Object} as a key, but in JSON they must be a {@link String}.
      */
diff --git a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/AbstractRoundTripTest.java b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/AbstractRoundTripTest.java
index cfa1009..55fce50 100644
--- a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/AbstractRoundTripTest.java
+++ b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/AbstractRoundTripTest.java
@@ -23,6 +23,7 @@
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
 import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalMetrics;
 import org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
 import org.apache.tinkerpop.gremlin.structure.Direction;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.T;
@@ -181,6 +182,12 @@
                     assertEquals(bulkSetExpanded, bulklist);
                 }},
                 new Object[] {"Tree", tree, null},
+                new Object[] {"EmptyTraversalMetrics", emptyTraversalMetrics, (Consumer<String>) m -> {
+                    assertEquals(m, emptyTraversalMetrics.toString());
+                }},
+                new Object[] {"TraversalMetrics", traversalMetrics, (Consumer<String>) m -> {
+                    assertEquals(m, traversalMetrics.toString());
+                }},
 
                 // collections
                 new Object[] {"ListSingle", list, null},