BuildValue ExternalCommand::
getResultForOutput(Node* node, const BuildValue& value) {
  // If the value was a failed or skipped command, propagate the failure.
  if (value.isFailedCommand() || value.isSkippedCommand())
    return BuildValue::makeFailedInput();

  // Otherwise, we should have a successful command -- return the actual
  // result for the output.
  assert(value.isSuccessfulCommand());

  // If the node is virtual, the output is always a virtual input value.
  if (static_cast<BuildNode*>(node)->isVirtual()) {
    return BuildValue::makeVirtualInput();
  }
    
  // Find the index of the output node.
  //
  // FIXME: This is O(N). We don't expect N to be large in practice, but it
  // could be.
  auto it = std::find(outputs.begin(), outputs.end(), node);
  assert(it != outputs.end());
    
  auto idx = it - outputs.begin();
  assert(idx < value.getNumOutputs());

  auto& info = value.getNthOutputInfo(idx);
  if (info.isMissing())
    return BuildValue::makeMissingOutput();
    
  return BuildValue::makeExistingInput(info);
}
bool ExternalCommand::canUpdateIfNewerWithResult(const BuildValue& result) {
  // Unless `allowModifiedOutputs` is specified, we always need to update if
  // ran.
  if (!allowModifiedOutputs)
    return false;

  // If it was specified, then we can update if all of our outputs simply exist.
  for (unsigned i = 0, e = result.getNumOutputs(); i != e; ++i) {
    const FileInfo& outputInfo = result.getNthOutputInfo(i);

    // If the output is missing, we need to rebuild.
    if (outputInfo.isMissing())
      return false;
  }
  return true;
}