// add an item to the subgroup with the given name
        void AddToSubgroup(object item, LiveShapingItem lsi, CollectionViewGroupInternal group, int level, object name, bool loading)
        {
            CollectionViewGroupInternal subgroup;
            int index = (loading && IsDataInGroupOrder) ? group.LastIndex : 0;

            // find the desired subgroup using the map
            object groupNameKey = GetGroupNameKey(name, group);

            if (((subgroup = group.GetSubgroupFromMap(groupNameKey) as CollectionViewGroupInternal) != null) &&
                group.GroupBy.NamesMatch(subgroup.Name, name))
            {
                // Try best to set the LastIndex. If not possible reset it to 0.
                group.LastIndex = (group.Items[index] == subgroup ? index : 0);

                // Recursively call the AddToSubgroups method on subgroup.
                AddToSubgroups(item, lsi, subgroup, level + 1, loading);
                return;
            }

            // find the desired subgroup using linear search
            for (int n = group.Items.Count; index < n; ++index)
            {
                subgroup = group.Items[index] as CollectionViewGroupInternal;
                if (subgroup == null)
                {
                    continue;           // skip children that are not groups
                }
                if (group.GroupBy.NamesMatch(subgroup.Name, name))
                {
                    group.LastIndex = index;

                    // Update the name to subgroup map on the group.
                    group.AddSubgroupToMap(groupNameKey, subgroup);

                    // Recursively call the AddToSubgroups method on subgroup.
                    AddToSubgroups(item, lsi, subgroup, level + 1, loading);
                    return;
                }
            }

            // the item didn't match any subgroups.  Create a new subgroup and add the item.
            subgroup = new CollectionViewGroupInternal(name, group);
            InitializeGroup(subgroup, group.GroupBy, level + 1);

            if (loading)
            {
                group.Add(subgroup);
                group.LastIndex = index;
            }
            else
            {
                group.Insert(subgroup, item, ActiveComparer);
            }

            // Update the name to subgroup map on the group.
            group.AddSubgroupToMap(groupNameKey, subgroup);

            // Recursively call the AddToSubgroups method on subgroup.
            AddToSubgroups(item, lsi, subgroup, level + 1, loading);
        }
        // Token: 0x060073D5 RID: 29653 RVA: 0x0021272C File Offset: 0x0021092C
        private void MoveWithinSubgroup(object item, CollectionViewGroupInternal group, int level, object name, IList list, int oldIndex, int newIndex)
        {
            object groupNameKey = this.GetGroupNameKey(name, group);
            CollectionViewGroupInternal collectionViewGroupInternal;

            if ((collectionViewGroupInternal = group.GetSubgroupFromMap(groupNameKey)) != null && group.GroupBy.NamesMatch(collectionViewGroupInternal.Name, name))
            {
                this.MoveWithinSubgroups(item, collectionViewGroupInternal, level + 1, list, oldIndex, newIndex);
                return;
            }
            int i     = 0;
            int count = group.Items.Count;

            while (i < count)
            {
                collectionViewGroupInternal = (group.Items[i] as CollectionViewGroupInternal);
                if (collectionViewGroupInternal != null && group.GroupBy.NamesMatch(collectionViewGroupInternal.Name, name))
                {
                    group.AddSubgroupToMap(groupNameKey, collectionViewGroupInternal);
                    this.MoveWithinSubgroups(item, collectionViewGroupInternal, level + 1, list, oldIndex, newIndex);
                    return;
                }
                i++;
            }
        }
        // Token: 0x060073D3 RID: 29651 RVA: 0x00212564 File Offset: 0x00210764
        private void AddToSubgroup(object item, LiveShapingItem lsi, CollectionViewGroupInternal group, int level, object name, bool loading)
        {
            int    i            = (loading && this.IsDataInGroupOrder) ? group.LastIndex : 0;
            object groupNameKey = this.GetGroupNameKey(name, group);
            CollectionViewGroupInternal collectionViewGroupInternal;

            if ((collectionViewGroupInternal = group.GetSubgroupFromMap(groupNameKey)) != null && group.GroupBy.NamesMatch(collectionViewGroupInternal.Name, name))
            {
                group.LastIndex = ((group.Items[i] == collectionViewGroupInternal) ? i : 0);
                this.AddToSubgroups(item, lsi, collectionViewGroupInternal, level + 1, loading);
                return;
            }
            int count = group.Items.Count;

            while (i < count)
            {
                collectionViewGroupInternal = (group.Items[i] as CollectionViewGroupInternal);
                if (collectionViewGroupInternal != null && group.GroupBy.NamesMatch(collectionViewGroupInternal.Name, name))
                {
                    group.LastIndex = i;
                    group.AddSubgroupToMap(groupNameKey, collectionViewGroupInternal);
                    this.AddToSubgroups(item, lsi, collectionViewGroupInternal, level + 1, loading);
                    return;
                }
                i++;
            }
            collectionViewGroupInternal = new CollectionViewGroupInternal(name, group, false);
            this.InitializeGroup(collectionViewGroupInternal, group.GroupBy, level + 1);
            if (loading)
            {
                group.Add(collectionViewGroupInternal);
                group.LastIndex = i;
            }
            else
            {
                group.Insert(collectionViewGroupInternal, item, this.ActiveComparer);
            }
            group.AddSubgroupToMap(groupNameKey, collectionViewGroupInternal);
            this.AddToSubgroups(item, lsi, collectionViewGroupInternal, level + 1, loading);
        }
        // move an item within the subgroup with the given name
        void MoveWithinSubgroup(object item, CollectionViewGroupInternal group, int level, object name, IList list, int oldIndex, int newIndex)
        {
            CollectionViewGroupInternal subgroup;

            // find the desired subgroup using the map
            object groupNameKey = GetGroupNameKey(name, group);

            if (((subgroup = group.GetSubgroupFromMap(groupNameKey)) != null) &&
                group.GroupBy.NamesMatch(subgroup.Name, name))
            {
                // Recursively call the MoveWithinSubgroups method on subgroup.
                MoveWithinSubgroups(item, subgroup, level + 1, list, oldIndex, newIndex);
                return;
            }

            // find the desired subgroup using linear search
            for (int index = 0, n = group.Items.Count; index < n; ++index)
            {
                subgroup = group.Items[index] as CollectionViewGroupInternal;
                if (subgroup == null)
                {
                    continue;           // skip children that are not groups
                }
                if (group.GroupBy.NamesMatch(subgroup.Name, name))
                {
                    // Update the name to subgroup map on the group.
                    group.AddSubgroupToMap(groupNameKey, subgroup);

                    // Recursively call the MoveWithinSubgroups method on subgroup.
                    MoveWithinSubgroups(item, subgroup, level + 1, list, oldIndex, newIndex);
                    return;
                }
            }

            // the item didn't match any subgroups.  Something is wrong.
            // This could happen if the app changes the item's group name (by changing
            // properties that the name depends on) without notification.
            // We don't support this - the Move is just a no-op.  But assert (in
            // debug builds) to help diagnose the problem if it arises.
            Debug.Assert(false, "Failed to find item in expected subgroup after Move");
        }
        // move an item within the subgroup with the given name
        void MoveWithinSubgroup(object item, CollectionViewGroupInternal group, int level, object name, IList list, int oldIndex, int newIndex)
        {
            CollectionViewGroupInternal subgroup;

            // find the desired subgroup using the map
            object groupNameKey = GetGroupNameKey(name, group);
            if (((subgroup = group.GetSubgroupFromMap(groupNameKey)) != null) &&
                group.GroupBy.NamesMatch(subgroup.Name, name))
            {
                // Recursively call the MoveWithinSubgroups method on subgroup.
                MoveWithinSubgroups(item, subgroup, level + 1, list, oldIndex, newIndex);
                return;
            }

            // find the desired subgroup using linear search
            for (int index=0, n=group.Items.Count; index < n; ++index)
            {
                subgroup = group.Items[index] as CollectionViewGroupInternal;
                if (subgroup == null)
                    continue;           // skip children that are not groups

                if (group.GroupBy.NamesMatch(subgroup.Name, name))
                {
                    // Update the name to subgroup map on the group.
                    group.AddSubgroupToMap(groupNameKey, subgroup);

                    // Recursively call the MoveWithinSubgroups method on subgroup.
                    MoveWithinSubgroups(item, subgroup, level+1, list, oldIndex, newIndex);
                    return;
                }
            }

            // the item didn't match any subgroups.  Something is wrong.
            // This could happen if the app changes the item's group name (by changing
            // properties that the name depends on) without notification.
            // We don't support this - the Move is just a no-op.  But assert (in
            // debug builds) to help diagnose the problem if it arises.
            Debug.Assert(false, "Failed to find item in expected subgroup after Move");
        }
        // add an item to the subgroup with the given name
        void AddToSubgroup(object item, LiveShapingItem lsi, CollectionViewGroupInternal group, int level, object name, bool loading)
        {
            CollectionViewGroupInternal subgroup;
            int index = (loading && IsDataInGroupOrder) ? group.LastIndex : 0;

            // find the desired subgroup using the map
            object groupNameKey = GetGroupNameKey(name, group);
            if (((subgroup = group.GetSubgroupFromMap(groupNameKey) as CollectionViewGroupInternal) != null) &&
                group.GroupBy.NamesMatch(subgroup.Name, name))
            {
                // Try best to set the LastIndex. If not possible reset it to 0.
                group.LastIndex = (group.Items[index] == subgroup ? index : 0);

                // Recursively call the AddToSubgroups method on subgroup.
                AddToSubgroups(item, lsi, subgroup, level + 1, loading);
                return;
            }

            // find the desired subgroup using linear search
            for (int n = group.Items.Count; index < n; ++index)
            {
                subgroup = group.Items[index] as CollectionViewGroupInternal;
                if (subgroup == null)
                    continue;           // skip children that are not groups

                if (group.GroupBy.NamesMatch(subgroup.Name, name))
                {
                    group.LastIndex = index;

                    // Update the name to subgroup map on the group.
                    group.AddSubgroupToMap(groupNameKey, subgroup);

                    // Recursively call the AddToSubgroups method on subgroup.
                    AddToSubgroups(item, lsi, subgroup, level+1, loading);
                    return;
                }
            }

            // the item didn't match any subgroups.  Create a new subgroup and add the item.
            subgroup = new CollectionViewGroupInternal(name, group);
            InitializeGroup(subgroup, group.GroupBy, level+1);

            if (loading)
            {
                group.Add(subgroup);
                group.LastIndex = index;
            }
            else
            {
                group.Insert(subgroup, item, ActiveComparer);
            }

            // Update the name to subgroup map on the group.
            group.AddSubgroupToMap(groupNameKey, subgroup);

            // Recursively call the AddToSubgroups method on subgroup.
            AddToSubgroups(item, lsi, subgroup, level+1, loading);
        }