public object ReadThing(VoxBinaryReader thingReader, Type hintType)
        {
            var type = typeReader.ReadType(thingReader);

            // special cases for type deserialization
            if (type == typeof(TBoolTrue) || type == typeof(TBoolFalse) || type == typeof(TNull))
            {
                // fall straight to reader, ignoring hintType
                return(thingReaderWriterContainer.Get(type).ReadBody(thingReader));
            }
            else if (type == typeof(Type))
            {
                Trace.Assert(hintType == null || typeof(Type).IsAssignableFrom(hintType));
                return(thingReaderWriterContainer.Get(type).ReadBody(thingReader));
            }
            else if (integerTypes.Contains(type))
            {
                var value = thingReaderWriterContainer.Get(type).ReadBody(thingReader);
                if (hintType == null)
                {
                    return(value);
                }
                else if (hintType.IsEnum)
                {
                    return(Convert.ChangeType(value, Enum.GetUnderlyingType(hintType)));
                }
                else
                {
                    return(Convert.ChangeType(value, hintType));
                }
            }

            if (hintType != null)
            {
                var simplifiedType = TypeSimplifier.SimplifyType(hintType);

                if (type == simplifiedType)
                {
                    type = hintType;
                }
                else if (!hintType.IsAssignableFrom(type))
                {
                    logger.Error($"Unable to convert from {type.FullName} to hinted {hintType.FullName}.");
                    throw new InvalidStateException();
                }
            }
            return(thingReaderWriterContainer.Get(type).ReadBody(thingReader));
        }
 public object ReadBody(VoxBinaryReader reader)
 {
     return(typeReader.ReadType(reader));
 }