public unsafe static void Convert(BlobBuilder builder, MetadataModel metadataModel, byte[] signature, object value)
        {
            fixed(byte *sigPtr = signature)
            {
                var sigReader = new BlobReader(sigPtr, signature.Length);

                // copy custom modifiers over:
                byte rawTypeCode;

                while (true)
                {
                    rawTypeCode = sigReader.ReadByte();
                    if (rawTypeCode != (int)SignatureTypeCode.OptionalModifier && rawTypeCode != (int)SignatureTypeCode.RequiredModifier)
                    {
                        break;
                    }

                    builder.WriteByte(rawTypeCode);
                    builder.WriteCompressedInteger(sigReader.ReadCompressedInteger());
                }

                switch ((SignatureTypeCode)rawTypeCode)
                {
                case (SignatureTypeCode)SignatureTypeKind.Class:
                case (SignatureTypeCode)SignatureTypeKind.ValueType:
                    int typeRefDefSpec = sigReader.ReadCompressedInteger();

                    if (value is decimal)
                    {
                        // GeneralConstant: VALUETYPE TypeDefOrRefOrSpecEncoded <decimal>
                        builder.WriteByte((byte)SignatureTypeKind.ValueType);
                        builder.WriteCompressedInteger(typeRefDefSpec);
                        builder.WriteDecimal((decimal)value);
                    }
                    else if (value is DateTime)
                    {
                        // GeneralConstant: VALUETYPE TypeDefOrRefOrSpecEncoded <date-time>
                        builder.WriteByte((byte)SignatureTypeKind.ValueType);
                        builder.WriteCompressedInteger(typeRefDefSpec);
                        builder.WriteDateTime((DateTime)value);
                    }
                    else if (value == null)
                    {
                        // GeneralConstant: CLASS TypeDefOrRefOrSpecEncoded
                        builder.WriteByte(rawTypeCode);
                        builder.WriteCompressedInteger(typeRefDefSpec);
                    }
                    else
                    {
                        // EnumConstant ::= EnumTypeCode EnumValue EnumType
                        // EnumTypeCode ::= BOOLEAN | CHAR | I1 | U1 | I2 | U2 | I4 | U4 | I8 | U8
                        // EnumType     ::= TypeDefOrRefOrSpecEncoded

                        var enumTypeCode = MetadataHelpers.GetConstantTypeCode(value);
                        builder.WriteByte((byte)enumTypeCode);
                        builder.WriteConstant(value);
                        builder.WriteCompressedInteger(typeRefDefSpec);
                    }

                    break;

                case SignatureTypeCode.Object:
                    // null:
                    Debug.Assert(value == null);
                    builder.WriteByte((byte)SignatureTypeCode.Object);
                    break;

                case SignatureTypeCode.Boolean:
                case SignatureTypeCode.Char:
                case SignatureTypeCode.SByte:
                case SignatureTypeCode.Byte:
                case SignatureTypeCode.Int16:
                case SignatureTypeCode.UInt16:
                case SignatureTypeCode.Int32:
                case SignatureTypeCode.UInt32:
                case SignatureTypeCode.Int64:
                case SignatureTypeCode.UInt64:
                case SignatureTypeCode.Single:
                case SignatureTypeCode.Double:
                case SignatureTypeCode.String:
                    // PrimitiveConstant
                    builder.WriteByte(rawTypeCode);
                    builder.WriteConstant(value);
                    break;

                case SignatureTypeCode.SZArray:
                case SignatureTypeCode.Array:
                case SignatureTypeCode.GenericTypeInstance:
                    Debug.Assert(value == null);

                    // Find an existing TypeSpec in metadata.
                    // If there isn't one we can't represent the constant type in the Portable PDB, use Object.

                    // +1/-1 for the type code we already read.
                    var spec = new byte[sigReader.RemainingBytes + 1];
                    Buffer.BlockCopy(signature, sigReader.Offset - 1, spec, 0, spec.Length);

                    TypeSpecificationHandle typeSpec;
                    if (metadataModel.TryResolveTypeSpecification(spec, out typeSpec))
                    {
                        builder.WriteCompressedInteger(CodedIndex.TypeDefOrRefOrSpec(typeSpec));
                    }
                    else
                    {
                        // TODO: warning - can't translate const type
                        builder.WriteByte((byte)SignatureTypeCode.Object);
                    }

                    break;

                case SignatureTypeCode.GenericMethodParameter:
                case SignatureTypeCode.GenericTypeParameter:
                case SignatureTypeCode.FunctionPointer:
                case SignatureTypeCode.Pointer:
                    // generic parameters, pointers are not valid types for constants:
                    throw new BadImageFormatException();
                }
            }
        }