             return SpectraXMLNodeType.VertexDescriptor.nodeParser(node, key: k, options: options)!
             }.inObjectScope(.None) // always return a new instance of the closure
         
+        parser.register(SpectraXMLNodeParser.self, name: SpectraXMLNodeType.Camera.rawValue) { (r, k: String, node: XMLElement, options: [String:Any]) in
+            return SpectraXMLNodeType.Camera.nodeParser(node, key: k, options: options)!
+            }.inObjectScope(.None) // always return a new instance of the closure
+        
+        parser.register(SpectraXMLNodeParser.self, name: SpectraXMLNodeType.PhysicalLensParams.rawValue) { (r, k: String, node: XMLElement, options: [String:Any]) in
+            return SpectraXMLNodeType.PhysicalLensParams.nodeParser(node, key: k, options: options)!
+            }.inObjectScope(.None) // always return a new instance of the closure
+        
+        parser.register(SpectraXMLNodeParser.self, name: SpectraXMLNodeType.PhysicalImagingSurfaceParams.rawValue) { (r, k: String, node: XMLElement, options: [String:Any]) in
+            return SpectraXMLNodeType.PhysicalImagingSurfaceParams.nodeParser(node, key: k, options: options)!
+            }.inObjectScope(.None) // always return a new instance of the closure
+        
 //        parser.register(SpectraXMLNodeParser.self, name: SpectraXMLNodeType.World.rawValue) { (r, k: String, node: XMLElement, options: [String: Any]) in
 //            return SpectraXMLNodeType.World.nodeParser(node, key: k, options: options)!
 //            }.inObjectScope(.None) // always return a new instance of the closure

        for child in xml!.root!.children {
            let (tag, key) = (child.tag!, child.attributes["key"])

            let nodeParser = self.parser.resolve(SpectraXMLNodeParser.self, arguments: (tag, key, child, options))!
            
            let result = nodeParser(container: container, node: child, key: key, options: options)
//            let mirror = Mirror(result)

            //TODO: use .dynamicType for meta type at run time
            // - nvm, "auto-injection" feature won't be in swinject until 2.0.0
            
            
            let resultKlass = SpectraXMLNodeType(rawValue: tag)!.nodeFinalType(parser)!
//            container.register(result.dynamicType, name: tag) { _ in
//                return result
//            }
            
            // TODO: use options to set ObjectScope (default to .Container?)
            

    case TextureSampler = "texture-sampler"
    case Light = "light"
    
    // TODO: reimplement nodeParser() once auto-injection is available in Swinject
    // - until then, I really can't resolve the type
    public func nodeParser(node: XMLElement, key: String, options: [String: Any] = [:]) -> SpectraXMLNodeParser? {
        
        //NOTE: nodeParser can't be used until either 
        // - (1) Swinject supports auto-injection
        // - (2) I can resolve the reflection issues with resolving a swinject container of arbitrary type
        //    - can i do this with func generics: func nodeParser<NodeType>(...) -> SpectraXMLNodeParser<NodeType>?
        
        switch self {
        case .VertexAttribute:
            return {(container, node, key, options) in
                let vertexAttr = SpectraXMLVertexAttributeNode().parse(container, elem: node, options: options)
