/// <summary>
        /// Reads the JSON representation of a <see cref="CommandEnvelope"/> instance.
        /// </summary>
        /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
        /// <param name="objectType">The type of object.</param>
        /// <param name="existingValue">The existing value of the object being read.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override Object ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
        {
            if (!reader.CanReadObject())
                return null;

            var aggregateId = Guid.Empty;
            var command = default(Command);
            while (reader.Read() && reader.TokenType != JsonToken.EndObject)
            {
                String propertyName;
                if (!reader.TryGetProperty(out propertyName))
                    continue;

                switch (propertyName)
                {
                    case "a":
                        aggregateId = serializer.Deserialize<Guid>(reader);
                        break;
                    case "c":
                        command = serializer.Deserialize<Command>(reader);
                        break;
                }
            }

            return new CommandEnvelope(aggregateId, command);
        }
        /// <summary>
        /// Reads the JSON representation of a <see cref="EventCollection"/> instance.
        /// </summary>
        /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
        /// <param name="objectType">The type of object.</param>
        /// <param name="existingValue">The existing value of the object being read.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override Object ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
        {
            if (!reader.CanReadObject())
                return null;

            var id = Guid.Empty;
            var payload = default(Object);
            var headers = HeaderCollection.Empty;
            var payloadType = KnownPayloadTypes[objectType];
            while (reader.Read() && reader.TokenType != JsonToken.EndObject)
            {
                String propertyName;
                if (!reader.TryGetProperty(out propertyName))
                    continue;

                switch (propertyName)
                {
                    case "id":
                        id = serializer.Deserialize<Guid>(reader);
                        break;
                    case "h":
                        headers = serializer.Deserialize<HeaderCollection>(reader);
                        break;
                    case "p":
                        payload = serializer.Deserialize(reader, payloadType);
                        break;
                }
            }

            return Activator.CreateInstance(objectType, id, headers, payload);
        }
        /// <summary>
        /// Reads the JSON representation of an <see cref="EventVersion"/> instance.
        /// </summary>
        /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
        /// <param name="objectType">The type of object.</param>
        /// <param name="existingValue">The existing value of the object being read.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override Object ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
        {
            if (!reader.CanReadObject())
                return null;

            var item = 0;
            var count = 0;
            var version = 0;
            while (reader.Read() && reader.TokenType != JsonToken.EndObject)
            {
                String propertyName;
                if (!reader.TryGetProperty(out propertyName))
                    continue;

                switch (propertyName)
                {
                    case "v":
                        version = serializer.Deserialize<Int32>(reader);
                        break;
                    case "c":
                        count = serializer.Deserialize<Int32>(reader);
                        break;
                    case "i":
                        item = serializer.Deserialize<Int32>(reader);
                        break;
                }
            }

            return new EventVersion(version, count, item);
        }
        /// <summary>
        /// Reads the JSON representation of a <see cref="CommitData"/> instance.
        /// </summary>
        /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
        /// <param name="objectType">The type of object.</param>
        /// <param name="existingValue">The existing value of the object being read.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override Object ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
        {
            if (!reader.CanReadObject())
                return CommitData.Empty;

            var events = EventCollection.Empty;
            var headers = HeaderCollection.Empty;
            while (reader.Read() && reader.TokenType != JsonToken.EndObject)
            {
                String propertyName;
                if (!reader.TryGetProperty(out propertyName))
                    continue;

                switch (propertyName)
                {
                    case "h":
                        headers = serializer.Deserialize<HeaderCollection>(reader);
                        break;
                    case "e":
                        events = serializer.Deserialize<EventCollection>(reader);
                        break;
                }
            }

            return new CommitData(headers, events);
        }
        /// <summary>
        /// Reads the JSON representation of an <see cref="StateObject"/> instance.
        /// </summary>
        /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
        /// <param name="objectType">The type of object.</param>
        /// <param name="existingValue">The existing value of the object being read.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override Object ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
        {
            if (!reader.CanReadObject())
                return null;

            var stateObject = default(StateObject);
            var state = new Dictionary<String, Object>();
            while (reader.Read() && reader.TokenType != JsonToken.EndObject)
            {
                var propertyName = String.Empty;
                if (!reader.TryGetProperty(out propertyName))
                    continue;

                if (propertyName == TypePropertyName)
                {
                    objectType = Type.GetType(serializer.Deserialize<String>(reader), throwOnError: true, ignoreCase: true);
                    stateObject = (StateObject)FormatterServices.GetUninitializedObject(objectType);
                }
                else
                {
                    stateObject = stateObject ?? (StateObject)FormatterServices.GetUninitializedObject(objectType);
                    state.Add(propertyName, serializer.Deserialize(reader, stateObject.GetFieldType(propertyName)));
                }
            }

            stateObject?.SetState(state);

            return stateObject;
        }
        /// <summary>
        /// Reads the JSON representation of an <see cref="EventEnvelope"/> instance.
        /// </summary>
        /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
        /// <param name="objectType">The type of object.</param>
        /// <param name="existingValue">The existing value of the object being read.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override Object ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
        {
            if (!reader.CanReadObject())
                return null;

            var e = default(Event);
            var aggregateId = Guid.Empty;
            var correlationId = Guid.Empty;
            var version = EventVersion.Empty;
            while (reader.Read() && reader.TokenType != JsonToken.EndObject)
            {
                String propertyName;
                if (!reader.TryGetProperty(out propertyName))
                    continue;

                switch (propertyName)
                {
                    case "a":
                        aggregateId = serializer.Deserialize<Guid>(reader);
                        break;
                    case "v":
                        version = serializer.Deserialize<EventVersion>(reader);
                        break;
                    case "e":
                        e = serializer.Deserialize<Event>(reader);
                        break;
                    case "c":
                        correlationId = serializer.Deserialize<Guid>(reader);
                        break;
                }
            }

            return new EventEnvelope(correlationId, aggregateId, version, e);
        }
        /// <summary>
        /// Reads the JSON representation of a <see cref="HeaderCollection"/> instance.
        /// </summary>
        /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
        /// <param name="objectType">The type of object.</param>
        /// <param name="existingValue">The existing value of the object being read.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override Object ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
        {
            if (!reader.CanReadObject())
                return null;

            var dictionary = new Dictionary<String, String>();
            while (reader.Read() && reader.TokenType != JsonToken.EndObject)
            {
                String propertyName;
                if (!reader.TryGetProperty(out propertyName))
                    continue;

                dictionary.Add(propertyName, serializer.Deserialize<String>(reader));
            }

            return new HeaderCollection(dictionary);
        }
        /// <summary>
        /// Reads the JSON representation of a <see cref="ValueObject"/> instance.
        /// </summary>
        /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
        /// <param name="objectType">The type of object.</param>
        /// <param name="existingValue">The existing value of the object being read.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override Object ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
        {
            if (!reader.CanReadObject())
                return null;

            var genericTypes = GetGenericTypeArguments(objectType);
            var dictionary = (IDictionary)Activator.CreateInstance(objectType);
            while (reader.Read() && reader.TokenType != JsonToken.EndObject)
            {
                String propertyName;
                if (!reader.TryGetProperty(out propertyName))
                    continue;

                dictionary.Add(ValueObject.Parse(genericTypes.Key, propertyName), serializer.Deserialize(reader, genericTypes.Value));
            }

            return dictionary;
        }