     }
     
     internal func booleanOperation(_ operation: BooleanPathOperation) -> Path {
-        // handle components that have no crossings
+        
+        // special cases for components which do not cross
+        let nonCrossingComponents1: [PathComponent] = self.list1.nonCrossingComponents()
+        let nonCrossingComponents2: [PathComponent] = self.list2.nonCrossingComponents()
+        
         func anyPointOnComponent(_ c: PathComponent) -> CGPoint {
             return c.curves[0].startingPoint
         }
         var pathComponents: [PathComponent] = []
         switch operation {
         case .removeCrossings:
-            pathComponents += nonCrossingComponents1 // TODO: hmm7
+            pathComponents += nonCrossingComponents1
         case .union:
             pathComponents += nonCrossingComponents1.filter { path2.contains(anyPointOnComponent($0)) == false }
             pathComponents += nonCrossingComponents2.filter { path1.contains(anyPointOnComponent($0)) == false }

            var isOnFirstCurve = true
            var v = start
            repeat {
                //                if isOnFirstCurve && unvisitedCrossings.contains(v) == false {
                //                    print("already visited this crossing! bailing out to avoid infinite loop! Needs debugging.")
                //                    break
                //                }
                let movingForwards = shouldMoveForwards(fromVertex: v, forOperation: operation, isOnFirstCurve: isOnFirstCurve)
                unvisitedCrossings = unvisitedCrossings.filter { $0 !== v }
                repeat {

        self.lists = p.subpaths.map { self.createListFor(component: $0) }
    }
    
    fileprivate func nonCrossingComponents() -> [PathComponent] {
        // returns the components of this path that do not cross the path passed as the argument to markEntryExit(_:)
        var result: [PathComponent] = []
        for i in 0..<lists.count {
            var hasCrossing = false
            self.forEachVertexInComponent(atIndex: i) { v in
                if v.isCrossing {
                    hasCrossing = true
                }
            }
            if hasCrossing == false {
                result.append(self.path.subpaths[i])
            }
        }
        return result
    }
    
    fileprivate func markEntryExit(_ path: Path, useRelativeWinding: Bool = false) {
        let fillRule: PathFillRule = useRelativeWinding ? .winding : .evenOdd

        for i in 0..<lists.count {
            // determine winding counts relative to the first vertex
            var relativeWindingCount = 0
            self.forEachVertexInComponent(atIndex: i) { v in
