// http://facebook.github.io/graphql/June2018/#AreTypesCompatible()
        private bool AreTypesCompatible(
            ITypeNode variableType,
            IType locationType)
        {
            if (locationType.IsNonNullType())
            {
                if (variableType.IsNonNullType())
                {
                    return(AreTypesCompatible(
                               variableType.InnerType(),
                               locationType.InnerType()));
                }
                return(false);
            }

            if (variableType.IsNonNullType())
            {
                return(AreTypesCompatible(
                           variableType.InnerType(),
                           locationType));
            }

            if (locationType.IsListType())
            {
                if (variableType.IsListType())
                {
                    return(AreTypesCompatible(
                               variableType.InnerType(),
                               locationType.InnerType()));
                }
                return(false);
            }

            if (variableType.IsListType())
            {
                return(false);
            }

            if (variableType is NamedTypeNode vn &&
                locationType is INamedType lt)
            {
                return(string.Equals(
                           vn.Name.Value,
                           lt.Name,
                           StringComparison.Ordinal));
            }

            return(false);
        }
        // helpers
        protected TypeDefinitionField TransformTypeField(ITypeNode type, TypeDefinitionField context, bool nullable = false)
        {
            var ctx = context ?? new TypeDefinitionField();

            if (type.IsNonNullType())
            {
                ctx.NotNullable = true;
                return(TransformTypeField(type.InnerType(), ctx));
            }

            if (type.IsListType())
            {
                ctx.IsList    = true;
                ctx.InnerType = TransformTypeField(type.InnerType(), null);
                return(ctx);
            }

            ctx.Type = type.ToString();
            return(ctx);
        }