     }
 
 
-    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")

        mainLoop: while !scanner.atEnd {
            //Scan normal text
            var fragment: NSString?
            let didScanFragment = scanner.scanUpToCharactersFromSet(singleQuoteDelimittedStringDelimiters, intoString:&fragment)
            if didScanFragment,
                let fragment = fragment as? String {
                    text.appendContentsOf(fragment)

        return mutableCharacterSet
        }()

    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.
