| Index: pkg/analyzer/lib/src/context/cache.dart | 
| diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart | 
| index 7dbe3984feeeee6bbe2c9395cb8f28686416b8d4..130beb41ee5029250f3d73b91e1c5d3feece13a2 100644 | 
| --- a/pkg/analyzer/lib/src/context/cache.dart | 
| +++ b/pkg/analyzer/lib/src/context/cache.dart | 
| @@ -54,6 +54,7 @@ class AnalysisCache { | 
| */ | 
| AnalysisCache(this._partitions) { | 
| for (CachePartition partition in _partitions) { | 
| +      partition.containingCaches.add(this); | 
| ReentrantSynchronousStreamSubscription<InvalidatedResult> subscription = | 
| partition.onResultInvalidated.listen((InvalidatedResult event) { | 
| onResultInvalidated.add(event); | 
| @@ -96,6 +97,9 @@ class AnalysisCache { | 
| in onResultInvalidatedPartitionSubscriptions) { | 
| subscription.cancel(); | 
| } | 
| +    for (CachePartition partition in _partitions) { | 
| +      partition.containingCaches.remove(this); | 
| +    } | 
| } | 
|  | 
| /** | 
| @@ -349,12 +353,18 @@ class CacheEntry { | 
| * Notifies the entry that the client is going to stop using it. | 
| */ | 
| void dispose() { | 
| -    _resultMap.forEach((descriptor, data) { | 
| +    _resultMap.forEach((ResultDescriptor descriptor, ResultData data) { | 
| TargetedResult result = new TargetedResult(target, descriptor); | 
| for (TargetedResult dependedOnResult in data.dependedOnResults) { | 
| -        ResultData dependedOnData = _partition._getDataFor(dependedOnResult); | 
| -        if (dependedOnData != null) { | 
| -          dependedOnData.dependentResults.remove(result); | 
| +        for (AnalysisCache cache in _partition.containingCaches) { | 
| +          CacheEntry entry = cache.get(dependedOnResult.target); | 
| +          if (entry != null) { | 
| +            ResultData data = | 
| +                entry.getResultDataOrNull(dependedOnResult.result); | 
| +            if (data != null) { | 
| +              data.dependentResults.remove(result); | 
| +            } | 
| +          } | 
| } | 
| } | 
| }); | 
| @@ -375,14 +385,21 @@ class CacheEntry { | 
| } | 
|  | 
| /** | 
| -   * Look up the [ResultData] of [descriptor], or add a new one if it isn't | 
| -   * there. | 
| +   * Return the result data associated with the [descriptor], creating one if it | 
| +   * isn't there. | 
| */ | 
| ResultData getResultData(ResultDescriptor descriptor) { | 
| return _resultMap.putIfAbsent(descriptor, () => new ResultData(descriptor)); | 
| } | 
|  | 
| /** | 
| +   * Return the result data associated with the [descriptor], or `null` if there | 
| +   * is no data currently associated with the descriptor. | 
| +   */ | 
| +  ResultData getResultDataOrNull(ResultDescriptor descriptor) => | 
| +      _resultMap[descriptor]; | 
| + | 
| +  /** | 
| * Return the state of the result represented by the given [descriptor]. | 
| */ | 
| CacheState getState(ResultDescriptor descriptor) { | 
| @@ -584,11 +601,19 @@ class CacheEntry { | 
| //      } | 
| } | 
| // Stop depending on other results. | 
| -    TargetedResult thisResult = new TargetedResult(target, descriptor); | 
| -    for (TargetedResult dependedOnResult in thisData.dependedOnResults) { | 
| -      ResultData data = _partition._getDataFor(dependedOnResult); | 
| -      if (data != null && deltaResult != DeltaResult.KEEP_CONTINUE) { | 
| -        data.dependentResults.remove(thisResult); | 
| +    if (deltaResult != DeltaResult.KEEP_CONTINUE) { | 
| +      TargetedResult thisResult = new TargetedResult(target, descriptor); | 
| +      for (TargetedResult dependedOnResult in thisData.dependedOnResults) { | 
| +        for (AnalysisCache cache in _partition.containingCaches) { | 
| +          CacheEntry entry = cache.get(dependedOnResult.target); | 
| +          if (entry != null) { | 
| +            ResultData data = | 
| +                entry.getResultDataOrNull(dependedOnResult.result); | 
| +            if (data != null) { | 
| +              data.dependentResults.remove(thisResult); | 
| +            } | 
| +          } | 
| +        } | 
| } | 
| } | 
| // Invalidate results that depend on this result. | 
| @@ -621,11 +646,15 @@ class CacheEntry { | 
| */ | 
| void _invalidateDependentResults( | 
| int id, ResultData thisData, Delta delta, int level) { | 
| +    // It is necessary to copy the results to a list to avoid a concurrent | 
| +    // modification of the set of dependent results. | 
| List<TargetedResult> dependentResults = thisData.dependentResults.toList(); | 
| for (TargetedResult dependentResult in dependentResults) { | 
| -      CacheEntry entry = _partition.get(dependentResult.target); | 
| -      if (entry != null) { | 
| -        entry._invalidate(id, dependentResult.result, delta, level); | 
| +      for (AnalysisCache cache in _partition.containingCaches) { | 
| +        CacheEntry entry = cache.get(dependentResult.target); | 
| +        if (entry != null) { | 
| +          entry._invalidate(id, dependentResult.result, delta, level); | 
| +        } | 
| } | 
| } | 
| } | 
| @@ -645,16 +674,26 @@ class CacheEntry { | 
| void _setDependedOnResults(ResultData thisData, TargetedResult thisResult, | 
| List<TargetedResult> dependedOn) { | 
| thisData.dependedOnResults.forEach((TargetedResult dependedOnResult) { | 
| -      ResultData data = _partition._getDataFor(dependedOnResult); | 
| -      if (data != null) { | 
| -        data.dependentResults.remove(thisResult); | 
| +      for (AnalysisCache cache in _partition.containingCaches) { | 
| +        CacheEntry entry = cache.get(dependedOnResult.target); | 
| +        if (entry != null) { | 
| +          ResultData data = entry.getResultDataOrNull(dependedOnResult.result); | 
| +          if (data != null) { | 
| +            data.dependentResults.remove(thisResult); | 
| +          } | 
| +        } | 
| } | 
| }); | 
| thisData.dependedOnResults = dependedOn; | 
| thisData.dependedOnResults.forEach((TargetedResult dependedOnResult) { | 
| -      ResultData data = _partition._getDataFor(dependedOnResult); | 
| -      if (data != null) { | 
| -        data.dependentResults.add(thisResult); | 
| +      for (AnalysisCache cache in _partition.containingCaches) { | 
| +        CacheEntry entry = cache.get(dependedOnResult.target); | 
| +        if (entry != null) { | 
| +          ResultData data = entry.getResultDataOrNull(dependedOnResult.result); | 
| +          if (data != null) { | 
| +            data.dependentResults.add(thisResult); | 
| +          } | 
| +        } | 
| } | 
| }); | 
| } | 
| @@ -671,8 +710,12 @@ class CacheEntry { | 
| thisData.value = descriptor.defaultValue; | 
| // Propagate the error state. | 
| thisData.dependentResults.forEach((TargetedResult dependentResult) { | 
| -      CacheEntry entry = _partition.get(dependentResult.target); | 
| -      entry._setErrorState(dependentResult.result, exception); | 
| +      for (AnalysisCache cache in _partition.containingCaches) { | 
| +        CacheEntry entry = cache.get(dependentResult.target); | 
| +        if (entry != null) { | 
| +          entry._setErrorState(dependentResult.result, exception); | 
| +        } | 
| +      } | 
| }); | 
| } | 
|  | 
| @@ -865,6 +908,12 @@ abstract class CachePartition { | 
| final InternalAnalysisContext context; | 
|  | 
| /** | 
| +   * A list of the caches that contain this partition. This includes the cache | 
| +   * associated with the context that owns this partition. | 
| +   */ | 
| +  final List<AnalysisCache> containingCaches = <AnalysisCache>[]; | 
| + | 
| +  /** | 
| * A table mapping caching policies to the cache flush managers. | 
| */ | 
| final HashMap<ResultCachingPolicy, CacheFlushManager> _flushManagerMap = | 
| @@ -1013,11 +1062,6 @@ abstract class CachePartition { | 
| } | 
| } | 
|  | 
| -  ResultData _getDataFor(TargetedResult result) { | 
| -    CacheEntry entry = context.analysisCache.get(result.target); | 
| -    return entry != null ? entry._resultMap[result.result] : null; | 
| -  } | 
| - | 
| /** | 
| * Return the [CacheFlushManager] for the given [descriptor], not `null`. | 
| */ | 
|  |