private bool IsBundle(int updateIndex)
 {
     EnsureBundlesIndexLoaded();
     if (BundlesIndex.ContainsKey(updateIndex))
     {
         return(true);
     }
     else if (IsInBaseline(updateIndex))
     {
         return(BaselineSource.IsBundle(updateIndex));
     }
     else
     {
         return(false);
     }
 }
        private IEnumerable <Identity> GetBundledUpdates(int updateIndex)
        {
            EnsureBundlesIndexLoaded();

            if (BundlesIndex.TryGetValue(updateIndex, out var result))
            {
                return(result.Select(index => this[index]));
            }
            else if (IsInBaseline(updateIndex))
            {
                return(BaselineSource.GetBundledUpdates(updateIndex));
            }
            else
            {
                throw new Exception($"Update {this[updateIndex]} is not a bundle");
            }
        }
        private void AddUpdateBundleInformation(int newUpdateIndex, Identity newUpdateIdentity, XDocument updateXml)
        {
            var bundledUpdates = BundlesUpdatesParser.Parse(updateXml);

            if (PendingBundledUpdates.ContainsKey(newUpdateIdentity))
            {
                // We've seen this update before, as bundled with other updates
                // Now that we have an update for it, adds its bundling information
                IsBundledTable.Add(newUpdateIndex, PendingBundledUpdates[newUpdateIdentity]);
                foreach (var newUpdateParentBundleIndex in PendingBundledUpdates[newUpdateIdentity])
                {
                    // A bundled update that was pending before was added; add it to the parent's list of bundled updates
                    if (!BundlesIndex[newUpdateParentBundleIndex].Contains(newUpdateIndex))
                    {
                        BundlesIndex[newUpdateParentBundleIndex].Add(newUpdateIndex);
                    }
                }

                // Remove from list of pending updates;
                PendingBundledUpdates.Remove(newUpdateIdentity);
            }
            else
            {
                // When initially added, updates are not considered bundled
                // Updates become bundled when they are found within another update
                IsBundledTable.Add(newUpdateIndex, new List <int>());
            }

            if (bundledUpdates.Count > 0)
            {
                var knownBundledUpdates   = bundledUpdates.Where(u => Identities.Contains(u)).Select(id => this[id]);
                var unknownBundledUpdates = bundledUpdates.Where(u => !Identities.Contains(u));

                // Add known bundled updates
                BundlesIndex.Add(
                    newUpdateIndex,
                    new List <int>(knownBundledUpdates));

                // Mark all bundled updates as bundled
                foreach (var bundledUpdate in knownBundledUpdates)
                {
                    // Try to mark the bundled update as bundled by adding it to the bundled table
                    if (IsBundledTable.ContainsKey(bundledUpdate))
                    {
                        // An entry already exists; switch it to true now, regardless of the previous value
                        if (!IsBundledTable[bundledUpdate].Contains(newUpdateIndex))
                        {
                            IsBundledTable[bundledUpdate].Add(newUpdateIndex);
                        }
                    }
                    else
                    {
                        IsBundledTable.Add(bundledUpdate, new List <int>()
                        {
                            newUpdateIndex
                        });
                    }
                }

                // Add unknown bundled updates to a pending list
                foreach (var bundledUpdate in unknownBundledUpdates)
                {
                    // The bundled update was not added to the metadata collection yet. Put it on a pending list with a mapping to its parent bundle
                    if (PendingBundledUpdates.ContainsKey(bundledUpdate))
                    {
                        if (!PendingBundledUpdates[bundledUpdate].Contains(newUpdateIndex))
                        {
                            PendingBundledUpdates[bundledUpdate].Add(newUpdateIndex);
                        }
                    }
                    else
                    {
                        PendingBundledUpdates.TryAdd(bundledUpdate, new List <int>()
                        {
                            newUpdateIndex
                        });
                    }
                }
            }
        }