 
 import MapKit
 
-public struct Point {
-    let x: Double
-    let y: Double
-    
-    public init(_ x: Double, _ y: Double) {
-        self.x = x
-        self.y = y
-    }
-}
-
-public struct Size {
-    var xLength: Double
-    var yLength: Double
-    
-    public init(xLength: Double, yLength: Double) {
-        precondition(xLength >= 0, "xLength can not be negative")
-        precondition(yLength >= 0, "yLength can not be negative")
-        self.xLength = xLength
-        self.yLength = yLength
-    }
-    
-    var half: Size {
-        return Size(xLength: xLength / 2, yLength: yLength / 2)
-    }
-}
-
-public struct Rect {
-    // left top vertice
-    var origin: Point
-    var size: Size
-    
-    public init(origin: Point, size: Size) {
-        self.origin = origin
-        self.size = size
-    }
-    
-    var minX: Double {
-        return origin.x
-    }
-    
-    var minY: Double {
-        return origin.y
-    }
-    
-    var maxX: Double {
-        return origin.x + size.xLength
-    }
-    
-    var maxY: Double {
-        return origin.y + size.yLength
-    }
-    
-    func containts(point: Point) -> Bool {
-        return (minX <= point.x && point.x <= maxX) &&
-            (minY <= point.y && point.y <= maxY)
-    }
-    
-    var leftTopRect: Rect {
-        return Rect(origin: origin, size: size.half)
-    }
-    
-    var leftBottomRect: Rect {
-        return Rect(origin: Point(origin.x, origin.y + size.half.yLength), size: size.half)
-    }
-    
-    var rightTopRect: Rect {
-        return Rect(origin: Point(origin.x + size.half.xLength, origin.y), size: size.half)
-    }
-    
-    var rightBottomRect: Rect {
-        return Rect(origin: Point(origin.x + size.half.xLength, origin.y + size.half.yLength), size: size.half)
-    }
-    
-    func intersects(rect: Rect) -> Bool {
-        
-        func lineSegmentsIntersect(lStart: Double, lEnd: Double, rStart: Double, rEnd: Double) -> Bool {
-            return max(lStart, rStart) <= min(lEnd, rEnd)
-        }
-        // to intersect, both horizontal and vertical projections need to intersect
-        // horizontal
-        if !lineSegmentsIntersect(lStart: minX, lEnd: maxX, rStart: rect.minX, rEnd: rect.maxX) {
-            return false
-        }
-        
-        // vertical
-        return lineSegmentsIntersect(lStart: minY, lEnd: maxY, rStart: rect.minY, rEnd: rect.maxY)
-    }
-    
-}
-
-protocol PointsContainer {
-    func add(point: Point) -> Bool
-    func points(inRect rect: Rect) -> [Point]
+protocol AnnotationsContainer {
+    func add(_ annotation: MKAnnotation) -> Bool
+    func annotations(in rect: MKMapRect) -> [MKAnnotation]
 }
 
 class QuadTreeNode {

    }
    
    struct Children: Sequence {
        let leftTop: QuadTreeNode
        let leftBottom: QuadTreeNode
        let rightTop: QuadTreeNode
        let rightBottom: QuadTreeNode
        
        init(parentNode: QuadTreeNode) {
            leftTop = QuadTreeNode(rect: parentNode.rect.leftTopRect)
            leftBottom = QuadTreeNode(rect: parentNode.rect.leftBottomRect)
            rightTop = QuadTreeNode(rect: parentNode.rect.rightTopRect)
            rightBottom = QuadTreeNode(rect: parentNode.rect.rightBottomRect)
        }
        
        struct ChildrenIterator: IteratorProtocol {

            }
            
            mutating func next() -> QuadTreeNode? {
                defer { index += 1 }
                switch index {
                case 0: return children.northWest
                case 1: return children.northEast
                case 2: return children.southWest
                case 3: return children.southEast
                default: return nil
                }
            }
