anchor.diff:    do! Files.writeFile receiptPath receipt
   }
   
  -let compareReceipt (context : TaskContext) installPath location = async {
  +let private compareReceipt logger installPath location = async {
     let receiptPath = getReceiptPath installPath
   
     if File.Exists receiptPath
     then
  -    context.Console.Write("Reading receipt at " + receiptPath, LoggingLevel.Trace)
  +    logger.Trace("Reading receipt at " + receiptPath + "...")
  +
       let! content = Files.readFile receiptPath
       let maybePackageLocation =
         content
         |> Toml.parse
         |> Result.mapError Toml.TomlError.show
         |> Result.bind PackageLock.fromToml
  +
       match maybePackageLocation with
       | Result.Ok receiptLocation ->
         if receiptLocation = location
         then
           return true
         else
  -        context.Console.Write("Outdated receipt at " + installPath, LoggingLevel.Trace)
  +        logger.Info("The receipt at " + installPath + " is outdated. ")
  +
           return false
       | Result.Error error ->
  -      context.Console.Write(error, LoggingLevel.Debug)
  -      context.Console.Write("Invalid receipt at " + receiptPath + "; it will be deleted. ", LoggingLevel.Info)
  +      logger.Trace(error)
  +      logger.Warning("Invalid receipt at " + receiptPath + "; it will be deleted. ")
  +
         do! Files.delete receiptPath
  +
         return false
     else
  -    context.Console.Write("No receipt found for " + installPath, LoggingLevel.Trace)
  +    logger.Info("No receipt found for " + installPath + "; it will be installed. ")
  +
       return false
   }
   
   let installPackageSources (context : Tasks.TaskContext) (installPath : string) (location : PackageLock) (versions : Set<Version>) = async {
  -  let log x =
  -    x
  -    |> RichOutput.text
  -    |> context.Console.Write
  -
  -  let logSuccess x =
  -    x
  -    |> RichOutput.text
  -    |> RichOutput.foreground ConsoleColor.Green
  -    |> context.Console.Write
  +  let logger = createLogger context.Console
   
     let downloadManager = context.DownloadManager
     let gitManager = context.GitManager
  -  let! isSame = compareReceipt context installPath location
  -  if isSame = false
  +  let! isSame = compareReceipt logger installPath location
  +
  +  if isSame
     then
  -    log("Installing " + installPath + "... ")
  +    logger.Success (installPath + " is already up-to-date. ")
  +  else
  +    logger.Info ("Installing " + installPath + "... ")
       let installFromGit url revision versions = async {
         let hint =
           versions
  
positive.code:       do! Files.deleteDirectoryIfExists installPath |> Async.Ignore
        do! Files.mkdirp installPath
        do! Archive.extractTo pathToCache installPath http.StripPrefix
      log ("Writing installation receipt for " + installPath + "... ")
      do! writeReceipt installPath location
      logSuccess ("Installed " + installPath)
    else
      logSuccess (installPath + " is already up-to-date")
  }
  
  let private generateBuckConfig (sourceExplorer : ISourceExplorer) (parents : PackageIdentifier list) lockedPackage packages (pathToCell : string) = async {
  
negative.code:     |> Map.add "buckaroo" buckarooSection
      |> Map.add "repositories" repositoriesSection
  
    do! Files.mkdirp (Path.Combine (root, ".buckconfig.d"))
    do! Files.writeFile (Path.Combine (root, ".buckconfig.d", ".buckconfig.buckaroo")) (BuckConfig.render config)
  }
  
  let task (context : Tasks.TaskContext) = async {
    let logger = createLogger context.Console
  
    logger.Info "Installing packages..."
  
    let! lock = Tasks.readLock
  
    do! installPackages context "." [] lock.Packages
    do! writeTopLevelFiles context "." lock
  
    logger.Success "The packages folder is now up-to-date. "
  
    return ()
  }
  