public CorePointsToAnalysisData MergeCoreAnalysisDataForBackEdge( PointsToAnalysisData forwardEdgeAnalysisData, PointsToAnalysisData backEdgeAnalysisData, Func <PointsToAbstractValue, ImmutableHashSet <AnalysisEntity> > getChildAnalysisEntities, Action <AnalysisEntity, PointsToAnalysisData> resetAbstractValue) { // Stop tracking points to values present in both branches if their is an assignment to a may-be null value from the back edge. // Clone the input forwardEdgeAnalysisData to ensure we don't overwrite the input dictionary. forwardEdgeAnalysisData = (PointsToAnalysisData)forwardEdgeAnalysisData.Clone(); List <AnalysisEntity> keysInMap1 = forwardEdgeAnalysisData.CoreAnalysisData.Keys.ToList(); foreach (var key in keysInMap1) { var forwardEdgeValue = forwardEdgeAnalysisData[key]; if (backEdgeAnalysisData.TryGetValue(key, out var backEdgeValue) && backEdgeValue != forwardEdgeValue) { switch (backEdgeValue.NullState) { case NullAbstractValue.MaybeNull: stopTrackingAnalysisDataForKeyAndChildren(); break; case NullAbstractValue.NotNull: if (backEdgeValue.MakeMayBeNull() != forwardEdgeValue) { if (forwardEdgeValue.NullState == NullAbstractValue.NotNull) { stopTrackingAnalysisDataForChildren(); } else { stopTrackingAnalysisDataForKeyAndChildren(); } } break; } void stopTrackingAnalysisDataForKeyAndChildren() { stopTrackingAnalysisDataForChildren(); stopTrackingAnalysisDataForEntity(key); } void stopTrackingAnalysisDataForChildren() { var childEntities = getChildAnalysisEntities(forwardEdgeValue) .AddRange(getChildAnalysisEntities(backEdgeValue)); foreach (var childEntity in childEntities) { stopTrackingAnalysisDataForEntity(childEntity); } } void stopTrackingAnalysisDataForEntity(AnalysisEntity entity) { if (entity.IsChildOrInstanceMember) { resetAbstractValue(entity, forwardEdgeAnalysisData); } } } } var resultMap = Merge(forwardEdgeAnalysisData.CoreAnalysisData, backEdgeAnalysisData.CoreAnalysisData); Debug.Assert(Compare(forwardEdgeAnalysisData.CoreAnalysisData, resultMap) <= 0); Debug.Assert(Compare(backEdgeAnalysisData.CoreAnalysisData, resultMap) <= 0); return(resultMap); }