         var debugDescription: String {
             return "\(path)\n\(jayson)"
         }
+    }
+}
+
+extension JAYSON {
+    
+    public subscript (key: String) -> JAYSON? {
+        return (source as? [AnyHashable : Any])
+            .flatMap { $0[key] }
+            .map { JAYSON(source: $0, breadcrumb: Breadcrumb(jayson: self, key: key)) }
+    }
+    
+    public subscript (index: Int) -> JAYSON? {
+        return (source as? [Any])
+            .flatMap { $0[index] }
+            .map { JAYSON(source: $0, breadcrumb: Breadcrumb(jayson: self, index: index)) }
     }
 }
 

        if let data = source as? Data {
            try self.init(data: data)
        } else {
            self.init(source: source, breadcrumb: nil)
        }
    }
    
    init(data: Data) throws {
        let source = try JSONSerialization.jsonObject(with: data, options: [])
        self.init(source: source, breadcrumb: nil)
    }
    
    init(source: Any?, breadcrumb: Breadcrumb?) {
        self.source = source
        self.breadcrumb = breadcrumb
    }
    
    public subscript (key: String) -> JAYSON? {
        return (source as? [AnyHashable : Any])
            .flatMap { $0[key] }
            .map { JAYSON(source: $0, breadcrumb: Breadcrumb(jayson: self, key: key)) }
    }
    
    public subscript (index: Int) -> JAYSON? {
        return (source as? [Any])
            .flatMap { $0[index] }
            .map { JAYSON(source: $0, breadcrumb: Breadcrumb(jayson: self, index: index)) }
    }
    
    public func currentPath() -> String {

    case FailedToGetBool(Any, JAYSON)
    case FailedToGetNumber(Any, JAYSON)
    case FailedToGetArray(Any, JAYSON)
    case InvalidJSONObject
}

public struct JAYSON: CustomDebugStringConvertible {
