         let places = database.getPlaceKeys(aroundPoint: location, withRadius: radius).andThen(upon: queue) { (placeKeyToLoc) -> Future<[DatabaseResult<Place>]> in
             var unfetchedPlaces = [String]()
             var fetchedPlaces = [Deferred<DatabaseResult<Place>>]()
-            self.placesLock.lock()
-            for placeKey in Array(placeKeyToLoc.keys) {
-                if let index = (self.places.index { (place) -> Bool in
-                    place.id == placeKey
-                }) {
-                    let place = self.places[index]
-                    fetchedPlaces.append(Deferred(filledWith: DatabaseResult.succeed(value: place)))
-                } else {
-                    unfetchedPlaces.append(placeKey)
-                }
-            }
-            self.placesLock.unlock()
-            // TODO: limit the number of place details we look up. X closest places?
-            // TODO: These should be ordered by display order
+            self.placesLock.withReadLock {
+                for placeKey in Array(placeKeyToLoc.keys) {
+                    if let index = (self.places.index { (place) -> Bool in
+                        place.id == placeKey
+                    }) {
+                        let place = self.places[index]
+                        fetchedPlaces.append(Deferred(filledWith: DatabaseResult.succeed(value: place)))
+                    } else {
+                        unfetchedPlaces.append(placeKey)
+                    }
+                }
+            }
             return (self.database.getPlaceDetails(fromKeys: unfetchedPlaces) + fetchedPlaces).allFilled()
         }
         return places

    }

    func sortPlaces(byLocation location: CLLocation) {
        self.placesLock.lock()
        let sortedPlaces = PlaceUtilities.sort(places: places, byDistanceFromLocation: location)
        self.places = sortedPlaces
        self.placesLock.unlock()
    }
}


extension PlacesProvider: PlaceDataSource {
    func nextPlace(forPlace place: Place) -> Place? {
        return self.placesLock.withReadLock {
            // if the place isn't in the list, make the first item in the list the next item
            guard let currentPlaceIndex = places.index(where: {$0 == place}) else {
                return places.count > 0 ? places[places.startIndex] : nil
            }

            guard currentPlaceIndex + 1 < places.endIndex else { return nil }

            return places[places.index(after: currentPlaceIndex)]
        }
    }

    func previousPlace(forPlace place: Place) -> Place? {
        return self.placesLock.withReadLock {
            guard let currentPlaceIndex = places.index(where: {$0 == place}),
                currentPlaceIndex > places.startIndex else { return nil }

            return places[places.index(before: currentPlaceIndex)]
        }
    }

    func numberOfPlaces() -> Int {
        return self.placesLock.withReadLock {
            return places.count
        }
    }

    func place(forIndex index: Int) throws -> Place {
        return try self.placesLock.withReadLock {
            guard index < places.endIndex,
                index >= places.startIndex else {
                    throw PlaceDataSourceError(message: "There is no place at index: \(index)")
            }

            return places[index]
        }
    }

    func index(forPlace place: Place) -> Int? {
        return self.placesLock.withReadLock {
            return places.index(of: place)
        }
    }

    func fetchPlace(placeKey: String, withEvent eventKey: String, callback: @escaping (Place?) -> ()) {
        self.placesLock.withReadLock {
            if let placeIndex = places.index(where: { $0.id == placeKey }) {
                let place = places[placeIndex]
                if place.events.contains(where: { $0.id == eventKey }) {
                    callback(place)
                }
                let eventProvider = EventsProvider()
                eventProvider.event(forKey: eventKey) { event in
                    guard let event = event else { return callback(nil) }
                    self.placesLock.withWriteLock {
                        place.events.append(event)
                    }
                    callback(place)
                }
            } else {
                self.place(withKey: placeKey, forEventWithKey: eventKey) { place in
                    callback(place)
                }
            }
        }
    }
