private bool EqualsType(ITypeSignature x, ITypeSignature y, ICodeNode xGenericContext = null)
        {
            if (x == y)
            {
                return(true);
            }

            if (x == null || y == null)
            {
                return(false);
            }

            switch (x.ElementCode)
            {
            case TypeElementCode.Array:
            {
                if (y.ElementCode != TypeElementCode.Array)
                {
                    return(false);
                }

                if (!SignatureComparer.EqualsArrayDimensions(x.ArrayDimensions, y.ArrayDimensions))
                {
                    return(false);
                }

                if (!EqualsType(x.ElementType, y.ElementType, xGenericContext))
                {
                    return(false);
                }

                return(true);
            }

            case TypeElementCode.ByRef:
            {
                if (y.ElementCode != TypeElementCode.ByRef)
                {
                    return(false);
                }

                if (!EqualsType(x.ElementType, y.ElementType, xGenericContext))
                {
                    return(false);
                }

                return(true);
            }

            case TypeElementCode.CustomModifier:
            {
                if (y.ElementCode != TypeElementCode.CustomModifier)
                {
                    return(false);
                }

                CustomModifierType xModifierType;
                var xModifier = x.GetCustomModifier(out xModifierType);

                CustomModifierType yModifierType;
                var yModifier = y.GetCustomModifier(out yModifierType);

                if (xModifierType != yModifierType)
                {
                    return(false);
                }

                if (!EqualsType(x.ElementType, y.ElementType, xGenericContext))
                {
                    return(false);
                }

                if (!EqualsType(xModifier, yModifier))
                {
                    return(false);
                }

                return(true);
            }

            case TypeElementCode.FunctionPointer:
            {
                if (y.ElementCode != TypeElementCode.FunctionPointer)
                {
                    return(false);
                }

                if (!EqualsMethod(x.GetFunctionPointer(), y.GetFunctionPointer()))
                {
                    return(false);
                }

                return(true);
            }

            case TypeElementCode.GenericParameter:
            {
                bool xIsMethod;
                int  xPosition;
                x.GetGenericParameter(out xIsMethod, out xPosition);

                if (xGenericContext != null)
                {
                    var xGenericType = xGenericContext.GetGenericArgument(xIsMethod, xPosition);
                    if (xGenericType != null)
                    {
                        return(EqualsType(xGenericType, y));
                    }
                }

                if (y.ElementCode != TypeElementCode.GenericParameter)
                {
                    return(false);
                }

                bool yIsMethod;
                int  yPosition;
                y.GetGenericParameter(out yIsMethod, out yPosition);

                if (xIsMethod != yIsMethod)
                {
                    return(false);
                }

                if (xPosition != yPosition)
                {
                    return(false);
                }

                return(true);
            }

            case TypeElementCode.GenericType:
            {
                if (y.ElementCode != TypeElementCode.GenericType)
                {
                    return(false);
                }

                if (!EqualsType(x.DeclaringType, y.DeclaringType))
                {
                    return(false);
                }

                if (!EqualsTypes(x.GenericArguments, y.GenericArguments, xGenericContext))
                {
                    return(false);
                }

                return(true);
            }

            case TypeElementCode.Pinned:
            {
                if (y.ElementCode != TypeElementCode.Pinned)
                {
                    return(false);
                }

                if (!EqualsType(x.ElementType, y.ElementType, xGenericContext))
                {
                    return(false);
                }

                return(true);
            }

            case TypeElementCode.Pointer:
            {
                if (y.ElementCode != TypeElementCode.Pointer)
                {
                    return(false);
                }

                if (!EqualsType(x.ElementType, y.ElementType, xGenericContext))
                {
                    return(false);
                }

                return(true);
            }

            case TypeElementCode.DeclaringType:
            {
                if (x.Name != y.Name)
                {
                    return(false);
                }

                if (x.Namespace != y.Namespace)
                {
                    return(false);
                }

                if (!EqualsTypeOwner(x.Owner, y.Owner))
                {
                    return(false);
                }

                return(true);
            }

            default:
                throw new NotImplementedException();
            }
        }
            private bool Equals(IType x, IType y)
            {
                if (x == y)
                {
                    return(true);
                }

                if (x == null || y == null)
                {
                    return(false);
                }

                if (x.ElementCode != y.ElementCode)
                {
                    return(false);
                }

                switch (x.ElementCode)
                {
                case TypeElementCode.Array:
                {
                    if (!SignatureComparer.EqualsArrayDimensions(x.ArrayDimensions, y.ArrayDimensions))
                    {
                        return(false);
                    }

                    if (!object.ReferenceEquals(x.ElementType, y.ElementType))
                    {
                        return(false);
                    }

                    return(true);
                }

                case TypeElementCode.ByRef:
                {
                    if (!object.ReferenceEquals(x.ElementType, y.ElementType))
                    {
                        return(false);
                    }

                    return(true);
                }

                case TypeElementCode.CustomModifier:
                {
                    CustomModifierType xModifierType;
                    var xModifier = x.GetCustomModifier(out xModifierType);

                    CustomModifierType yModifierType;
                    var yModifier = y.GetCustomModifier(out yModifierType);

                    if (xModifierType != yModifierType)
                    {
                        return(false);
                    }

                    if (!object.ReferenceEquals(x.ElementType, y.ElementType))
                    {
                        return(false);
                    }

                    if (!object.ReferenceEquals(xModifier, yModifier))
                    {
                        return(false);
                    }

                    return(true);
                }

                case TypeElementCode.FunctionPointer:
                {
                    if (!object.ReferenceEquals(x.GetFunctionPointer(), y.GetFunctionPointer()))
                    {
                        return(false);
                    }

                    return(true);
                }

                case TypeElementCode.GenericParameter:
                {
                    bool xIsMethod;
                    int  xPosition;
                    x.GetGenericParameter(out xIsMethod, out xPosition);

                    bool yIsMethod;
                    int  yPosition;
                    y.GetGenericParameter(out yIsMethod, out yPosition);

                    if (xIsMethod != yIsMethod)
                    {
                        return(false);
                    }

                    if (xPosition != yPosition)
                    {
                        return(false);
                    }

                    return(true);
                }

                case TypeElementCode.GenericType:
                {
                    if (!object.ReferenceEquals(x.DeclaringType, y.DeclaringType))
                    {
                        return(false);
                    }

                    if (!Equals(x.GenericArguments, y.GenericArguments))
                    {
                        return(false);
                    }

                    return(true);
                }

                case TypeElementCode.Pinned:
                {
                    if (!object.ReferenceEquals(x.ElementType, y.ElementType))
                    {
                        return(false);
                    }

                    return(true);
                }

                case TypeElementCode.Pointer:
                {
                    if (!object.ReferenceEquals(x.ElementType, y.ElementType))
                    {
                        return(false);
                    }

                    return(true);
                }

                case TypeElementCode.DeclaringType:
                    throw new InvalidOperationException();

                default:
                    throw new NotImplementedException();
                }
            }