private void AddMembers(IDictionary <Type, MemberCollection> dict, Type type, BindingFlags flags, int recursionLevel)
        {
            if (!dict.ContainsKey(type))
            {
                MemberCollection memberInfo = AutocompleteMembersQuery(type.GetMembers(flags));
                dict.Add(type, memberInfo);
                for (int i = 0; i < memberInfo.Names.Count; i++)
                {
                    AddTypeImpl(memberInfo.UnderlyingTypes[i], recursionLevel);

                    // NB! There seems to be some unexpected behavior on Mono (v4.2.3.4) using null propagation with extension methods.
                    // Therefore, regular null checks and foreach statements are used!
                    // Issue: https://github.com/discosultan/quake-console/issues/6#issuecomment-217608599

                    //memberInfo.ParamInfos[i]?.ForEach(overload =>
                    //    overload?.ForEach(parameter => AddTypeImpl(parameter.ParameterType, recursionLevel)));

                    ParameterInfo[][] paramInfos = memberInfo.ParamInfos[i];
                    if (paramInfos != null)
                    {
                        foreach (ParameterInfo[] paramInfo in paramInfos)
                        {
                            if (paramInfo != null)
                            {
                                foreach (ParameterInfo param in paramInfo)
                                {
                                    AddTypeImpl(param.ParameterType, recursionLevel);
                                }
                            }
                        }
                    }
                }
            }
        }
        private static MemberCollection AutocompleteMembersQuery(IEnumerable <MemberInfo> members)
        {
            var result = new MemberCollection();

            var ordered = members.Where(x => !AutocompleteFilters
                                        .Any(y => x.Name.StartsWith(y, PythonInterpreter.StringComparisonMethod))) // Filter.
                          .GroupBy(x => x.Name)                                                                    // Distinctly named values only.
                          .OrderBy(x => x.Key)                                                                     // Order alphabetically.
                          .Select(group =>                                                                         // Pick member from first, param overloads from all
            {
                MemberInfo firstMember = group.First();
                return(new
                {
                    firstMember.Name,
                    Type = firstMember.GetUnderlyingType(),
                    firstMember.MemberType,
                    Parameters =
                        firstMember.MemberType == MemberTypes.Method
                                ? group.Select(x => ((MethodInfo)x).GetParameters()).ToArray()
                                : null
                });
            });

            ordered.ForEach(x => result.Add(x.Name, x.Type, x.MemberType, x.Parameters));

            return(result);
        }
 private void AddMembers(IDictionary <Type, MemberCollection> dict, Type type, BindingFlags flags, int recursionLevel)
 {
     if (!dict.ContainsKey(type))
     {
         MemberCollection memberInfo = AutocompleteMembersQuery(type.GetMembers(flags));
         dict.Add(type, memberInfo);
         for (int i = 0; i < memberInfo.Names.Count; i++)
         {
             AddTypeImpl(memberInfo.UnderlyingTypes[i], recursionLevel);
             memberInfo.ParamInfos[i]?.ForEach(overload =>
                                               overload?.ForEach(parameter => AddTypeImpl(parameter.ParameterType, recursionLevel)));
         }
     }
 }