 
 fileprivate func scanChildren(_ item: FileItem, sorted: Bool = false) {
   let children = FileUtils.directDescendants(of: item.url).map(FileItem.init)
-  syncAddChildren {
+  synced {
     if sorted {
       item.children = children.sorted()
     } else {
       item.children = children
     }
+
+    item.childrenScanned = true
+    item.needsScanChildren = false
   }
-
-  item.childrenScanned = true
-  item.needsScanChildren = false
 }

    }

    let child = FileItem(childUrl)
    syncAddChildren { parent.children.append(child) }

    return child
  }

/// When at least this much of non-directory and visible files are scanned, they are emitted.
fileprivate let emitChunkSize = 1000
fileprivate let scanDispatchQueue = DispatchQueue.global(qos: .userInitiated)
fileprivate let lock = NSRecursiveLock()

fileprivate func synced<T>(_ fn: () -> T) -> T {
  lock.lock()
  defer { lock.unlock() }
  return fn()
}

fileprivate func fileItem(for pathComponents: [String], root: FileItem, create: Bool = true) -> FileItem? {
  return synced {
    pathComponents.dropFirst().reduce(root) { (resultItem, childName) -> FileItem? in
      guard let parent = resultItem else {
        return nil
      }

      return child(withName: childName, ofParent: parent, create: true)
    }
  }
}

fileprivate func fileItem(for url: URL, root: FileItem, create: Bool = true) -> FileItem? {
