public BlobReader Skip()
        {
            var reader = _reader;
            while (reader.IsCustomModifier())
                reader = new CustomModifierSignature(reader).Skip();

            switch (reader.PeekSignatureTypeCode())
            {
            case SignatureTypeCode.ByReference:
                reader.ReadSignatureTypeCode();
                goto default;

            case SignatureTypeCode.TypedReference:
            case SignatureTypeCode.Void:
                reader.ReadSignatureTypeCode();
                break;

            default:
                reader = new TypeSignature(reader).Skip();
                break;
            }

            return reader;
        }
        public BlobReader Skip()
        {
            BlobReader reader = _reader;
            reader.ReadSignatureHeader();

            int parameterCount = reader.ReadCompressedInteger();

            while (reader.IsCustomModifier())
                reader = new CustomModifierSignature(reader).Skip();

            reader = new TypeSignature(reader).Skip();

            for (int i = 0; i < parameterCount; i++)
                reader = new ParameterSignature(reader).Skip();

            return reader;
        }
        private bool IsSameTypeSignature(MetadataReader referenceMetadata, MetadataReader newMetadata, TypeSignature referenceSignature, TypeSignature newSignature)
        {
            if (referenceSignature.TypeCode != newSignature.TypeCode)
                return false;

            switch (referenceSignature.TypeCode)
            {
            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.IntPtr:
            case SignatureTypeCode.UIntPtr:
            case SignatureTypeCode.Single:
            case SignatureTypeCode.Double:
                return true;

            case SignatureTypeCode.Object:
            case SignatureTypeCode.String:
                return true;

            case SignatureTypeCode.Array:
                throw new NotImplementedException(string.Format("{0} is not yet implemented.", referenceSignature.TypeCode));

            case SignatureTypeCode.FunctionPointer:
                throw new NotImplementedException(string.Format("{0} is not yet implemented.", referenceSignature.TypeCode));

            case SignatureTypeCode.GenericTypeInstance:
                if (!IsSameType(referenceMetadata, newMetadata, referenceSignature.TypeHandle, newSignature.TypeHandle))
                    return false;

                ImmutableArray<TypeSignature> referenceGenericArguments = referenceSignature.GenericTypeArguments;
                ImmutableArray<TypeSignature> newGenericArguments = newSignature.GenericTypeArguments;
                if (referenceGenericArguments.Length != newGenericArguments.Length)
                    return false;

                for (int i = 0; i < referenceGenericArguments.Length; i++)
                {
                    if (!IsSameTypeSignature(referenceMetadata, newMetadata, referenceGenericArguments[i], newGenericArguments[i]))
                        return false;
                }

                return true;

            case SignatureTypeCode.GenericMethodParameter:
            case SignatureTypeCode.GenericTypeParameter:
                return referenceSignature.GenericParameterIndex == newSignature.GenericParameterIndex;

            case SignatureTypeCode.TypeHandle:
                Handle referenceTypeHandle = referenceSignature.TypeHandle;
                Handle newTypeHandle = newSignature.TypeHandle;
                return IsSameType(referenceMetadata, newMetadata, referenceTypeHandle, newTypeHandle);

            case SignatureTypeCode.Pointer:
                throw new NotImplementedException(string.Format("{0} is not yet implemented.", referenceSignature.TypeCode));

            case SignatureTypeCode.SZArray:
                if (!referenceSignature.CustomModifiers.IsEmpty || !newSignature.CustomModifiers.IsEmpty)
                    throw new NotImplementedException();

                return IsSameTypeSignature(referenceMetadata, newMetadata, referenceSignature.ElementType, newSignature.ElementType);

            default:
                throw new InvalidOperationException("Invalid signature type code.");
            }
        }
        private string CompareTypeSignatures(TypeSignature sourceSignature, TypeSignature targetSignature)
        {
            if (sourceSignature.TypeCode != targetSignature.TypeCode)
                return "Type mismatch";

            switch (sourceSignature.TypeCode)
            {
            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.IntPtr:
            case SignatureTypeCode.UIntPtr:
            case SignatureTypeCode.Single:
            case SignatureTypeCode.Double:
                return null;

            case SignatureTypeCode.Object:
            case SignatureTypeCode.String:
                return null;

            case SignatureTypeCode.Array:
                throw new NotImplementedException(string.Format("{0} is not yet implemented.", sourceSignature.TypeCode));

            case SignatureTypeCode.FunctionPointer:
                throw new NotImplementedException(string.Format("{0} is not yet implemented.", sourceSignature.TypeCode));

            case SignatureTypeCode.GenericTypeInstance:
                if (!IsSameHandle(sourceSignature.TypeHandle, targetSignature.TypeHandle))
                    return "Unbound generic type does not match.";

                ImmutableArray<TypeSignature> sourceGenericArguments = sourceSignature.GenericTypeArguments;
                ImmutableArray<TypeSignature> targetGenericArguments = targetSignature.GenericTypeArguments;
                if (sourceGenericArguments.Length != targetGenericArguments.Length)
                    return "Generic arity does not match.";

                for (int i = 0; i < sourceGenericArguments.Length; i++)
                {
                    string genericParameterResult = CompareTypeSignatures(sourceGenericArguments[i], targetGenericArguments[i]);
                    if (genericParameterResult != null)
                        return string.Format("Generic parameter {0} does not match: {1}", i, genericParameterResult);
                }

                return null;

            case SignatureTypeCode.GenericMethodParameter:
            case SignatureTypeCode.GenericTypeParameter:
                if (sourceSignature.GenericParameterIndex != targetSignature.GenericParameterIndex)
                    return "Generic parameter index differs.";

                return null;

            case SignatureTypeCode.TypeHandle:
                throw new NotImplementedException(string.Format("{0} is not yet implemented.", sourceSignature.TypeCode));
                //Handle referenceTypeHandle = sourceSignature.TypeHandle;
                //Handle newTypeHandle = targetSignature.TypeHandle;
                //return IsSameType(referenceMetadata, newMetadata, referenceTypeHandle, newTypeHandle);

            case SignatureTypeCode.Pointer:
                throw new NotImplementedException(string.Format("{0} is not yet implemented.", sourceSignature.TypeCode));

            case SignatureTypeCode.SZArray:
                if (!sourceSignature.CustomModifiers.IsEmpty || !targetSignature.CustomModifiers.IsEmpty)
                    throw new NotImplementedException();

                string szArrayResult = CompareTypeSignatures(sourceSignature.ElementType, targetSignature.ElementType);
                if (szArrayResult != null)
                    szArrayResult = string.Format("SZArray element type mismatch: {0}", szArrayResult);

                return szArrayResult;

            default:
                throw new InvalidOperationException("Invalid signature type code.");
            }
        }
        public BlobReader Skip()
        {
            BlobReader reader = _reader;
            SignatureTypeCode typeCode = reader.ReadSignatureTypeCode();

            switch (typeCode)
            {
            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.IntPtr:
            case SignatureTypeCode.UIntPtr:
            case SignatureTypeCode.Single:
            case SignatureTypeCode.Double:
                break;

            case SignatureTypeCode.Object:
            case SignatureTypeCode.String:
                break;

            case SignatureTypeCode.Array:
                reader = new TypeSignature(reader).Skip();
                reader = new ArrayShapeSignature(reader).Skip();
                break;

            case SignatureTypeCode.FunctionPointer:
                throw new NotImplementedException(string.Format("{0} is not yet implemented.", typeCode));

            case SignatureTypeCode.GenericTypeInstance:
                reader.ReadSignatureTypeCode();
                reader.ReadTypeHandle();

                int argumentCount = reader.ReadCompressedInteger();
                for (int i = 0; i < argumentCount; i++)
                    reader = new TypeSignature(reader).Skip();

                break;

            case SignatureTypeCode.GenericMethodParameter:
            case SignatureTypeCode.GenericTypeParameter:
                // skip the generic parameter index
                reader.ReadCompressedInteger();
                break;

            case SignatureTypeCode.TypeHandle:
                reader.ReadTypeHandle();
                break;

            case SignatureTypeCode.Pointer:
                while (reader.IsCustomModifier())
                    reader = new CustomModifierSignature(reader).Skip();

                if (reader.PeekSignatureTypeCode() == SignatureTypeCode.Void)
                    reader.ReadSignatureTypeCode();
                else
                    reader = new TypeSignature(reader).Skip();

                break;

            case SignatureTypeCode.SZArray:
                while (reader.IsCustomModifier())
                    reader = new CustomModifierSignature(reader).Skip();

                reader = new TypeSignature(reader).Skip();
                break;

            default:
                throw new InvalidOperationException("Invalid signature type code.");
            }

            return reader;
        }