                     state.objectName = scanner.readLine()
                     scanner.moveToNextLine()
                     continue
-                } else if ObjLoader.isFace(m) {
+                }
+
+                if ObjLoader.isGroup(m) {
+                    if let s = buildShape() {
+                        shapes.append(s)
+                    }
+
+                    state = State()
+                    state.objectName = try scanner.readString()
+                    scanner.moveToNextLine()
+                    continue
+                }
+
+                if ObjLoader.isFace(m) {
                     if let indices = try scanner.readFace() {
                         state.faces.append(normalizeVertexIndices(indices))
                     }
 
                     scanner.moveToNextLine()
                     continue
-                } else {
-                    scanner.moveToNextLine()
-                    continue
-                }
+                }
+
+                if ObjLoader.isMaterialLibrary(m) {
+                    let filenames = try scanner.readTokens()
+                    try parseMaterialFiles(filenames)
+                    scanner.moveToNextLine()
+                    continue
+                }
+
+                if ObjLoader.isUseMaterial(m) {
+                    let materialName = try scanner.readString()
+
+                    guard let material = self.materialCache[materialName] else {
+                        throw ObjLoadingError.UnexpectedFileFormat(error: "Material \(materialName) referenced before it was definied")
+                    }
+
+                    state.material = material
+                    scanner.moveToNextLine()
+                    continue
+                }
+
+                scanner.moveToNextLine()
             }
 
-            if let s = buildShape(state.objectName, vertices: state.vertices, normals: state.normals, textureCoords: state.textureCoords, faces: state.faces) {
+            if let s = buildShape() {
                 shapes.append(s)
             }
             state = State()
-
-            running = false
         } catch let e {
-            running = false
             resetState()
             throw e
         }

        textureCoordCount = 0
    }

    private func buildShape(name: NSString?, vertices: [[Double]], normals: [[Double]], textureCoords: [[Double]], faces: [[VertexIndex]]) -> Shape? {
        if vertices.count == 0 && normals.count == 0 && textureCoords.count == 0 {
            return nil
        }


        let result =  Shape(name: (name as String?), vertices: vertices, normals: normals, textureCoords: textureCoords, faces: faces)
        vertexCount += vertices.count
        normalCount += normals.count
        textureCoordCount += textureCoords.count

        return result
    }

    private static let normalMarker = "vn"
    private static let textureCoordMarker = "vt"
    private static let objectMarker = "o".characterAtIndex(0)
    private static let groupMarker = "g".characterAtIndex(0)
    private static let faceMarker = "f".characterAtIndex(0)
    private static let materialLibraryMarker = "mtllib"
    private static let useMaterialMarker = "usemtl"

    private let scanner: ObjScanner
    private let basePath: NSString
    private var materialCache: [NSString: Material] = [:]

    private var state = State()
    private var vertexCount = 0
