     }
 }
 
+private enum BlockType {
+    case all
+    case thirdParty
+}
+
 private class BlockRule {
-    fileprivate let regex: NSRegularExpression
-    fileprivate let domainExceptions: [NSRegularExpression]?
+    let regex: NSRegularExpression
+    let type: BlockType
+    let domainExceptions: [NSRegularExpression]?
 
-    init(regex: NSRegularExpression, domainExceptions: [NSRegularExpression]?) {
+    init(regex: NSRegularExpression, type: BlockType, domainExceptions: [NSRegularExpression]?) {
         self.regex = regex
+        self.type = type
         self.domainExceptions = domainExceptions
     }
 }

                    return try! NSRegularExpression(pattern: regex, options: [])
                }

                blockRules.append(BlockRule(regex: filterRegex, domainExceptions: domainExceptions))
            }
        }
    }

    func isBlocked(_ url: URL) -> Bool {
        guard let host = url.host else { return false }

        let absoluteString = url.absoluteString
        let range = NSRange(location: 0, length: absoluteString.characters.count)

        domainSearch: for rule in blockRules {
            // First, test the top-level filters to see if this URL might be blocked.
            if rule.regex.firstMatch(in: absoluteString, options: .anchored, range: range) != nil {
                // We matched, and there are no exceptions.
                guard let domainExceptions = rule.domainExceptions else {
                    return true

    }

    override func startLoading() {
        guard !ContentBlocker.blockList.isBlocked(request) else {
            let response = HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: nil, headerFields: ["Content-Length": "0"])
            client?.urlProtocol(self, didReceive: response!, cacheStoragePolicy: .notAllowed)
            client?.urlProtocolDidFinishLoading(self)
            return
        }
