internal void UpdateDependenciesFrom(
            DataKind kind,
            string fromKey,
            ItemDescriptor fromItem
            )
        {
            var fromWhat            = new KindAndKey(kind, fromKey);
            var updatedDependencies = ComputeDependenciesFrom(kind, fromItem); // never null

            if (_dependenciesFrom.TryGetValue(fromWhat, out var oldDependencySet))
            {
                foreach (var oldDep in oldDependencySet)
                {
                    if (_dependenciesTo.TryGetValue(oldDep, out var depsToThisOldDep))
                    {
                        depsToThisOldDep.Remove(fromWhat);
                    }
                }
            }
            _dependenciesFrom[fromWhat] = updatedDependencies;
            foreach (var newDep in updatedDependencies)
            {
                if (!_dependenciesTo.TryGetValue(newDep, out var depsToThisNewDep))
                {
                    depsToThisNewDep        = new HashSet <KindAndKey>();
                    _dependenciesTo[newDep] = depsToThisNewDep;
                }
                depsToThisNewDep.Add(fromWhat);
            }
        }
 internal void AddAffectedItems(ISet <KindAndKey> itemsOut, KindAndKey initialModifiedItem)
 {
     if (!itemsOut.Contains(initialModifiedItem))
     {
         itemsOut.Add(initialModifiedItem);
         if (_dependenciesTo.TryGetValue(initialModifiedItem, out var affectedItems))
         {
             foreach (var affectedItem in affectedItems)
             {
                 AddAffectedItems(itemsOut, affectedItem);
             }
         }
     }
 }