anchor.diff:      return completer.future;
     }
   
  +  ApiSignature getUnitKeyByPath(String path) {
  +    var file = fsState.getFileForPath(path);
  +    ApiSignature signature = new ApiSignature();
  +    signature.addUint32List(_salt);
  +    signature.addString(file.transitiveSignature);
  +    return signature;
  +  }
  +
     /**
      * Return a [Future] that completes with a [ParseResult] for the file
      * with the given [path].
  
positive.code:       }
      }
      return null;
    }
  
    /**
     * Perform a single chunk of work and produce [results].
     */
    Future<Null> performWork() async {
      if (_fileTracker.verifyChangedFilesIfNeeded()) {
        return;
      }
  
      // Analyze a requested file.
      if (_requestedFiles.isNotEmpty) {
        String path = _requestedFiles.keys.first;
        try {
          AnalysisResult result = _computeAnalysisResult(path, withUnit: true);
          // If a part without a library, delay its analysis.
          if (result == null) {
            _requestedParts
                .putIfAbsent(path, () => [])
                .addAll(_requestedFiles.remove(path));
            return;
          }
          // Notify the completers.
          _requestedFiles.remove(path).forEach((completer) {
            completer.complete(result);
          });
          // Remove from to be analyzed and produce it now.
          _fileTracker.fileWasAnalyzed(path);
          _resultController.add(result);
        } catch (exception, stackTrace) {
          _fileTracker.fileWasAnalyzed(path);
          _requestedFiles.remove(path).forEach((completer) {
            completer.completeError(exception, stackTrace);
          });
        }
        return;
      }
  
      // Process an index request.
      if (_indexRequestedFiles.isNotEmpty) {
        String path = _indexRequestedFiles.keys.first;
        AnalysisDriverUnitIndex index = _computeIndex(path);
        _indexRequestedFiles.remove(path).forEach((completer) {
          completer.complete(index);
        });
        return;
      }
  
      // Process a unit element key request.
      if (_unitElementSignatureRequests.isNotEmpty) {
        String path = _unitElementSignatureRequests.keys.first;
        String signature = _computeUnitElementSignature(path);
        _unitElementSignatureRequests.remove(path).forEach((completer) {
          completer.complete(signature);
        });
        return;
      }
  
      // Process a unit element request.
      if (_unitElementRequestedFiles.isNotEmpty) {
        String path = _unitElementRequestedFiles.keys.first;
        UnitElementResult result = _computeUnitElement(path);
        _unitElementRequestedFiles.remove(path).forEach((completer) {
          completer.complete(result);
        });
        return;
      }
  
      // Compute files defining a name.
      if (_definingClassMemberNameTasks.isNotEmpty) {
        _FilesDefiningClassMemberNameTask task =
            _definingClassMemberNameTasks.first;
        bool isDone = await task.perform();
        if (isDone) {
          _definingClassMemberNameTasks.remove(task);
        }
        return;
      }
  
      // Compute files referencing a name.
      if (_referencingNameTasks.isNotEmpty) {
        _FilesReferencingNameTask task = _referencingNameTasks.first;
        bool isDone = await task.perform();
        if (isDone) {
          _referencingNameTasks.remove(task);
        }
        return;
      }
  
      // Compute top-level declarations.
      if (_topLevelNameDeclarationsTasks.isNotEmpty) {
        _TopLevelNameDeclarationsTask task = _topLevelNameDeclarationsTasks.first;
        bool isDone = await task.perform();
        if (isDone) {
          _topLevelNameDeclarationsTasks.remove(task);
        }
        return;
      }
  
      // Analyze a priority file.
      if (_priorityFiles.isNotEmpty) {
        for (String path in _priorityFiles) {
          if (_fileTracker.isFilePending(path)) {
            try {
              AnalysisResult result =
                  _computeAnalysisResult(path, withUnit: true);
              if (result == null) {
                _partsToAnalyze.add(path);
              } else {
                _resultController.add(result);
              }
            } catch (exception, stackTrace) {
              _reportException(path, exception, stackTrace);
            } finally {
              _fileTracker.fileWasAnalyzed(path);
            }
            return;
          }
        }
      }
  
      // Analyze a general file.
      if (_fileTracker.hasPendingFiles) {
        String path = _fileTracker.anyPendingFile;
        try {
          AnalysisResult result = _computeAnalysisResult(path,
              withUnit: false, skipIfSameSignature: true);
          if (result == null) {
            _partsToAnalyze.add(path);
          } else if (result == AnalysisResult._UNCHANGED) {
            // We found that the set of errors is the same as we produced the
            // last time, so we don't need to produce it again now.
          } else {
            _resultController.add(result);
            _lastProducedSignatures[result.path] = result._signature;
          }
        } catch (exception, stackTrace) {
          _reportException(path, exception, stackTrace);
        } finally {
          _fileTracker.fileWasAnalyzed(path);
        }
        return;
      }
  
      // Analyze a requested part file.
      if (_requestedParts.isNotEmpty) {
        String path = _requestedParts.keys.first;
        try {
          AnalysisResult result = _computeAnalysisResult(path,
              withUnit: true, asIsIfPartWithoutLibrary: true);
          // Notify the completers.
          _requestedParts.remove(path).forEach((completer) {
            completer.complete(result);
          });
          // Remove from to be analyzed and produce it now.
          _partsToAnalyze.remove(path);
          _resultController.add(result);
        } catch (exception, stackTrace) {
          _partsToAnalyze.remove(path);
          _requestedParts.remove(path).forEach((completer) {
            completer.completeError(exception, stackTrace);
          });
        }
        return;
      }
  
      // Analyze a general part.
      if (_partsToAnalyze.isNotEmpty) {
        String path = _partsToAnalyze.first;
        _partsToAnalyze.remove(path);
        try {
          AnalysisResult result = _computeAnalysisResult(path,
              withUnit: _priorityFiles.contains(path),
              asIsIfPartWithoutLibrary: true);
          _resultController.add(result);
        } catch (exception, stackTrace) {
          _reportException(path, exception, stackTrace);
        }
        return;
      }
    }
  
    void _reportException(String path, exception, StackTrace stackTrace) {
  
negative.code:     return completer.future;
    }
  
    ApiSignature getResolvedUnitKeyByPath(String path) {
      ApiSignature signature = getUnitKeyByPath(path);
      var file = fsState.getFileForPath(path);
      signature.addString(file.contentHash);
      return signature;
    }
  
    /**
     * Return a [Future] that completes with a [AnalysisResult] for the Dart
     * file with the given [path]. If the file is not a Dart file or cannot
  