     }
 
 
-    private static let subScriptDelimiters = NSCharacterSet(charactersInString: "`'")
+    private static func componentsInPath(path: String) throws -> [Component] {
+        var components = [Component]()
+        try JSONPath.enumerateComponentsInPath(path) { component, componentIdx, stop in
+            components.append(component)
+        }
+        return components
+    }
+
+
+    public static func enumerateComponentsInPath(JSONPath: String, enumerator: (component: Component, componentIdx: Int, inout stop: Bool) throws -> Void) throws {
+
+        let scanner = NSScanner(string: JSONPath)
+        scanner.charactersToBeSkipped = nil //Don't skip whitespace!
+
+        var componentIdx = 0
+        repeat {
+
+            let component = try scanComponent(scanner)
+            //Call the enumerator
+            var stop = false
+            try enumerator(component: component, componentIdx: componentIdx, stop: &stop)
+            if stop { return }
+
+            //Prepare for next loop
+            componentIdx++
+
+        } while !scanner.atEnd
+
+        //Done without error
+    }
+
+
+    private static func scanComponent(scanner: NSScanner) throws -> Component {
+
+        if let component = try scanSubscriptComponent(scanner) {
+            return component
+        }
+
+        if let component = try scanIdentifierComponent(scanner) {
+            return component
+        }
+
+        throw ParsingError.ExpectedComponent
+    }
+
+
+    private static func scanSubscriptComponent(scanner: NSScanner) throws -> Component? {
+        let result: Component
+
+        //Is it subscript?
+        let isSubscript = scanner.scanString("[", intoString: nil)
+        guard isSubscript else {
+            return nil
+        }
+
+        //Scan the value
+        var idx: Int64 = 0
+        var text: String = ""
+        switch scanner {
+
+        case (_) where scanner.scanLongLong(&idx):
+            result = .Numeric(idx)
+
+        case (_) where scanner.scanString("self", intoString: nil):
+            result = .SelfReference
+
+        case (_) where try scanSingleQuoteDelimittedString(scanner, string: &text):
+            result = .Text(text)
+
+        default:
+            throw ParsingError.InvalidSubscriptValue
+        }
+
+        //Close the subscript
+        guard scanner.scanString("]", intoString: nil) else {
+            throw ParsingError.ExpectedEndOfSubscript
+        }
+
+        consumeOptionalTraillingDot(scanner)
+
+        return result
+    }
+
+
     private static let headCharacters = NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_")
     private static let bodyCharacters: NSCharacterSet = {
         let mutableCharacterSet = NSMutableCharacterSet(charactersInString: "0123456789")

        return mutableCharacterSet
        }()


    private static func componentsInPath(path: String) throws -> [Component] {
        var components = [Component]()
        try JSONPath.enumerateComponentsInPath(path) { component, componentIdx, stop in
            components.append(component)
        }
        return components
    }


    public static func enumerateComponentsInPath(JSONPath: String, enumerator: (component: Component, componentIdx: Int, inout stop: Bool) throws -> Void) throws {

        let scanner = NSScanner(string: JSONPath)
        scanner.charactersToBeSkipped = nil //Don't skip whitespace!

        var componentIdx = 0
        repeat {

            let component = try scanComponent(scanner)
            //Call the enumerator
            var stop = false
            try enumerator(component: component, componentIdx: componentIdx, stop: &stop)
            if stop { return }

            //Prepare for next loop
            componentIdx++

        } while !scanner.atEnd

        //Done without error
    }


    private static func scanComponent(scanner: NSScanner) throws -> Component {

        if let component = try scanSubscriptComponent(scanner) {
            return component
        }

        if let component = try scanIdentifierComponent(scanner) {
            return component
        }

        throw ParsingError.ExpectedComponent
    }


    private static func scanSubscriptComponent(scanner: NSScanner) throws -> Component? {
        let result: Component

        //Is it subscript?
        let isSubscript = scanner.scanString("[", intoString: nil)
        guard isSubscript else {
            return nil
        }

        //Scan the value
        var idx: Int64 = 0
        var text: String = ""
        switch scanner {

        case (_) where scanner.scanLongLong(&idx):
            result = .Numeric(idx)

        case (_) where scanner.scanString("self", intoString: nil):
            result = .SelfReference

        case (_) where try scanSingleQuoteDelimittedString(scanner, string: &text):
            result = .Text(text)

        default:
            throw ParsingError.InvalidSubscriptValue
        }

        //Close the subscript
        guard scanner.scanString("]", intoString: nil) else {
            throw ParsingError.ExpectedEndOfSubscript
        }

        consumeOptionalTraillingDot(scanner)

        return result
    }


    private static func scanIdentifierComponent(scanner: NSScanner) throws -> Component? {
        //Technically there are a lot more unicode code points that are acceptable, but we go for 99+% of JSON keys.
        //See on https://mathiasbynens.be/notes/javascript-properties.

    }


    private static let subScriptDelimiters = NSCharacterSet(charactersInString: "`'")

    private static func scanSingleQuoteDelimittedString(scanner: NSScanner, inout string: String) throws -> Bool {

