public T GetSignature <T>(SignatureKinds signatureKind, uint heapIndex)
            where T :
        ICliMetadataSignature
        {
            if (heapIndex >= this.Size)
            {
                throw new ArgumentOutOfRangeException("heapIndex");
            }
            SmallBlobEntry  smallResult;
            MediumBlobEntry mediumResult;
            LargeBlobEntry  largeResult;

            lock (this.syncObject)
            {
                if (smallEntries.TryGetValue(heapIndex, out smallResult))
                {
                    if (smallResult.Signature == null)
                    {
                        LoadSignatureGeneral(signatureKind, heapIndex, smallResult);
                    }
                    return((T)smallResult.Signature);
                }
                else if (mediumEntries.TryGetValue(heapIndex, out mediumResult))
                {
                    if (mediumResult.Signature == null)
                    {
                        LoadSignatureGeneral(signatureKind, heapIndex, mediumResult);
                    }
                    return((T)mediumResult.Signature);
                }
                else if (!largEntries.TryGetValue(heapIndex, out largeResult))
                {
                    throw new IndexOutOfRangeException("heapIndex");
                }
                else
                {
                    if (largeResult.Signature == null)
                    {
                        LoadSignatureGeneral(signatureKind, heapIndex, largeResult);
                    }
                    return((T)largeResult.Signature);
                }
            }
            throw new ArgumentOutOfRangeException("heapIndex");
        }
        private void LoadSignatureGeneral(SignatureKinds signatureKind, uint heapIndex, _ICliMetadataBlobEntry entry)
        {
            lock (this.syncObject)
            {
                uint offset = heapIndex + entry.LengthByteCount;

                this.reader.BaseStream.Seek(offset, SeekOrigin.Begin);
                switch (signatureKind)
                {
                case SignatureKinds.MethodDefSig:
                    entry.Signature = SignatureParser.ParseMethodDefSig(this.reader, metadataRoot);
                    break;

                case SignatureKinds.MethodRefSig:
                    entry.Signature = SignatureParser.ParseMethodRefSig(this.reader, metadataRoot);
                    break;

                case SignatureKinds.FieldSig:
                    entry.Signature = SignatureParser.ParseFieldSig(this.reader, metadataRoot);
                    break;

                case SignatureKinds.PropertySig:
                    entry.Signature = SignatureParser.ParsePropertySig(this.reader, metadataRoot);
                    break;

                case SignatureKinds.StandaloneSignature:
                    entry.Signature = SignatureParser.ParseStandaloneSig(this.reader, metadataRoot);
                    break;

                case SignatureKinds.CustomModifier:
                    entry.Signature = SignatureParser.ParseCustomModifier(this.reader, metadataRoot);
                    break;

                case SignatureKinds.Param:
                    entry.Signature = SignatureParser.ParseParam(this.reader, metadataRoot);
                    break;

                case SignatureKinds.Type:
                    entry.Signature = SignatureParser.ParseType(this.reader, metadataRoot);
                    break;

                case SignatureKinds.ArrayShape:
                    entry.Signature = SignatureParser.ParseArrayShape(this.reader, metadataRoot);
                    break;

                case SignatureKinds.TypeSpec:
                    entry.Signature = SignatureParser.ParseTypeSpec(this.reader, metadataRoot);
                    break;

                case SignatureKinds.MethodSpec:
                    entry.Signature = SignatureParser.ParseMethodSpec(this.reader, metadataRoot);
                    break;

                case SignatureKinds.MemberRefSig:
                    entry.Signature = SignatureParser.ParseMemberRefSig(this.reader, metadataRoot);
                    break;

                default:
                    throw new ArgumentOutOfRangeException("signatureKind");
                }
            }
        }