                 let value = try self.dictionary[key].orThrow(UnboxPathError.missingKey(key))
                 return try transform(value).orThrow(UnboxPathError.invalidValue(value, key))
             case .keyPath(let keyPath):
-                var currentMode = UnboxingMode.dictionary(self.dictionary)
+                var node: UnboxPathNode = self.dictionary
                 let components = keyPath.components(separatedBy: ".")
-                let lastKey = try components.last.orThrow(UnboxPathError.emptyKeyPath)
+                let lastKey = components.last
                 
-                try components.forEach { key in
-                    switch currentMode {
-                    case .dictionary(let dictionary):
-                        currentMode = try UnboxingMode(value: dictionary[key].orThrow(UnboxPathError.missingKey(key)))
-                    case .array(let array):
-                        guard let index = Int(key), index < array.count else {
-                            throw UnboxPathError.missingKey(key)
-                        }
-                        
-                        currentMode = UnboxingMode(value: array[index])
-                    case .value(let value):
-                        throw UnboxPathError.invalidValue(value, key)
+                for key in components {
+                    guard let nextValue = node.unboxPathValue(forKey: key) else {
+                        throw UnboxPathError.missingKey(key)
                     }
+                    
+                    if key == lastKey {
+                        return try transform(nextValue).orThrow(UnboxPathError.invalidValue(nextValue, key))
+                    }
+                    
+                    guard let nextNode = nextValue as? UnboxPathNode else {
+                        print(type(of: nextValue))
+                        throw UnboxPathError.invalidValue(nextValue, key)
+                    }
+                    
+                    node = nextNode
                 }
                 
-                return try transform(currentMode.value).orThrow(UnboxPathError.invalidValue(currentMode.value, lastKey))
+                throw UnboxPathError.emptyKeyPath
             }
         } catch {
             if let publicError = error as? UnboxError {

        }
    }
}

private extension Unboxer {
    func unbox<R>(path: UnboxPath, transform: UnboxTransform<R>) throws -> R {

    }
}

// MARK: - UnboxContainers

private struct UnboxContainer<T: Unboxable>: UnboxableWithContext {
