diff --git a/docs/source/release-notes.rst b/docs/source/release-notes.rst
index 14d9a494cc..79263cfd6e 100644
--- a/docs/source/release-notes.rst
+++ b/docs/source/release-notes.rst
@@ -6,6 +6,11 @@ Here are release notes for each snapshot release from M9 onwards.
 Unreleased
 ----------
 
+** Enum Class Evolution
+   With the addition of AMQP serialization Corda now supports enum constant evolution, that is the abilit to alter
+   an enum constant and, as long as certain rules ar followed and the correct annotations applied, have older and
+   newer instances of that enumeration be understood.
+
 Release 2.0
 ----------
 Following quickly on the heels of the release of Corda 1.0, Corda version 2.0 consolidates
diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumEvolutionSerializer.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumEvolutionSerializer.kt
index f8579fc21e..221954371b 100644
--- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumEvolutionSerializer.kt
+++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumEvolutionSerializer.kt
@@ -7,7 +7,12 @@ import java.lang.reflect.Type
 import java.util.*
 
 /**
- * @property transforms
+ * @property clazz The enum as it exists now, not as it did when it was seialised (either in the past
+ * or future).
+ * @property factory the [SerializerFactory] that is building this serialization object.
+ * @property conversions A mapping between all potential enum constants that could've been assigned as
+ * existed at serialisation and those that exist now
+ * @property ordinals Convenience mapping of constant to ordinality
  *
  */
 class EnumEvolutionSerializer(
@@ -19,7 +24,7 @@ class EnumEvolutionSerializer(
     override val typeDescriptor = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${fingerprintForType(type, factory)}")!!
 
     companion object {
-        fun MutableMap<String, String>.mapInPlace(f : (String)->String) {
+        private fun MutableMap<String, String>.mapInPlace(f : (String)->String) {
             val i = this.iterator()
             while(i.hasNext()) {
                 val curr = (i.next())
@@ -28,8 +33,14 @@ class EnumEvolutionSerializer(
         }
 
         /**
-         * @param old
-         * @param new
+         * Builds an Enum Evolver serializer.
+         *
+         * @param old The description of the enum as it existed at the time of serialisation take from the
+         * received AMQP header
+         * @param new The Serializer object we built based on the current state of the enum class on our classpath
+         * @param factory the [SerializerFactory] that is building this serialization object.
+         * @param transformsFromBlob the transforms attached to the class in the AMQP header, i.e. the transforms
+         * known at serialization time
          */
         fun make(old: RestrictedType,
                  new: AMQPSerializer<Any>,
@@ -48,9 +59,9 @@ class EnumEvolutionSerializer(
             val renameRules = transforms[TransformTypes.Rename] as? List<RenameSchemaTransform>
 
             // What values exist on the enum as it exists on the class path
-            val localVals = new.type.asClass()!!.enumConstants.map { it.toString() }
+            val localValues = new.type.asClass()!!.enumConstants.map { it.toString() }
 
-            var conversions : MutableMap<String, String> = new.type.asClass()!!.enumConstants.map { it.toString() }
+            val conversions : MutableMap<String, String> = new.type.asClass()!!.enumConstants.map { it.toString() }
                     .union(defaultRules?.map { it.new }?.toSet() ?: emptySet())
                     .union(renameRules?.map { it.to } ?: emptySet())
                     .associateBy({ it }, { it })
@@ -60,17 +71,20 @@ class EnumEvolutionSerializer(
             rules.putAll(defaultRules?.associateBy({ it.new }, { it.old }) ?: emptyMap())
             rules.putAll(renameRules?.associateBy({ it.to }, { it.from }) ?: emptyMap())
 
-            while (conversions.filter { it.value !in localVals }.isNotEmpty()) {
+            while (conversions.filter { it.value !in localValues }.isNotEmpty()) {
                 conversions.mapInPlace { rules[it] ?: it }
             }
 
+            // you'd think this was overkill to get access to the ordinal values for each constant but it's actually
+            // rather tricky when you don't have access to the actual type, so this is a nice way to be able
+            // to precompute and pass to the actual object
             var idx = 0
-            return EnumEvolutionSerializer(new.type, factory, conversions, localVals.associateBy( {it}, { idx++ }))
+            return EnumEvolutionSerializer(new.type, factory, conversions, localValues.associateBy( {it}, { idx++ }))
         }
     }
 
     override fun readObject(obj: Any, schemas: SerializationSchemas, input: DeserializationInput): Any {
-        var enumName = (obj as List<*>)[0] as String
+        val enumName = (obj as List<*>)[0] as String
 
         if (enumName !in conversions) {
             throw NotSerializableException ("No rule to evolve enum constant $type::$enumName")