private static OrderSensitiveValueComparisonList <LogicalLocation> ConstructLogicalLocationsChain(
            LogicalLocation currentLogicalLocation,
            IList <LogicalLocation> existingLogicalLocations)
        {
            var logicalLocationChain = new OrderSensitiveValueComparisonList <LogicalLocation>(LogicalLocation.ValueComparer);

            int parentIndex;

            do
            {
                currentLogicalLocation = currentLogicalLocation.DeepClone();
                parentIndex            = currentLogicalLocation.ParentIndex;

                // Index information is entirely irrelevant for the identity of nested logical locations,
                // as each element of the chain could be stored at arbitrary locations in the
                // run.logicalLocations table. And so we elide this information.
                currentLogicalLocation.ParentIndex = -1;
                currentLogicalLocation.Index       = -1;

                logicalLocationChain.Add(currentLogicalLocation);

                if (parentIndex != -1)
                {
                    currentLogicalLocation = existingLogicalLocations[parentIndex];
                }
            } while (parentIndex != -1);

            return(logicalLocationChain);
        }
        private int CacheLogicalLocation(LogicalLocation logicalLocation, IList <LogicalLocation> currentLogicalLocations)
        {
            logicalLocation = logicalLocation.DeepClone();

            // Ensure all parent nodes are remapped.
            int parentIndex = logicalLocation.ParentIndex;

            if (parentIndex != -1)
            {
                logicalLocation.ParentIndex = CacheLogicalLocation(currentLogicalLocations[parentIndex], currentLogicalLocations);
            }

            OrderSensitiveValueComparisonList <LogicalLocation> logicalLocationChain = ConstructLogicalLocationsChain(logicalLocation, LogicalLocations);

            if (!LogicalLocationToIndex.TryGetValue(logicalLocationChain, out int remappedIndex))
            {
                remappedIndex         = LogicalLocationToIndex.Count;
                logicalLocation.Index = remappedIndex;

                this.LogicalLocations.Add(logicalLocation);
                LogicalLocationToIndex[logicalLocationChain] = remappedIndex;
            }

            return(remappedIndex);
        }