private static IEnumerable <FieldType> GetFieldsForFieldType(string remote, Introspection.TypeElement parentField)
        {
            FieldTypeResolver complexFieldTypeResolver = member =>
            {
                if (!(member is RemoteLiteralGraphTypeMemberInfo literalMember))
                {
                    return(null);
                }

                if (!RemoteServerTypes.TryGetValue(remote, out var remoteTypes))
                {
                    return(null);
                }

                var schemaType = remoteTypes.FirstOrDefault(t => t.Name == literalMember.TypeName);
                var realType   = literalMember.IsList
                    ? typeof(ListGraphType <>).MakeGenericType(schemaType)
                    : schemaType;

                return(new FieldType
                {
                    Name = literalMember.Name,
                    Type = realType,
                    Resolver = LiteralGraphTypeHelpers.CreateFieldResolverFor(literalMember)
                });
            };

            var fields = parentField.Fields;

            if (fields == null)
            {
                return(new FieldType[] { });
            }

            return(fields
                   .Select(field =>
            {
                return new RemoteLiteralGraphTypeMemberInfo
                {
                    DeclaringTypeName = parentField.Name,
                    Name = field.Name,
                    Type = IntrospectionTypeToLiteralGraphTypeMemberInfoType(field.Type),
                    TypeName = IntrospectionTypeToLiteralGraphTypeMemberInfoTypeName(field.Type),
                    IsList = field.Type.Kind == TypeElementTypeKind.List,
                    GetValueFn = ctx =>
                    {
                        return ((JToken)ctx.Source)[field.Name].Value <object>();
                    }
                };
            })
                   // TODO: handle unresolvable types (I'm looking at you UNION)
                   .Where(member => member.Type != LiteralGraphTypeMemberInfoType.Unknown)
                   .Select(member => LiteralGraphTypeHelpers.GetFieldTypeForMember(member, complexFieldTypeResolver))
                   .ToList());
        }
        private IEnumerable <FieldType> GetFields()
        {
            const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;

            var members = typeof(T)
                          .GetProperties(bindingFlags)
                          .AsEnumerable <MemberInfo>()
                          .Union(typeof(T).GetFields(bindingFlags))
                          .Select(member =>
            {
                var type = GetTypeForMemberInfo(member);

                return(new TypedLiteralGraphTypeMemberInfo
                {
                    DeclaringTypeName = member.DeclaringType.FullName,
                    Name = member.Name,
                    Type = LiteralGraphTypeHelpers.GetLiteralGraphTypeMemberInfoTypeForType(type),
                    IsList = IsListType(type),
                    ActualType = type,
                    GetValueFn = MakeGetValueFnForMemberInfo(member)
                });
            })
                          .ToList();

            FieldTypeResolver complexTypeResolver = member =>
            {
                if (!(member is TypedLiteralGraphTypeMemberInfo typedMember))
                {
                    return(null);
                }

                var maybeActualType = typedMember.ActualType;
                if (maybeActualType == null)
                {
                    return(null);
                }

                var literalGraphType = typedMember.IsList
                                       // IEnumerable<T> -> ListGraphType<LiteralGraphType<T>>
                    ? typeof(ListGraphType <>).MakeGenericType(typeof(LiteralGraphType <>).MakeGenericType(GetListElementType(maybeActualType)))
                                       // T -> LiteralGraphType<T>
                    : typeof(LiteralGraphType <>).MakeGenericType(maybeActualType);

                return(typeof(LiteralGraphTypeHelpers)
                       .GetMethod(nameof(LiteralGraphTypeHelpers.CreateFieldType), BindingFlags.NonPublic | BindingFlags.Static)
                       .MakeGenericMethod(literalGraphType)
                       .Invoke(null, new[] { member }) as FieldType);
            };

            return(members
                   .Select(member =>
            {
                try
                {
                    // Find the field type
                    var fieldType = LiteralGraphTypeHelpers.GetFieldTypeForMember(member, complexTypeResolver);

                    return fieldType;
                }
                catch (Exception)
                {
                    // TODO: log

                    return null;
                }
            })
                   .ToList());
        }