// effects: A restrictive version of GroupLeafChildrenByExtent --
        // only for LASJ and LOJ nodes (works for LOJ only when A LOJ B LOJ C
        // s.t., B and C are subsets of A -- in our case that is how LOJs are constructed
        private static List <CellTreeNode> GroupNonAssociativeLeafChildren(List <CellTreeNode> nodes)
        {
            // Keep track of leaf cells for each extent ignoring the 0th child
            var extentMap =
                new KeyToListMap <EntitySetBase, CellTreeNode>(EqualityComparer <EntitySetBase> .Default);

            var newNodes     = new List <CellTreeNode>();
            var nonLeafNodes = new List <CellTreeNode>();

            // Add the 0th child
            newNodes.Add(nodes[0]);
            for (var i = 1; i < nodes.Count; i++)
            {
                var node     = nodes[i];
                var leafNode = node as LeafCellTreeNode;
                // All non-leaf nodes are added to the result now
                // leaf nodes are added outside the loop
                if (leafNode != null)
                {
                    extentMap.Add(leafNode.LeftCellWrapper.RightCellQuery.Extent, leafNode);
                }
                else
                {
                    nonLeafNodes.Add(node);
                }
            }
            // Go through the map and add the leaf children
            // If a group of nodes exists for the 0th node's extent -- place
            // that group first
            var firstNode = nodes[0] as LeafCellTreeNode;

            if (firstNode != null)
            {
                var firstExtent = firstNode.LeftCellWrapper.RightCellQuery.Extent;
                if (extentMap.ContainsKey(firstExtent))
                {
                    newNodes.AddRange(extentMap.ListForKey(firstExtent));
                    // Remove this set from the map
                    extentMap.RemoveKey(firstExtent);
                }
            }
            newNodes.AddRange(extentMap.AllValues);
            newNodes.AddRange(nonLeafNodes);
            return(newNodes);
        }
        private static List <CellTreeNode> GroupNonAssociativeLeafChildren(
            List <CellTreeNode> nodes)
        {
            KeyToListMap <EntitySetBase, CellTreeNode> keyToListMap = new KeyToListMap <EntitySetBase, CellTreeNode>((IEqualityComparer <EntitySetBase>)EqualityComparer <EntitySetBase> .Default);
            List <CellTreeNode> cellTreeNodeList1 = new List <CellTreeNode>();
            List <CellTreeNode> cellTreeNodeList2 = new List <CellTreeNode>();

            cellTreeNodeList1.Add(nodes[0]);
            for (int index = 1; index < nodes.Count; ++index)
            {
                CellTreeNode     node             = nodes[index];
                LeafCellTreeNode leafCellTreeNode = node as LeafCellTreeNode;
                if (leafCellTreeNode != null)
                {
                    keyToListMap.Add(leafCellTreeNode.LeftCellWrapper.RightCellQuery.Extent, (CellTreeNode)leafCellTreeNode);
                }
                else
                {
                    cellTreeNodeList2.Add(node);
                }
            }
            LeafCellTreeNode node1 = nodes[0] as LeafCellTreeNode;

            if (node1 != null)
            {
                EntitySetBase extent = node1.LeftCellWrapper.RightCellQuery.Extent;
                if (keyToListMap.ContainsKey(extent))
                {
                    cellTreeNodeList1.AddRange((IEnumerable <CellTreeNode>)keyToListMap.ListForKey(extent));
                    keyToListMap.RemoveKey(extent);
                }
            }
            cellTreeNodeList1.AddRange(keyToListMap.AllValues);
            cellTreeNodeList1.AddRange((IEnumerable <CellTreeNode>)cellTreeNodeList2);
            return(cellTreeNodeList1);
        }
        // effects: A restrictive version of GroupLeafChildrenByExtent --
        // only for LASJ and LOJ nodes (works for LOJ only when A LOJ B LOJ C
        // s.t., B and C are subsets of A -- in our case that is how LOJs are constructed
        private static List<CellTreeNode> GroupNonAssociativeLeafChildren(List<CellTreeNode> nodes)
        {
            // Keep track of leaf cells for each extent ignoring the 0th child
            KeyToListMap<EntitySetBase, CellTreeNode> extentMap =
                new KeyToListMap<EntitySetBase, CellTreeNode>(EqualityComparer<EntitySetBase>.Default);

            List<CellTreeNode> newNodes = new List<CellTreeNode>();
            List<CellTreeNode> nonLeafNodes = new List<CellTreeNode>();
            // Add the 0th child
            newNodes.Add(nodes[0]);
            for (int i = 1; i < nodes.Count; i++)
            {
                CellTreeNode node = nodes[i];
                LeafCellTreeNode leafNode = node as LeafCellTreeNode;
                // All non-leaf nodes are added to the result now
                // leaf nodes are added outside the loop
                if (leafNode != null)
                {
                    extentMap.Add(leafNode.LeftCellWrapper.RightCellQuery.Extent, leafNode);
                }
                else
                {
                    nonLeafNodes.Add(node);
                }
            }
            // Go through the map and add the leaf children
            // If a group of nodes exists for the 0th node's extent -- place
            // that group first
            LeafCellTreeNode firstNode = nodes[0] as LeafCellTreeNode;
            if (firstNode != null)
            {
                EntitySetBase firstExtent = firstNode.LeftCellWrapper.RightCellQuery.Extent;
                if (extentMap.ContainsKey(firstExtent))
                {
                    newNodes.AddRange(extentMap.ListForKey(firstExtent));
                    // Remove this set from the map
                    extentMap.RemoveKey(firstExtent);
                }
            }
            newNodes.AddRange(extentMap.AllValues);
            newNodes.AddRange(nonLeafNodes);
            return newNodes;
        }