     /// Optional parameter 'maxDistance' if you are not interested in neighbours beyond a specified distance
     ///
     /// - Complexity: O(N log N).
-    public func nearest(to element: Element, maxDistance: Double = Double.infinity) -> Element? {
+    public func nearest(to element: Element, maxDistance: Double = Double.infinity, condition: (Element) -> Bool = { _ in true }) -> Element? {
         guard !self.isEmpty else { return nil }
         
-        return nearest(to: element, bestValue: nil, bestDistance: maxDistance).bestValue
+        return nearest(to: element, bestValue: nil, bestDistance: maxDistance, condition: condition).bestValue
     }
     
-    fileprivate func nearest(to searchElement: Element, bestValue: Element?, bestDistance: Double) -> (bestValue: Element?, bestDistance: Double) {
+    fileprivate func nearest(to searchElement: Element, bestValue: Element?, bestDistance: Double, condition: (Element) -> Bool) -> (bestValue: Element?, bestDistance: Double) {
         switch self {
         case .leaf: break
-        case let .node(.leaf, value, _, .leaf):
+        case let .node(.leaf, value, _, .leaf) where condition(value):
             let currentDistance = value.squaredDistance(to: searchElement)
             if currentDistance < bestDistance { return (value, currentDistance) }
         case let .node(left, value, dim, right):

            
            //check the best estimate side
            let closerSubtree = isLeftOfValue ? left : right
            var (bestNewElement, bestNewDistance) = closerSubtree.nearest(to: searchElement, bestValue: bestValue, bestDistance: bestDistance)
            
            // if the bestDistance so far intersects the hyperplane at the other side of this value
            // there could be points in the other subtree
            if dimensionDifference*dimensionDifference < bestNewDistance {
                //check the nodes value
                if searchElement != value {
                    let currentDistance = value.squaredDistance(to: searchElement)
                    if currentDistance < bestNewDistance { (bestNewElement, bestNewDistance) = (value, currentDistance) }
                }
                
                let otherSubtree = isLeftOfValue ? right : left
                (bestNewElement, bestNewDistance) = otherSubtree.nearest(to: searchElement, bestValue: bestNewElement, bestDistance: bestNewDistance)
            }
            
            return (bestNewElement, bestNewDistance)

            
            //check the best estimate side
            let closerSubtree = isLeftOfValue ? left : right
            closerSubtree.nearestK(to: searchElement, bestValues: &bestValues, where: condition)

            if condition(value) {
                //check the nodes value
                let currentDistance = value.squaredDistance(to: searchElement)
                bestValues.append(value, distance: currentDistance)
            }

            //if the bestDistance so far intersects the hyperplane at the other side of this value
            //there could be points in the other subtree
            if dimensionDifference*dimensionDifference < bestValues.biggestDistance || !bestValues.full {
                let otherSubtree = isLeftOfValue ? right : left
                otherSubtree.nearestK(to: searchElement, bestValues: &bestValues, where: condition)
            }
        case .leaf: break
        }
