private static async Task SearchProfileField(UnityEngine.Object profile, SearchConfig config, List <ProfileSearchResult> searchResults)
        {
            await Task.Yield();

            // The result that we will return, if not empty
            ProfileSearchResult result = new ProfileSearchResult();

            result.Profile = profile;
            BaseMixedRealityProfile baseProfile = (profile as BaseMixedRealityProfile);

            result.IsCustomProfile = (baseProfile != null) ? baseProfile.IsCustomProfile : false;
            searchResults.Add(result);

            // Go through the profile's serialized fields
            foreach (SerializedProperty property in GatherProperties(profile))
            {
                if (CheckFieldForProfile(property))
                {
                    await SearchProfileField(property.objectReferenceValue, config, searchResults);
                }
                else
                {
                    CheckFieldForKeywords(property, config, result);
                }
            }

            if (result.Fields.Count > 0)
            {
                result.Fields.Sort(delegate(FieldSearchResult r1, FieldSearchResult r2)
                {
                    if (r1.MatchStrength != r2.MatchStrength)
                    {
                        return(r2.MatchStrength.CompareTo(r1.MatchStrength));
                    }
                    return(r2.Property.name.CompareTo(r1.Property.name));
                });
            }
        }
        private static void CheckFieldForKeywords(SerializedProperty property, SearchConfig config, ProfileSearchResult result)
        {
            int    numMatchedKeywords = 0;
            int    numExactMatches    = 0;
            int    numFieldMatches    = 0;
            int    numTooltipMatches  = 0;
            int    numContentMatches  = 0;
            string propertyName       = property.name.ToLower();
            string toolTip            = property.tooltip.ToLower();

            foreach (string keyword in config.Keywords)
            {
                bool keywordMatch = false;

                if (propertyName.Contains(keyword))
                {
                    keywordMatch = true;
                    numFieldMatches++;
                    if (propertyName == keyword)
                    {
                        numExactMatches++;
                    }
                }

                if (config.SearchTooltips)
                {
                    if (toolTip.Contains(keyword))
                    {
                        keywordMatch = true;
                        numTooltipMatches++;
                    }
                }

                if (config.SearchFieldContent)
                {
                    switch (property.propertyType)
                    {
                    case SerializedPropertyType.ObjectReference:
                        if (property.objectReferenceValue != null && property.objectReferenceValue.name.ToLower().Contains(keyword))
                        {
                            keywordMatch = true;
                            numContentMatches++;
                        }
                        break;

                    case SerializedPropertyType.String:
                        if (!string.IsNullOrEmpty(property.stringValue) && property.stringValue.ToLower().Contains(keyword))
                        {
                            keywordMatch = true;
                            numContentMatches++;
                        }
                        break;
                    }
                }

                if (keywordMatch)
                {
                    numMatchedKeywords++;
                }
            }

            bool requirementsMet = numMatchedKeywords > 0;

            if (config.RequireAllKeywords && config.Keywords.Count > 1)
            {
                requirementsMet &= numMatchedKeywords >= config.Keywords.Count;
            }

            if (requirementsMet)
            {
                int matchStrength = numMatchedKeywords + numExactMatches;
                if (numMatchedKeywords >= config.Keywords.Count)
                {   // If we match all keywords in a multi-keyword search, double the score
                    matchStrength *= 2;
                }

                // Weight the score based on match type
                matchStrength += numFieldMatches * 3;
                matchStrength += numTooltipMatches * 2;
                matchStrength += numContentMatches * 1;

                result.ProfileMatchStrength += matchStrength;
                result.Fields.Add(new FieldSearchResult()
                {
                    Property      = property.Copy(),
                    MatchStrength = numMatchedKeywords,
                });
            }
        }