/// <inheritdoc/>
        public T FromProtobuf <T>(Stream stream, bool includesLength = false)
        {
            var instance = (T)Activator.CreateInstance(typeof(T));

            using (var inputStream = new CodedInputStream(stream))
            {
                var messageDescription = _messageDescriptions.GetFor <T>();

                var tag = inputStream.ReadTag();
                while (!inputStream.IsAtEnd)
                {
                    var fieldNumber         = WireFormat.GetTagFieldNumber(tag);
                    var propertyDescription = messageDescription.Properties.SingleOrDefault(_ => _.Number == fieldNumber);
                    if (propertyDescription != null)
                    {
                        object value = null;
                        var    type  = propertyDescription.Property.PropertyType;

                        IValueConverter converter = null;

                        var targetType = type;

                        if (_valueConverters.CanConvert(type))
                        {
                            converter  = _valueConverters.GetConverterFor(type);
                            targetType = type;
                            type       = converter.SerializedAs(type);
                        }

                        value = ReadValue(inputStream, value, type, targetType, converter);
                        propertyDescription.Property.SetValue(instance, value);
                    }

                    tag = inputStream.ReadTag();
                }
            }

            return(instance);
        }