             if symbolProperties & UInt64(INDEXSTORE_SYMBOL_PROPERTY_UNITTEST.rawValue) == 0 {
                 return true
             }
+            if fn.symbol_get_kind(sym) != INDEXSTORE_SYMBOL_KIND_CLASS{
+                return true
+            }
+
+            let parentClassName = fn.symbol_get_name(sym).str
+            
+            let childClassNameRef = Ref("", api: inheritanceRef.api)
+            let childClassNamePointer = unsafeBitCast(Unmanaged.passUnretained(childClassNameRef), to: UnsafeMutableRawPointer.self)
+            _ = fn.occurrence_relations_apply_f(occ!, childClassNamePointer) { childClassNamePointer, relation in
+                guard let relation = relation else { return true }
+                let childClassNameRef = Unmanaged<Ref<String>>.fromOpaque(childClassNamePointer!).takeUnretainedValue()
+                let fn = childClassNameRef.api.fn
+
+                // Look for the base class.
+                if fn.symbol_relation_get_roles(relation) != UInt64(INDEXSTORE_SYMBOL_ROLE_REL_BASEOF.rawValue) {
+                    return true
+                }
+
+                let childClassNameSym = fn.symbol_relation_get_symbol(relation)
+                childClassNameRef.instance = fn.symbol_get_name(childClassNameSym).str
+                return true
+            }
+
+            if !childClassNameRef.instance.isEmpty {
+                inheritanceRef.instance[childClassNameRef.instance] = parentClassName
+            }
+
+            return true
+        }
+
+        // scan for methods
+
+        let testMethodsRef = Ref([String: [(name: String, async: Bool)]](), api: api)
+        let testMethodsPointer = unsafeBitCast(Unmanaged.passUnretained(testMethodsRef), to: UnsafeMutableRawPointer.self)
+
+        _ = self.api.fn.record_reader_occurrences_apply_f(recordReader, testMethodsPointer) { testMethodsPointer , occ -> Bool in
+            let testMethodsRef = Unmanaged<Ref<[String: [(name: String, async: Bool)]]>>.fromOpaque(testMethodsPointer!).takeUnretainedValue()
+            let fn = testMethodsRef.api.fn
+
+            // Get the symbol.
+            let sym = fn.occurrence_get_symbol(occ)
+            let symbolProperties = fn.symbol_get_properties(sym)
+            // We only care about symbols that are marked unit tests and are instance methods.
+            if symbolProperties & UInt64(INDEXSTORE_SYMBOL_PROPERTY_UNITTEST.rawValue) == 0 {
+                return true
+            }
             if fn.symbol_get_kind(sym) != INDEXSTORE_SYMBOL_KIND_INSTANCEMETHOD {
                 return true
             }
 
-            let className = Ref("", api: builder.api)
-            let ctx = unsafeBitCast(Unmanaged.passUnretained(className), to: UnsafeMutableRawPointer.self)
-
-            _ = fn.occurrence_relations_apply_f(occ!, ctx) { ctx, relation in
+            let classNameRef = Ref("", api: testMethodsRef.api)
+            let classNamePointer = unsafeBitCast(Unmanaged.passUnretained(classNameRef), to: UnsafeMutableRawPointer.self)
+
+            _ = fn.occurrence_relations_apply_f(occ!, classNamePointer) { classNamePointer, relation in
                 guard let relation = relation else { return true }
-                let className = Unmanaged<Ref<String>>.fromOpaque(ctx!).takeUnretainedValue()
-                let fn = className.api.fn
+                let classNameRef = Unmanaged<Ref<String>>.fromOpaque(classNamePointer!).takeUnretainedValue()
+                let fn = classNameRef.api.fn
 
                 // Look for the class.
                 if fn.symbol_relation_get_roles(relation) != UInt64(INDEXSTORE_SYMBOL_ROLE_REL_CHILDOF.rawValue) {
                     return true
                 }
 
-                let sym = fn.symbol_relation_get_symbol(relation)
-                className.instance = fn.symbol_get_name(sym).str
+                let classNameSym = fn.symbol_relation_get_symbol(relation)
+                classNameRef.instance = fn.symbol_get_name(classNameSym).str
                 return true
             }
 
-            if !className.instance.isEmpty {
+            if !classNameRef.instance.isEmpty {
                 let methodName = fn.symbol_get_name(sym).str
                 let isAsync = symbolProperties & UInt64(INDEXSTORE_SYMBOL_PROPERTY_SWIFT_ASYNC.rawValue) != 0
-                builder.instance.add(className: className.instance, method: TestCaseClass.TestMethod(name: methodName, isAsync: isAsync))
+                testMethodsRef.instance[classNameRef.instance, default: []].append((name: methodName, async: isAsync))
             }
 
             return true
         }
 
-        return builder.instance.build()
+        return (
+            inheritance: inheritanceRef.instance,
+            testMethods: testMethodsRef.instance
+        )
+
     }
 
     private func getRecords(unitReader: indexstore_unit_reader_t?) throws -> [String] {
         let builder = Ref([String](), api: api)
 
         let ctx = unsafeBitCast(Unmanaged.passUnretained(builder), to: UnsafeMutableRawPointer.self)
-        _ = fn.unit_reader_dependencies_apply_f(unitReader, ctx) { ctx , unit -> Bool in
+        _ = self.api.fn.unit_reader_dependencies_apply_f(unitReader, ctx) { ctx , unit -> Bool in
             let store = Unmanaged<Ref<[String]>>.fromOpaque(ctx!).takeUnretainedValue()
             let fn = store.api.fn
             if fn.unit_dependency_get_kind(unit) == INDEXSTORE_UNIT_DEPENDENCY_RECORD {

        return IndexStore(impl)
    }

    public func listTests(inObjectFile object: AbsolutePath) throws -> [TestCaseClass] {
        return try impl.listTests(inObjectFile: object)
    }

    private func unitName(object: AbsolutePath) -> String {
        let initialSize = 64
        var buf = UnsafeMutablePointer<CChar>.allocate(capacity: initialSize)
        let len = self.api.fn.store_get_unit_name_from_output_path(store, object.pathString, buf, initialSize)

        if len + 1 > initialSize {
            buf.deallocate()
            buf = UnsafeMutablePointer<CChar>.allocate(capacity: len + 1)
            _ = self.api.fn.store_get_unit_name_from_output_path(store, object.pathString, buf, len + 1)
        }

        defer {
