public override IEnumerable <MemberResult> GetDefinedMembers(int index, AstMemberType memberType)
        {
            HashSet <MemberResult> members = new HashSet <MemberResult>();

            HashSet <GeneroPackage> includedPackages = new HashSet <GeneroPackage>();

            if (memberType.HasFlag(AstMemberType.Types))
            {
                // Built-in types
                members.AddRange(BuiltinTypes.Select(x => new MemberResult(Tokens.TokenKinds[x], GeneroMemberType.Keyword, this)));

                foreach (var package in Packages.Values.Where(x => _importedPackages[x.Name] && x.ContainsInstanceMembers))
                {
                    members.Add(new MemberResult(package.Name, GeneroMemberType.Module, this));
                    includedPackages.Add(package);
                }
            }
            if (memberType.HasFlag(AstMemberType.Constants))
            {
                members.AddRange(SystemConstants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Keyword, this)));
                members.AddRange(SystemMacros.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
            }
            if (memberType.HasFlag(AstMemberType.Variables))
            {
                members.AddRange(SystemVariables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Keyword, this)));
            }
            if (memberType.HasFlag(AstMemberType.Functions))
            {
                members.AddRange(SystemFunctions.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Function, this)));
                foreach (var package in Packages.Values.Where(x => _importedPackages[x.Name] && x.ContainsStaticClasses))
                {
                    if (!includedPackages.Contains(package))
                    {
                        members.Add(new MemberResult(package.Name, GeneroMemberType.Module, this));
                    }
                }
            }

            // TODO: need to handle multiple results of the same name
            AstNode containingNode = GetContainingNode(_body, index);

            if (containingNode != null)
            {
                if (containingNode is IFunctionResult)
                {
                    if (memberType.HasFlag(AstMemberType.Variables))
                    {
                        members.AddRange((containingNode as IFunctionResult).Variables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                        foreach (var varList in (containingNode as IFunctionResult).LimitedScopeVariables)
                        {
                            foreach (var item in varList.Value)
                            {
                                if (item.Item2.IsInSpan(index))
                                {
                                    members.Add(new MemberResult(item.Item1.Name, item.Item1, GeneroMemberType.Instance, this));
                                    break;
                                }
                            }
                        }
                    }
                    if (memberType.HasFlag(AstMemberType.Types))
                    {
                        members.AddRange((containingNode as IFunctionResult).Types.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Constants))
                    {
                        members.AddRange((containingNode as IFunctionResult).Constants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Functions))
                    {
                        foreach (var res in (containingNode as IFunctionResult).Variables /*.Where(x => x.Value.HasChildFunctions(this))
                                                                                           */.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                        {
                            if (!members.Contains(res))
                            {
                                members.Add(res);
                            }
                        }

                        foreach (var varList in (containingNode as IFunctionResult).LimitedScopeVariables)
                        {
                            foreach (var item in varList.Value)
                            {
                                if (item.Item2.IsInSpan(index))
                                {
                                    members.Add(new MemberResult(item.Item1.Name, item.Item1, GeneroMemberType.Instance, this));
                                    break;
                                }
                            }
                        }
                    }
                }

                if (_body is IModuleResult)
                {
                    // check for module vars, types, and constants (and globals defined in this module)
                    if (memberType.HasFlag(AstMemberType.Variables))
                    {
                        members.AddRange((_body as IModuleResult).Variables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                        members.AddRange((_body as IModuleResult).GlobalVariables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Types))
                    {
                        members.AddRange((_body as IModuleResult).Types.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                        members.AddRange((_body as IModuleResult).GlobalTypes.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Constants))
                    {
                        members.AddRange((_body as IModuleResult).Constants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                        members.AddRange((_body as IModuleResult).GlobalConstants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Dialogs))
                    {
                        members.AddRange((_body as IModuleResult).Functions.Where(x => x.Value is DeclarativeDialogBlock)
                                         .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Dialog, this)));
                        members.AddRange((_body as IModuleResult).FglImports.Select(x => new MemberResult(x, GeneroMemberType.Module, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Reports))
                    {
                        members.AddRange((_body as IModuleResult).Functions.Where(x => x.Value is ReportBlockNode)
                                         .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Report, this)));
                    }
                    if (memberType.HasFlag(AstMemberType.Functions))
                    {
                        members.AddRange((_body as IModuleResult).Functions
                                         .Where(x => !(x.Value is ReportBlockNode) && !(x.Value is DeclarativeDialogBlock))
                                         .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Method, this)));
                        foreach (var res in (_body as IModuleResult).Variables /*.Where(x => x.Value.HasChildFunctions(this))
                                                                                */.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                        {
                            if (!members.Contains(res))
                            {
                                members.Add(res);
                            }
                        }
                        foreach (var res in (_body as IModuleResult).GlobalVariables /*.Where(x => x.Value.HasChildFunctions(this))
                                                                                      */.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                        {
                            if (!members.Contains(res))
                            {
                                members.Add(res);
                            }
                        }
                    }

                    // Tables and cursors are module specific, and cannot be accessed via fgl import
                    if (memberType.HasFlag(AstMemberType.DeclaredCursors) ||
                        memberType.HasFlag(AstMemberType.PreparedCursors) ||
                        memberType.HasFlag(AstMemberType.Tables))
                    {
                        if (memberType.HasFlag(AstMemberType.DeclaredCursors))
                        {
                            members.AddRange((_body as IModuleResult).Cursors.Where(x => x.Value is DeclareStatement).Select(x => new MemberResult(x.Value.Name, x.Value, GeneroMemberType.Cursor, this)));
                        }
                        if (memberType.HasFlag(AstMemberType.PreparedCursors))
                        {
                            members.AddRange((_body as IModuleResult).Cursors.Where(x => x.Value is PrepareStatement).Select(x => new MemberResult(x.Value.Name, x.Value, GeneroMemberType.Cursor, this)));
                        }
                        if (memberType.HasFlag(AstMemberType.Tables))
                        {
                            members.AddRange((_body as IModuleResult).Tables.Select(x => new MemberResult(x.Value.Name, x.Value, GeneroMemberType.DbTable, this)));
                        }
                    }
                    else
                    {
                        members.AddRange((_body as IModuleResult).FglImports.Select(x => new MemberResult(x, GeneroMemberType.Module, this)));
                    }
                }
            }

            // TODO: this could probably be done more efficiently by having each GeneroAst load globals and functions into
            // dictionaries stored on the IGeneroProject, instead of in each project entry.
            // However, this does required more upkeep when changes occur. Will look into it...
            if (_projEntry != null && _projEntry is IGeneroProjectEntry)
            {
                IGeneroProjectEntry genProj = _projEntry as IGeneroProjectEntry;
                if (genProj.ParentProject != null)
                {
                    foreach (var projEntry in genProj.ParentProject.ProjectEntries.Where(x => x.Value != genProj))
                    {
                        if (projEntry.Value.Analysis != null &&
                            projEntry.Value.Analysis.Body != null)
                        {
                            projEntry.Value.Analysis.Body.SetNamespace(null);
                            IModuleResult modRes = projEntry.Value.Analysis.Body as IModuleResult;
                            if (modRes != null)
                            {
                                // check global types
                                // TODO: need to add an option to enable/disable legacy linking (to not reference other modules' non-public members
                                if (memberType.HasFlag(AstMemberType.Variables))
                                {
                                    members.AddRange(modRes.GlobalVariables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                                    members.AddRange(modRes.Variables.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.Types))
                                {
                                    members.AddRange(modRes.GlobalTypes.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                                    members.AddRange(modRes.Types.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Class, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.Constants))
                                {
                                    members.AddRange(modRes.GlobalConstants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                                    members.AddRange(modRes.Constants.Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Constant, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.Dialogs))
                                {
                                    members.AddRange(modRes.Functions.Where(x => x.Value is DeclarativeDialogBlock)
                                                     .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Dialog, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.Reports))
                                {
                                    members.AddRange(modRes.Functions.Where(x => x.Value is ReportBlockNode)
                                                     .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Report, this)));
                                }
                                if (memberType.HasFlag(AstMemberType.Functions))
                                {
                                    members.AddRange(modRes.Functions.Where(x => !(x.Value is ReportBlockNode) && !(x.Value is DeclarativeDialogBlock))
                                                     .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Method, this)));
                                    foreach (var res in modRes.GlobalVariables/*.Where(x =>
                                                                               * {
                                                                               * return x.Value.HasChildFunctions(this);
                                                                               * })*/
                                             .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                                    {
                                        if (!members.Contains(res))
                                        {
                                            members.Add(res);
                                        }
                                    }
                                    foreach (var res in modRes.Variables/*.Where(x =>
                                                                         * {
                                                                         * return x.Value.HasChildFunctions(this);
                                                                         * })*/
                                             .Select(x => new MemberResult(x.Key, x.Value, GeneroMemberType.Variable, this)))
                                    {
                                        if (!members.Contains(res))
                                        {
                                            members.Add(res);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (memberType.HasFlag(AstMemberType.Functions))
            {
                _includePublicFunctions = true; // allow for deferred adding of public functions
            }

            if (memberType.HasFlag(AstMemberType.Tables))
            {
                _includeDatabaseTables = true;  // allow for deferred adding of external database tables
            }

            members.AddRange(this.ProjectEntry.GetIncludedFiles().Where(x => x.Analysis != null).SelectMany(x => x.Analysis.GetDefinedMembers(1, memberType)));

            return(members);
        }