diff --git a/src/main/java/com/android/tools/r8/androidapi/ApiDatabaseEntry.java b/src/main/java/com/android/tools/r8/androidapi/ApiDatabaseEntry.java
index ba19aa9..3c5c80e 100644
--- a/src/main/java/com/android/tools/r8/androidapi/ApiDatabaseEntry.java
+++ b/src/main/java/com/android/tools/r8/androidapi/ApiDatabaseEntry.java
@@ -11,9 +11,10 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexReference;
 import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.references.FieldReference;
+import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.utils.internal.ThrowingFunction;
-import com.android.tools.r8.utils.internal.exceptions.Unreachable;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -26,7 +27,7 @@
  * pooled in a constant pool (see {@link ConstantPoolEntry}).
  *
  * <p>Each entry can be serialized into a "unique descriptor" which is a compact byte array
- * containing identifiers and constant pool indices. See {@code
+ * containing identifiers and constant pool indices. See {@link
  * com.android.tools.r8.apimodel.AndroidApiHashingDatabaseBuilderGenerator} for the serialization
  * format.
  */
@@ -48,8 +49,6 @@
       ThrowingFunction<ConstantPoolEntry, Integer, IOException> constantPoolLookup)
       throws IOException;
 
-  public abstract ApiDatabaseEntry withHolder(DexType newHolder);
-
   @Override
   public final int hashCode() {
     return apiDatabaseHashCode();
@@ -85,6 +84,29 @@
         DexString.encodeToMutf8(reference.getFieldName()));
   }
 
+  public static ApiDatabaseEntry of(ClassReference reference) {
+    return new TypeEntry(DexString.encodeToMutf8(reference.getDescriptor()));
+  }
+
+  public static ApiDatabaseEntry of(MethodReference reference) {
+    byte[][] parameters = new byte[reference.getFormalTypes().size()][];
+    for (int i = 0; i < parameters.length; i++) {
+      parameters[i] = DexString.encodeToMutf8(reference.getFormalTypes().get(i).getDescriptor());
+    }
+    return new MethodEntry(
+        DexString.encodeToMutf8(reference.getHolderClass().getDescriptor()),
+        DexString.encodeToMutf8(reference.getMethodName()),
+        parameters,
+        DexString.encodeToMutf8(
+            reference.getReturnType() == null ? "V" : reference.getReturnType().getDescriptor()));
+  }
+
+  public static ApiDatabaseEntry of(FieldReference reference) {
+    return new FieldEntry(
+        DexString.encodeToMutf8(reference.getHolderClass().getDescriptor()),
+        DexString.encodeToMutf8(reference.getFieldName()));
+  }
+
   private static byte getFirstByteFromShort(int value) {
     assert isU2(value);
     return (byte) (value >> 8);
@@ -159,10 +181,6 @@
       };
     }
 
-    @Override
-    public ApiDatabaseEntry withHolder(DexType newHolder) {
-      throw new Unreachable();
-    }
 
     @Override
     public boolean equals(Object obj) {
@@ -223,10 +241,6 @@
       return baos.toByteArray();
     }
 
-    @Override
-    public ApiDatabaseEntry withHolder(DexType newHolder) {
-      throw new Unreachable();
-    }
 
     @Override
     public boolean equals(Object obj) {
@@ -279,10 +293,6 @@
       };
     }
 
-    @Override
-    public ApiDatabaseEntry withHolder(DexType newHolder) {
-      return new FieldEntry(newHolder.getDescriptor().content, this.name);
-    }
 
     @Override
     public boolean equals(Object obj) {
diff --git a/src/main/java/com/android/tools/r8/apimodel/AndroidApiHashingDatabaseBuilderGenerator.java b/src/main/java/com/android/tools/r8/apimodel/AndroidApiHashingDatabaseBuilderGenerator.java
new file mode 100644
index 0000000..8f889e8
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/apimodel/AndroidApiHashingDatabaseBuilderGenerator.java
@@ -0,0 +1,359 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.apimodel;
+
+import static com.android.tools.r8.androidapi.AndroidApiDataAccess.constantPoolHash;
+import static com.android.tools.r8.lightir.ByteUtils.isU2;
+import static com.android.tools.r8.lightir.ByteUtils.setBitAtIndex;
+import static com.android.tools.r8.utils.internal.MapUtils.ignoreKey;
+
+import com.android.tools.r8.androidapi.AndroidApiDataAccess;
+import com.android.tools.r8.androidapi.ApiDatabaseEntry;
+import com.android.tools.r8.androidapi.ApiDatabaseEntry.ConstantPoolEntry;
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.references.MethodReference;
+import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.internal.IntBox;
+import com.android.tools.r8.utils.internal.ThrowingBiConsumer;
+import com.android.tools.r8.utils.internal.collections.Pair;
+import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+public class AndroidApiHashingDatabaseBuilderGenerator {
+
+  public static class GenerationException extends Exception {
+    public GenerationException(String message) {
+      super(message);
+    }
+
+    public GenerationException(String message, Throwable cause) {
+      super(message, cause);
+    }
+  }
+
+  /** The returned map has hash-independent iteration. */
+  public static Map<ApiDatabaseEntry, AndroidApiLevel> generateEntries(
+      List<ParsedApiClass> apiClasses) throws GenerationException {
+    Map<ClassReference, ParsedApiClass> lookupMap = new HashMap<>();
+    Map<ApiDatabaseEntry, AndroidApiLevel> databaseEntries = new LinkedHashMap<>();
+
+    for (ParsedApiClass apiClass : apiClasses) {
+      lookupMap.put(apiClass.getClassReference(), apiClass);
+      databaseEntries.put(
+          ApiDatabaseEntry.of(apiClass.getClassReference()), apiClass.getApiLevel());
+    }
+
+    for (ParsedApiClass apiClass : apiClasses) {
+      computeAllReferencesInHierarchy(
+          lookupMap, apiClass.getClassReference(), apiClass, AndroidApiLevel.B, databaseEntries);
+    }
+
+    return databaseEntries;
+  }
+
+  /**
+   * This method will generate one single database file where the format is as follows (uX is X
+   * number of unsigned bytes):
+   *
+   * <pre>
+   * constant_pool_size: u4
+   * constant_pool:      [constant_pool_size * payload_entry]
+   * constant_pool_map:  [0..max_hash(ConstantPoolEntry) * payload_entry]
+   * api_map:            [0..max_hash(ApiDatabaseEntry) * payload_entry]
+   * payload             raw data.
+   *
+   * payload_entry: u4:relative_offset_from_payload_start_or_tagged_value + u2:length
+   * </pre>
+   *
+   * For hash_definitions and entries see {@link AndroidApiDataAccess}.
+   */
+  public static void writeEntries(
+      Map<ApiDatabaseEntry, AndroidApiLevel> databaseEntries, Path pathToApiLevels)
+      throws GenerationException {
+    try (FileOutputStream fileOutputStream = new FileOutputStream(pathToApiLevels.toFile())) {
+      DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
+      generateDatabase(databaseEntries, dataOutputStream);
+    } catch (IOException e) {
+      throw new GenerationException("Failed to write API database to " + pathToApiLevels, e);
+    }
+  }
+
+  private static class ConstantPool {
+
+    private final IntBox intBox = new IntBox(0);
+    private final Object2IntMap<ConstantPoolEntry> pool = new Object2IntLinkedOpenHashMap<>();
+
+    public int getOrAdd(ConstantPoolEntry entry) {
+      return pool.computeIfAbsent(entry, ignored -> intBox.getAndIncrement());
+    }
+
+    public void forEach(ThrowingBiConsumer<ConstantPoolEntry, Integer, IOException> consumer)
+        throws IOException {
+      for (var mapEntry : pool.object2IntEntrySet()) {
+        consumer.accept(mapEntry.getKey(), mapEntry.getIntValue());
+      }
+    }
+
+    public int size() {
+      return pool.size();
+    }
+  }
+
+  private static int setUniqueConstantPoolEntry(int id) {
+    return setBitAtIndex(id, 32);
+  }
+
+  private static void generateDatabase(
+      Map<ApiDatabaseEntry, AndroidApiLevel> databaseEntries, DataOutputStream outputStream)
+      throws GenerationException, IOException {
+    Int2ObjectMap<List<Pair<ApiDatabaseEntry, AndroidApiLevel>>> generationMap =
+        new Int2ObjectLinkedOpenHashMap<>();
+    ConstantPool constantPool = new ConstantPool();
+
+    int constantPoolHashMapSize = 1 << AndroidApiDataAccess.entrySizeInBitsForConstantPoolMap();
+    int apiHashMapSize = 1 << AndroidApiDataAccess.entrySizeInBitsForApiLevelMap();
+
+    for (Entry<ApiDatabaseEntry, AndroidApiLevel> entry : databaseEntries.entrySet()) {
+      int newCode = AndroidApiDataAccess.apiLevelHash(entry.getKey());
+      if (newCode < 0 || newCode > apiHashMapSize) {
+        throw new GenerationException("Hash code out of bounds: " + newCode);
+      }
+      generationMap
+          .computeIfAbsent(newCode, ignoreKey(ArrayList::new))
+          .add(Pair.create(entry.getKey(), entry.getValue()));
+    }
+
+    Set<String> uniqueHashes = new HashSet<>();
+    Int2ObjectMap<Pair<Integer, Integer>> offsetMap = new Int2ObjectLinkedOpenHashMap<>();
+    ByteArrayOutputStream payload = new ByteArrayOutputStream();
+
+    // Serialize api map into payload. This will also generate the entire needed constant pool.
+    for (Int2ObjectMap.Entry<List<Pair<ApiDatabaseEntry, AndroidApiLevel>>> entry :
+        generationMap.int2ObjectEntrySet()) {
+      int startingOffset = payload.size();
+      int length = serializeIntoPayload(entry.getValue(), payload, constantPool, uniqueHashes);
+      offsetMap.put(entry.getIntKey(), Pair.create(startingOffset, length));
+    }
+
+    // Write constant pool size <u4:size>.
+    outputStream.writeInt(constantPool.size());
+
+    // Write constant pool consisting of <u4:payload_offset><u2:length>.
+    if (outputStream.size() != AndroidApiDataAccess.constantPoolOffset()) {
+      throw new GenerationException(
+          "Unexpected constant pool offset: expected "
+              + AndroidApiDataAccess.constantPoolOffset()
+              + ", got "
+              + outputStream.size());
+    }
+    IntBox lastReadIndex = new IntBox(-1);
+    constantPool.forEach(
+        (entry, id) -> {
+          if (id <= lastReadIndex.getAndIncrement()) {
+            throw new IOException("Constant pool ID out of order");
+          }
+          outputStream.writeInt(payload.size());
+          outputStream.writeShort(entry.getLength());
+          entry.writeTo(payload);
+        });
+
+    // Serialize hash lookup table for constant pool.
+    Map<Integer, List<Integer>> constantPoolLookupTable = new HashMap<>();
+    constantPool.forEach(
+        (entry, id) -> {
+          int constantPoolHash = constantPoolHash(entry);
+          assert constantPoolHash >= 0 && constantPoolHash <= constantPoolHashMapSize;
+          constantPoolLookupTable
+              .computeIfAbsent(constantPoolHash, ignoreKey(ArrayList::new))
+              .add(id);
+        });
+
+    int[] constantPoolEntries = new int[constantPoolHashMapSize];
+    int[] constantPoolEntryLengths = new int[constantPoolHashMapSize];
+    for (Entry<Integer, List<Integer>> entry : constantPoolLookupTable.entrySet()) {
+      // Tag if we have a unique value.
+      if (entry.getValue().size() == 1) {
+        int id = entry.getValue().get(0);
+        constantPoolEntries[entry.getKey()] = setUniqueConstantPoolEntry(id);
+      } else {
+        constantPoolEntries[entry.getKey()] = payload.size();
+        ByteArrayOutputStream temp = new ByteArrayOutputStream();
+        for (Integer id : entry.getValue()) {
+          temp.write(intToShortEncodedByteArray(id));
+        }
+        payload.write(temp.toByteArray());
+        constantPoolEntryLengths[entry.getKey()] = temp.size();
+      }
+    }
+    // Write constant pool lookup entries consisting of <u4:payload_offset><u2:length>.
+    if (outputStream.size()
+        != AndroidApiDataAccess.constantPoolHashMapOffset(constantPool.size())) {
+      throw new GenerationException("Unexpected constant pool hash map offset");
+    }
+    for (int i = 0; i < constantPoolEntries.length; i++) {
+      outputStream.writeInt(constantPoolEntries[i]);
+      outputStream.writeShort(constantPoolEntryLengths[i]);
+    }
+
+    int[] apiOffsets = new int[apiHashMapSize];
+    int[] apiOffsetLengths = new int[apiHashMapSize];
+    for (Int2ObjectMap.Entry<Pair<Integer, Integer>> hashIndexAndOffset :
+        offsetMap.int2ObjectEntrySet()) {
+      if (apiOffsets[hashIndexAndOffset.getIntKey()] != 0) {
+        throw new GenerationException(
+            "Hash collision in API map at index " + hashIndexAndOffset.getIntKey());
+      }
+      Pair<Integer, Integer> value = hashIndexAndOffset.getValue();
+      int offset = value.getFirst();
+      int length = value.getSecond();
+      apiOffsets[hashIndexAndOffset.getKey()] = offset;
+      apiOffsetLengths[hashIndexAndOffset.getKey()] = length;
+    }
+
+    // Write api lookup entries consisting of <u4:payload_offset><u2:length>.
+    if (outputStream.size() != AndroidApiDataAccess.apiLevelHashMapOffset(constantPool.size())) {
+      throw new GenerationException("Unexpected api level hash map offset");
+    }
+    for (int i = 0; i < apiOffsets.length; i++) {
+      outputStream.writeInt(apiOffsets[i]);
+      outputStream.writeShort(apiOffsetLengths[i]);
+    }
+
+    // Write the payload.
+    outputStream.write(payload.toByteArray());
+  }
+
+  /** This will serialize a collection of DexReferences and apis into a byte stream. */
+  private static int serializeIntoPayload(
+      List<Pair<ApiDatabaseEntry, AndroidApiLevel>> pairs,
+      ByteArrayOutputStream payload,
+      ConstantPool constantPool,
+      Set<String> seen)
+      throws GenerationException, IOException {
+    ByteArrayOutputStream temp = new ByteArrayOutputStream();
+    for (Pair<ApiDatabaseEntry, AndroidApiLevel> pair : pairs) {
+      byte[] uniqueDescriptorForReference =
+          pair.getFirst().getUniqueDescriptor(constantPool::getOrAdd);
+      if (uniqueDescriptorForReference == ApiDatabaseEntry.getNonExistingDescriptor()) {
+        throw new GenerationException("Reference descriptor does not exist: " + pair.getFirst());
+      }
+      if (!seen.add(Arrays.toString(uniqueDescriptorForReference))) {
+        throw new GenerationException(
+            "Duplicate reference descriptor in payload: " + pair.getFirst());
+      }
+      temp.write(intToShortEncodedByteArray(uniqueDescriptorForReference.length));
+      temp.write(uniqueDescriptorForReference);
+      if (pair.getSecond() == AndroidApiLevel.MAIN
+          || pair.getSecond() == AndroidApiLevel.EXTENSION) {
+        throw new GenerationException("Invalid API level for database entry: " + pair.getSecond());
+      }
+      temp.write(pair.getSecond().serializeAsByte());
+    }
+    byte[] tempArray = temp.toByteArray();
+    payload.write(tempArray);
+    return tempArray.length;
+  }
+
+  public static byte[] intToShortEncodedByteArray(int value) {
+    assert isU2(value);
+    byte[] bytes = new byte[2];
+    bytes[0] = (byte) (value >> 8);
+    bytes[1] = (byte) value;
+    return bytes;
+  }
+
+  private static final String OBJECT_DESCRIPTOR = "Ljava/lang/Object;";
+
+  private static void computeAllReferencesInHierarchy(
+      Map<ClassReference, ParsedApiClass> lookupMap,
+      ClassReference holder,
+      ParsedApiClass apiClass,
+      AndroidApiLevel linkLevel,
+      Map<ApiDatabaseEntry, AndroidApiLevel> databaseEntries)
+      throws GenerationException {
+    if (!apiClass.getClassReference().getDescriptor().equals(OBJECT_DESCRIPTOR)) {
+      apiClass.forEachMethod(
+          (methodReference, apiLevel) -> {
+            MethodReference methodWithNewHolder =
+                Reference.method(
+                    holder,
+                    methodReference.getMethodName(),
+                    methodReference.getFormalTypes(),
+                    methodReference.getReturnType());
+            addIfNewOrApiLevelIsLower(
+                linkLevel, databaseEntries, apiLevel, ApiDatabaseEntry.of(methodWithNewHolder));
+          });
+      apiClass.forEachField(
+          (fieldReference, apiLevel) -> {
+            FieldTypelessReference fieldWithNewHolder =
+                new FieldTypelessReference(holder, fieldReference.getFieldName());
+            addIfNewOrApiLevelIsLower(
+                linkLevel, databaseEntries, apiLevel, ApiDatabaseEntry.of(fieldWithNewHolder));
+          });
+
+      apiClass.forEachSupertypeThrowing(
+          (superType, apiLevel) -> {
+            ParsedApiClass superApiClass = lookupMap.get(superType);
+            if (superApiClass == null) {
+              if (!superType.getDescriptor().equals(OBJECT_DESCRIPTOR)) {
+                throw new GenerationException(
+                    "Supertype "
+                        + superType.getTypeName()
+                        + " of "
+                        + apiClass.getClassReference().getTypeName()
+                        + " is missing from the parsed API classes.");
+              }
+            } else {
+              computeAllReferencesInHierarchy(
+                  lookupMap, holder, superApiClass, linkLevel.max(apiLevel), databaseEntries);
+            }
+          });
+
+      apiClass.forEachInterfaceThrowing(
+          (interfaceReference, apiLevel) -> {
+            ParsedApiClass interfaceApiClass = lookupMap.get(interfaceReference);
+            if (interfaceApiClass == null) {
+              throw new GenerationException(
+                  "Interface "
+                      + interfaceReference.getTypeName()
+                      + " implemented by "
+                      + apiClass.getClassReference().getTypeName()
+                      + " is missing from the parsed API classes.");
+            }
+            computeAllReferencesInHierarchy(
+                lookupMap, holder, interfaceApiClass, linkLevel.max(apiLevel), databaseEntries);
+          });
+    }
+  }
+
+  private static void addIfNewOrApiLevelIsLower(
+      AndroidApiLevel linkLevel,
+      Map<ApiDatabaseEntry, AndroidApiLevel> additionMap,
+      AndroidApiLevel apiLevel,
+      ApiDatabaseEntry member) {
+    AndroidApiLevel currentApiLevel = apiLevel.max(linkLevel);
+    AndroidApiLevel existingApiLevel = additionMap.get(member);
+    if (existingApiLevel == null || currentApiLevel.isLessThanOrEqualTo(existingApiLevel)) {
+      additionMap.put(member, currentApiLevel);
+    }
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/apimodel/ParsedApiClass.java b/src/main/java/com/android/tools/r8/apimodel/ParsedApiClass.java
index 14ba584..2a32fda 100644
--- a/src/main/java/com/android/tools/r8/apimodel/ParsedApiClass.java
+++ b/src/main/java/com/android/tools/r8/apimodel/ParsedApiClass.java
@@ -7,6 +7,7 @@
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.internal.ThrowingBiConsumer;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.function.BiConsumer;
@@ -47,6 +48,14 @@
     supertypes.forEach(consumer);
   }
 
+  /** Visited in insertion order. */
+  public <E extends Throwable> void forEachSupertypeThrowing(
+      ThrowingBiConsumer<ClassReference, AndroidApiLevel, E> consumer) throws E {
+    for (Map.Entry<ClassReference, AndroidApiLevel> entry : supertypes.entrySet()) {
+      consumer.accept(entry.getKey(), entry.getValue());
+    }
+  }
+
   public void registerInterface(ClassReference reference, AndroidApiLevel introApiLevel) {
     assert !interfaces.containsKey(reference) : reference + " is already registered";
     interfaces.put(reference, introApiLevel);
@@ -61,6 +70,14 @@
     interfaces.forEach(consumer);
   }
 
+  /** Visited in insertion order. */
+  public <E extends Throwable> void forEachInterfaceThrowing(
+      ThrowingBiConsumer<ClassReference, AndroidApiLevel, E> consumer) throws E {
+    for (Map.Entry<ClassReference, AndroidApiLevel> entry : interfaces.entrySet()) {
+      consumer.accept(entry.getKey(), entry.getValue());
+    }
+  }
+
   public void registerMethod(MethodReference reference, AndroidApiLevel introApiLevel) {
     assert !methods.containsKey(reference) : reference + " is already registered";
     methods.put(reference, introApiLevel);
diff --git a/src/test/java/com/android/tools/r8/apimodel/AndroidApiHashingDatabaseBuilderGenerator.java b/src/test/java/com/android/tools/r8/apimodel/AndroidApiHashingDatabaseBuilderGenerator.java
deleted file mode 100644
index 55b096b..0000000
--- a/src/test/java/com/android/tools/r8/apimodel/AndroidApiHashingDatabaseBuilderGenerator.java
+++ /dev/null
@@ -1,464 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.apimodel;
-
-import static com.android.tools.r8.androidapi.AndroidApiDataAccess.constantPoolHash;
-import static com.android.tools.r8.lightir.ByteUtils.isU2;
-import static com.android.tools.r8.lightir.ByteUtils.setBitAtIndex;
-import static com.android.tools.r8.utils.internal.MapUtils.ignoreKey;
-import static org.junit.Assert.assertEquals;
-
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.androidapi.AndroidApiDataAccess;
-import com.android.tools.r8.androidapi.ApiDatabaseEntry;
-import com.android.tools.r8.androidapi.ApiDatabaseEntry.ConstantPoolEntry;
-import com.android.tools.r8.androidapi.GenerateCovariantReturnTypeMethodsTest.CovariantMethodsInJarResult;
-import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexLibraryClass;
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.internal.IntBox;
-import com.android.tools.r8.utils.internal.ThrowingBiConsumer;
-import com.android.tools.r8.utils.internal.collections.Pair;
-import com.android.tools.r8.utils.internal.exceptions.Unreachable;
-import com.android.tools.r8.utils.timing.Timing;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-public class AndroidApiHashingDatabaseBuilderGenerator extends TestBase {
-
-  /**
-   * Generate the information needed for looking up api level of references in the android.jar. This
-   * method will generate one single database file where the format is as follows (uX is X number of
-   * unsigned bytes):
-   *
-   * <pre>
-   * constant_pool_size: u4
-   * constant_pool:      [constant_pool_size * payload_entry]
-   * constant_pool_map:  [0..max_hash(ConstantPoolEntry) * payload_entry]
-   * api_map:            [0..max_hash(ApiDatabaseEntry) * payload_entry]
-   * payload             raw data.
-   *
-   * payload_entry: u4:relative_offset_from_payload_start_or_tagged_value + u2:length
-   * </pre>
-   *
-   * For hash_definitions and entries see {@code AndroidApiDataAccess}.
-   */
-  public static void generate(
-      List<ParsedApiClass> apiClasses, Path pathToApiLevels, AndroidApiLevel androidJarApiLevel)
-      throws Exception {
-    Map<ClassReference, Map<DexMethod, AndroidApiLevel>> methodMap = new HashMap<>();
-    Map<ClassReference, Map<FieldTypelessReference, AndroidApiLevel>> fieldMap = new HashMap<>();
-    Map<ClassReference, ParsedApiClass> lookupMap = new HashMap<>();
-
-    Map<ApiDatabaseEntry, AndroidApiLevel> databaseEntries = new HashMap<>();
-
-    Path androidJar = ToolHelper.getAndroidJar(androidJarApiLevel);
-    AndroidApp androidApp =
-        AndroidApp.builder()
-            .addLibraryFile(androidJar)
-            .disableAndroidJarHiddenClassExtension()
-            .build();
-    AppView<AppInfoWithClassHierarchy> appView =
-        computeAppViewWithClassHierarchy(androidApp, Timing.empty());
-    DexItemFactory factory = appView.dexItemFactory();
-
-    CovariantMethodsInJarResult covariantMethodsInJar = CovariantMethodsInJarResult.create();
-
-    for (ParsedApiClass apiClass : apiClasses) {
-      Map<DexMethod, AndroidApiLevel> methodsForApiClass = new HashMap<>();
-      apiClass.forEachMethod(
-          (method, apiLevel) -> methodsForApiClass.put(factory.createMethod(method), apiLevel));
-      covariantMethodsInJar.visitCovariantMethodsForHolder(
-          apiClass.getClassReference(),
-          methodReferenceWithApiLevel -> {
-            DexMethod method =
-                factory.createMethod(methodReferenceWithApiLevel.getMethodReference());
-            if (!methodsForApiClass.containsKey(method)) {
-              apiClass.registerMethod(
-                  methodReferenceWithApiLevel.getMethodReference(),
-                  methodReferenceWithApiLevel.getApiLevel());
-              methodsForApiClass.put(method, methodReferenceWithApiLevel.getApiLevel());
-            }
-          });
-      Map<FieldTypelessReference, AndroidApiLevel> fieldsForApiClass = new HashMap<>();
-      apiClass.forEachField(fieldsForApiClass::put);
-      methodMap.put(apiClass.getClassReference(), methodsForApiClass);
-      fieldMap.put(apiClass.getClassReference(), fieldsForApiClass);
-      lookupMap.put(apiClass.getClassReference(), apiClass);
-
-      databaseEntries.put(
-          ApiDatabaseEntry.of(factory.createType(apiClass.getClassReference().getDescriptor())),
-          apiClass.getApiLevel());
-    }
-
-    for (ParsedApiClass apiClass : apiClasses) {
-      computeAllReferencesInHierarchy(
-          lookupMap,
-          factory,
-          factory.createType(apiClass.getClassReference().getDescriptor()),
-          apiClass,
-          AndroidApiLevel.B,
-          databaseEntries);
-    }
-
-    assert ensureAllPublicMethodsAreMapped(
-        appView, lookupMap, methodMap, fieldMap, databaseEntries, androidJarApiLevel, androidJar);
-
-    try (FileOutputStream fileOutputStream = new FileOutputStream(pathToApiLevels.toFile())) {
-      DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
-      generateDatabase(databaseEntries, dataOutputStream);
-    }
-  }
-
-  private static boolean ensureAllPublicMethodsAreMapped(
-      AppView<AppInfoWithClassHierarchy> appView,
-      Map<ClassReference, ParsedApiClass> lookupMap,
-      Map<ClassReference, Map<DexMethod, AndroidApiLevel>> methodMap,
-      Map<ClassReference, Map<FieldTypelessReference, AndroidApiLevel>> fieldMap,
-      Map<ApiDatabaseEntry, AndroidApiLevel> databaseEntries,
-      AndroidApiLevel apiLevel,
-      Path androidJar) {
-    Map<DexType, String> missingMemberInformation = new IdentityHashMap<>();
-    DexItemFactory factory = appView.dexItemFactory();
-    for (DexLibraryClass clazz : appView.app().asDirect().libraryClasses()) {
-      ParsedApiClass parsedApiClass = lookupMap.get(clazz.getClassReference());
-      if (parsedApiClass == null) {
-        if (clazz.isPublic()) {
-          missingMemberInformation.put(clazz.getType(), "Could not be found in " + androidJar);
-        }
-        continue;
-      }
-      StringBuilder classBuilder = new StringBuilder();
-      Map<FieldTypelessReference, AndroidApiLevel> fieldMapForClass =
-          fieldMap.get(clazz.getClassReference());
-      assert fieldMapForClass != null;
-      clazz.forEachClassField(
-          field -> {
-            if (field.getAccessFlags().isPublic()
-                && databaseEntries.get(ApiDatabaseEntry.of(field.getReference())) == null
-                && !field.toSourceString().contains("this$0")) {
-              classBuilder.append("  ").append(field).append(" is missing\n");
-            }
-          });
-      Map<DexMethod, AndroidApiLevel> methodMapForClass = methodMap.get(clazz.getClassReference());
-      assert methodMapForClass != null;
-      clazz.forEachClassMethod(
-          method -> {
-            if (method.getAccessFlags().isPublic()
-                && databaseEntries.get(ApiDatabaseEntry.of(method.getReference())) == null
-                && !factory.objectMembers.isObjectMember(method.getReference())) {
-              classBuilder.append("  ").append(method).append(" is missing\n");
-            }
-          });
-      if (classBuilder.length() > 0) {
-        missingMemberInformation.put(clazz.getType(), classBuilder.toString());
-      }
-    }
-
-    Set<DexType> expectedMissingMembers = new HashSet<>();
-    // api-versions.xml do not encode all members of StringBuffers and StringBuilders, check that we
-    // only have missing definitions for those two classes.
-    expectedMissingMembers.add(factory.stringBufferType);
-    expectedMissingMembers.add(factory.stringBuilderType);
-    // TODO(b/231126636): api-versions.xml has missing definitions for the below classes.
-    expectedMissingMembers.add(
-        factory.createType("Ljava/util/concurrent/ConcurrentHashMap$KeySetView;"));
-    expectedMissingMembers.add(factory.createType("Ljava/time/chrono/ThaiBuddhistDate;"));
-    expectedMissingMembers.add(factory.createType("Ljava/time/chrono/HijrahDate;"));
-    expectedMissingMembers.add(factory.createType("Ljava/time/chrono/JapaneseDate;"));
-    expectedMissingMembers.add(factory.createType("Ljava/time/chrono/MinguoDate;"));
-    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcV;"));
-    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/IsoDep;"));
-    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/MifareUltralight;"));
-    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/MifareClassic;"));
-    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NdefFormatable;"));
-    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcA;"));
-    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcBarcode;"));
-    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcF;"));
-    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcB;"));
-    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/Ndef;"));
-    expectedMissingMembers.add(factory.createType("Landroid/webkit/CookieSyncManager;"));
-    if (apiLevel.isLessThan(AndroidApiLevel.BAKLAVA_1)) {
-      expectedMissingMembers.add(
-          factory.createType("Landroid/adservices/adselection/AdSelectionOutcome;"));
-      expectedMissingMembers.add(
-          factory.createType("Landroid/adservices/adselection/ReportEventRequest;"));
-      expectedMissingMembers.add(
-          factory.createType(
-              "Landroid/adservices/ondevicepersonalization/FederatedComputeScheduleRequest;"));
-      expectedMissingMembers.add(
-          factory.createType(
-              "Landroid/adservices/ondevicepersonalization/FederatedComputeScheduleResponse;"));
-      expectedMissingMembers.add(
-          factory.createType(
-              "Landroid/adservices/ondevicepersonalization/FederatedComputeScheduler;"));
-      expectedMissingMembers.add(
-          factory.createType("Landroid/adservices/ondevicepersonalization/InferenceInput;"));
-      expectedMissingMembers.add(
-          factory.createType(
-              "Landroid/adservices/ondevicepersonalization/InferenceInput$Builder;"));
-      expectedMissingMembers.add(
-          factory.createType("Landroid/adservices/ondevicepersonalization/InferenceInput$Params;"));
-      expectedMissingMembers.add(
-          factory.createType("Landroid/adservices/ondevicepersonalization/InferenceOutput;"));
-      expectedMissingMembers.add(
-          factory.createType(
-              "Landroid/adservices/ondevicepersonalization/InferenceOutput$Builder;"));
-      expectedMissingMembers.add(
-          factory.createType(
-              "Landroid/adservices/ondevicepersonalization/OnDevicePersonalizationManager;"));
-    }
-    assertEquals(
-        expectedMissingMembers.stream()
-                .map(DexType::toDescriptorString)
-                .sorted()
-                .collect(Collectors.joining("\n"))
-            + "\n---\n"
-            + missingMemberInformation.keySet().stream()
-                .map(DexType::toDescriptorString)
-                .sorted()
-                .collect(Collectors.joining("\n")),
-        expectedMissingMembers,
-        missingMemberInformation.keySet());
-    return true;
-  }
-
-  private static class ConstantPool {
-
-    private final IntBox intBox = new IntBox(0);
-    private final Map<ConstantPoolEntry, Integer> pool = new java.util.LinkedHashMap<>();
-
-    public int getOrAdd(ConstantPoolEntry entry) {
-      return pool.computeIfAbsent(entry, ignored -> intBox.getAndIncrement());
-    }
-
-    public void forEach(ThrowingBiConsumer<ConstantPoolEntry, Integer, IOException> consumer)
-        throws IOException {
-      for (Entry<ConstantPoolEntry, Integer> entry : pool.entrySet()) {
-        consumer.accept(entry.getKey(), entry.getValue());
-      }
-    }
-
-    public int size() {
-      return pool.size();
-    }
-  }
-
-  private static int setUniqueConstantPoolEntry(int id) {
-    return setBitAtIndex(id, 32);
-  }
-
-  public static void generateDatabase(
-      Map<ApiDatabaseEntry, AndroidApiLevel> databaseEntries, DataOutputStream outputStream)
-      throws Exception {
-    Map<Integer, List<Pair<ApiDatabaseEntry, AndroidApiLevel>>> generationMap = new HashMap<>();
-    ConstantPool constantPool = new ConstantPool();
-
-    int constantPoolHashMapSize = 1 << AndroidApiDataAccess.entrySizeInBitsForConstantPoolMap();
-    int apiHashMapSize = 1 << AndroidApiDataAccess.entrySizeInBitsForApiLevelMap();
-
-    for (Entry<ApiDatabaseEntry, AndroidApiLevel> entry : databaseEntries.entrySet()) {
-      int newCode = AndroidApiDataAccess.apiLevelHash(entry.getKey());
-      assert newCode >= 0 && newCode <= apiHashMapSize;
-      generationMap
-          .computeIfAbsent(newCode, ignoreKey(ArrayList::new))
-          .add(Pair.create(entry.getKey(), entry.getValue()));
-    }
-
-    Set<String> uniqueHashes = new HashSet<>();
-    Map<Integer, Pair<Integer, Integer>> offsetMap = new HashMap<>();
-    ByteArrayOutputStream payload = new ByteArrayOutputStream();
-
-    // Serialize api map into payload. This will also generate the entire needed constant pool.
-    for (Entry<Integer, List<Pair<ApiDatabaseEntry, AndroidApiLevel>>> entry :
-        generationMap.entrySet()) {
-      int startingOffset = payload.size();
-      int length = serializeIntoPayload(entry.getValue(), payload, constantPool, uniqueHashes);
-      offsetMap.put(entry.getKey(), Pair.create(startingOffset, length));
-    }
-
-    // Write constant pool size <u4:size>.
-    outputStream.writeInt(constantPool.size());
-
-    // Write constant pool consisting of <u4:payload_offset><u2:length>.
-    assertEquals(AndroidApiDataAccess.constantPoolOffset(), outputStream.size());
-    IntBox lastReadIndex = new IntBox(-1);
-    constantPool.forEach(
-        (entry, id) -> {
-          assert id > lastReadIndex.getAndIncrement();
-          outputStream.writeInt(payload.size());
-          outputStream.writeShort(entry.getLength());
-          entry.writeTo(payload);
-        });
-
-    // Serialize hash lookup table for constant pool.
-    Map<Integer, List<Integer>> constantPoolLookupTable = new HashMap<>();
-    constantPool.forEach(
-        (entry, id) -> {
-          int constantPoolHash = constantPoolHash(entry);
-          assert constantPoolHash >= 0 && constantPoolHash <= constantPoolHashMapSize;
-          constantPoolLookupTable
-              .computeIfAbsent(constantPoolHash, ignoreKey(ArrayList::new))
-              .add(id);
-        });
-
-    int[] constantPoolEntries = new int[constantPoolHashMapSize];
-    int[] constantPoolEntryLengths = new int[constantPoolHashMapSize];
-    for (Entry<Integer, List<Integer>> entry : constantPoolLookupTable.entrySet()) {
-      // Tag if we have a unique value
-      if (entry.getValue().size() == 1) {
-        int id = entry.getValue().get(0);
-        constantPoolEntries[entry.getKey()] = setUniqueConstantPoolEntry(id);
-      } else {
-        constantPoolEntries[entry.getKey()] = payload.size();
-        ByteArrayOutputStream temp = new ByteArrayOutputStream();
-        for (Integer id : entry.getValue()) {
-          temp.write(intToShortEncodedByteArray(id));
-        }
-        payload.write(temp.toByteArray());
-        constantPoolEntryLengths[entry.getKey()] = temp.size();
-      }
-    }
-    // Write constant pool lookup entries consisting of <u4:payload_offset><u2:length>
-    assertEquals(
-        AndroidApiDataAccess.constantPoolHashMapOffset(constantPool.size()), outputStream.size());
-    for (int i = 0; i < constantPoolEntries.length; i++) {
-      outputStream.writeInt(constantPoolEntries[i]);
-      outputStream.writeShort(constantPoolEntryLengths[i]);
-    }
-
-    int[] apiOffsets = new int[apiHashMapSize];
-    int[] apiOffsetLengths = new int[apiHashMapSize];
-    for (Entry<Integer, Pair<Integer, Integer>> hashIndexAndOffset : offsetMap.entrySet()) {
-      assert apiOffsets[hashIndexAndOffset.getKey()] == 0;
-      Pair<Integer, Integer> value = hashIndexAndOffset.getValue();
-      int offset = value.getFirst();
-      int length = value.getSecond();
-      apiOffsets[hashIndexAndOffset.getKey()] = offset;
-      apiOffsetLengths[hashIndexAndOffset.getKey()] = length;
-    }
-
-    // Write api lookup entries consisting of <u4:payload_offset><u2:length>
-    assertEquals(
-        AndroidApiDataAccess.apiLevelHashMapOffset(constantPool.size()), outputStream.size());
-    for (int i = 0; i < apiOffsets.length; i++) {
-      outputStream.writeInt(apiOffsets[i]);
-      outputStream.writeShort(apiOffsetLengths[i]);
-    }
-
-    // Write the payload.
-    outputStream.write(payload.toByteArray());
-  }
-
-  /** This will serialize a collection of DexReferences and apis into a byte stream. */
-  private static int serializeIntoPayload(
-      List<Pair<ApiDatabaseEntry, AndroidApiLevel>> pairs,
-      ByteArrayOutputStream payload,
-      ConstantPool constantPool,
-      Set<String> seen)
-      throws IOException {
-    ByteArrayOutputStream temp = new ByteArrayOutputStream();
-    for (Pair<ApiDatabaseEntry, AndroidApiLevel> pair : pairs) {
-      byte[] uniqueDescriptorForReference =
-          pair.getFirst().getUniqueDescriptor(constantPool::getOrAdd);
-      assert uniqueDescriptorForReference != ApiDatabaseEntry.getNonExistingDescriptor();
-      if (!seen.add(Arrays.toString(uniqueDescriptorForReference))) {
-        throw new Unreachable("Hash is not unique");
-      }
-      temp.write(intToShortEncodedByteArray(uniqueDescriptorForReference.length));
-      temp.write(uniqueDescriptorForReference);
-      assert pair.getSecond() != AndroidApiLevel.MAIN
-          && pair.getSecond() != AndroidApiLevel.EXTENSION;
-      temp.write(pair.getSecond().serializeAsByte());
-    }
-    byte[] tempArray = temp.toByteArray();
-    payload.write(tempArray);
-    return tempArray.length;
-  }
-
-  public static byte[] intToShortEncodedByteArray(int value) {
-    assert isU2(value);
-    byte[] bytes = new byte[2];
-    bytes[0] = (byte) (value >> 8);
-    bytes[1] = (byte) value;
-    return bytes;
-  }
-
-  private static void computeAllReferencesInHierarchy(
-      Map<ClassReference, ParsedApiClass> lookupMap,
-      DexItemFactory factory,
-      DexType holder,
-      ParsedApiClass apiClass,
-      AndroidApiLevel linkLevel,
-      Map<ApiDatabaseEntry, AndroidApiLevel> databaseEntries) {
-    if (!apiClass.getClassReference().getDescriptor().equals(factory.objectDescriptor.toString())) {
-      apiClass.forEachMethod(
-          (methodReference, apiLevel) ->
-              addIfNewOrApiLevelIsLower(
-                  linkLevel,
-                  databaseEntries,
-                  apiLevel,
-                  ApiDatabaseEntry.of(
-                      factory.createMethod(methodReference).withHolder(holder, factory))));
-      apiClass.forEachField(
-          (fieldReference, apiLevel) ->
-              addIfNewOrApiLevelIsLower(
-                  linkLevel,
-                  databaseEntries,
-                  apiLevel,
-                  ApiDatabaseEntry.of(fieldReference).withHolder(holder)));
-      apiClass.forEachSupertype(
-          (superType, apiLevel) ->
-              computeAllReferencesInHierarchy(
-                  lookupMap,
-                  factory,
-                  holder,
-                  lookupMap.get(superType),
-                  linkLevel.max(apiLevel),
-                  databaseEntries));
-      apiClass.forEachInterface(
-          (interfaceReference, apiLevel) ->
-              computeAllReferencesInHierarchy(
-                  lookupMap,
-                  factory,
-                  holder,
-                  lookupMap.get(interfaceReference),
-                  linkLevel.max(apiLevel),
-                  databaseEntries));
-    }
-  }
-
-  private static void addIfNewOrApiLevelIsLower(
-      AndroidApiLevel linkLevel,
-      Map<ApiDatabaseEntry, AndroidApiLevel> additionMap,
-      AndroidApiLevel apiLevel,
-      ApiDatabaseEntry member) {
-    AndroidApiLevel currentApiLevel = apiLevel.max(linkLevel);
-    AndroidApiLevel existingApiLevel = additionMap.get(member);
-    if (existingApiLevel == null || currentApiLevel.isLessThanOrEqualTo(existingApiLevel)) {
-      additionMap.put(member, currentApiLevel);
-    }
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/apimodel/AndroidApiHashingDatabaseBuilderGeneratorTest.java b/src/test/java/com/android/tools/r8/apimodel/AndroidApiHashingDatabaseBuilderGeneratorTest.java
index ce2c65f..b7b5dc8 100644
--- a/src/test/java/com/android/tools/r8/apimodel/AndroidApiHashingDatabaseBuilderGeneratorTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/AndroidApiHashingDatabaseBuilderGeneratorTest.java
@@ -22,7 +22,9 @@
 import com.android.tools.r8.androidapi.AndroidApiLevelCompute;
 import com.android.tools.r8.androidapi.AndroidApiLevelCompute.DefaultAndroidApiLevelCompute;
 import com.android.tools.r8.androidapi.AndroidApiLevelHashingDatabaseImpl;
+import com.android.tools.r8.androidapi.ApiDatabaseEntry;
 import com.android.tools.r8.androidapi.ComputedApiLevel;
+import com.android.tools.r8.androidapi.GenerateCovariantReturnTypeMethodsTest.CovariantMethodsInJarResult;
 import com.android.tools.r8.androidapi.SunMiscUnsafeApiTest;
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
@@ -55,6 +57,7 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -113,10 +116,166 @@
     TemporaryFolder temp = new TemporaryFolder();
     temp.create();
     Path apiLevels = temp.newFile("new_api_levels.ser").toPath();
-    AndroidApiHashingDatabaseBuilderGenerator.generate(apiClasses, apiLevels, androidJarApiLevel);
+    DexItemFactory factory = new DexItemFactory();
+    mergeCovariantMethods(apiClasses, factory);
+
+    Map<ApiDatabaseEntry, AndroidApiLevel> databaseEntries =
+        AndroidApiHashingDatabaseBuilderGenerator.generateEntries(apiClasses);
+
+    Path androidJar = ToolHelper.getAndroidJar(androidJarApiLevel);
+    AndroidApp androidApp =
+        AndroidApp.builder()
+            .addLibraryFile(androidJar)
+            .disableAndroidJarHiddenClassExtension()
+            .build();
+    AppView<AppInfoWithClassHierarchy> appView =
+        computeAppViewWithClassHierarchy(androidApp, Timing.empty());
+
+    ensureAllPublicMethodsAreMapped(
+        appView, apiClasses, databaseEntries, androidJarApiLevel, androidJar);
+
+    AndroidApiHashingDatabaseBuilderGenerator.writeEntries(databaseEntries, apiLevels);
+
     return new GenerateDatabaseResourceFilesResult(apiLevels);
   }
 
+  private static void ensureAllPublicMethodsAreMapped(
+      AppView<AppInfoWithClassHierarchy> appView,
+      List<ParsedApiClass> apiClasses,
+      Map<ApiDatabaseEntry, AndroidApiLevel> databaseEntries,
+      AndroidApiLevel apiLevel,
+      Path androidJar) {
+    Map<ClassReference, ParsedApiClass> lookupMap = new HashMap<>();
+    Map<ClassReference, Map<DexMethod, AndroidApiLevel>> methodMap = new HashMap<>();
+    Map<ClassReference, Map<FieldTypelessReference, AndroidApiLevel>> fieldMap = new HashMap<>();
+    DexItemFactory factory = appView.dexItemFactory();
+
+    for (ParsedApiClass apiClass : apiClasses) {
+      lookupMap.put(apiClass.getClassReference(), apiClass);
+      Map<DexMethod, AndroidApiLevel> methodsForApiClass = new HashMap<>();
+      apiClass.forEachMethod(
+          (method, lvl) -> methodsForApiClass.put(factory.createMethod(method), lvl));
+      methodMap.put(apiClass.getClassReference(), methodsForApiClass);
+
+      Map<FieldTypelessReference, AndroidApiLevel> fieldsForApiClass = new HashMap<>();
+      apiClass.forEachField(fieldsForApiClass::put);
+      fieldMap.put(apiClass.getClassReference(), fieldsForApiClass);
+    }
+
+    Map<DexType, String> missingMemberInformation = new IdentityHashMap<>();
+    for (DexLibraryClass clazz : appView.app().asDirect().libraryClasses()) {
+      ParsedApiClass parsedApiClass = lookupMap.get(clazz.getClassReference());
+      if (parsedApiClass == null) {
+        if (clazz.isPublic()) {
+          missingMemberInformation.put(clazz.getType(), "Could not be found in " + androidJar);
+        }
+        continue;
+      }
+      StringBuilder classBuilder = new StringBuilder();
+      Map<FieldTypelessReference, AndroidApiLevel> fieldMapForClass =
+          fieldMap.get(clazz.getClassReference());
+      assert fieldMapForClass != null;
+      clazz.forEachClassField(
+          field -> {
+            if (field.getAccessFlags().isPublic()
+                && databaseEntries.get(ApiDatabaseEntry.of(field.getReference())) == null
+                && !field.toSourceString().contains("this$0")) {
+              classBuilder.append("  ").append(field).append(" is missing\n");
+            }
+          });
+      Map<DexMethod, AndroidApiLevel> methodMapForClass = methodMap.get(clazz.getClassReference());
+      assert methodMapForClass != null;
+      clazz.forEachClassMethod(
+          method -> {
+            if (method.getAccessFlags().isPublic()
+                && databaseEntries.get(ApiDatabaseEntry.of(method.getReference())) == null
+                && !factory.objectMembers.isObjectMember(method.getReference())) {
+              classBuilder.append("  ").append(method).append(" is missing\n");
+            }
+          });
+      if (classBuilder.length() > 0) {
+        missingMemberInformation.put(clazz.getType(), classBuilder.toString());
+      }
+    }
+
+    Set<DexType> expectedMissingMembers = new HashSet<>();
+    // api-versions.xml do not encode all members of StringBuffers and StringBuilders, check that we
+    // only have missing definitions for those two classes.
+    expectedMissingMembers.add(factory.stringBufferType);
+    expectedMissingMembers.add(factory.stringBuilderType);
+    // TODO(b/231126636): api-versions.xml has missing definitions for the below classes.
+    expectedMissingMembers.add(
+        factory.createType("Ljava/util/concurrent/ConcurrentHashMap$KeySetView;"));
+    expectedMissingMembers.add(factory.createType("Ljava/time/chrono/ThaiBuddhistDate;"));
+    expectedMissingMembers.add(factory.createType("Ljava/time/chrono/HijrahDate;"));
+    expectedMissingMembers.add(factory.createType("Ljava/time/chrono/JapaneseDate;"));
+    expectedMissingMembers.add(factory.createType("Ljava/time/chrono/MinguoDate;"));
+    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcV;"));
+    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/IsoDep;"));
+    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/MifareUltralight;"));
+    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/MifareClassic;"));
+    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NdefFormatable;"));
+    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcA;"));
+    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcBarcode;"));
+    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcF;"));
+    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/NfcB;"));
+    expectedMissingMembers.add(factory.createType("Landroid/nfc/tech/Ndef;"));
+    expectedMissingMembers.add(factory.createType("Landroid/webkit/CookieSyncManager;"));
+    if (apiLevel.isLessThan(AndroidApiLevel.BAKLAVA_1)) {
+      expectedMissingMembers.add(
+          factory.createType("Landroid/adservices/adselection/AdSelectionOutcome;"));
+      expectedMissingMembers.add(
+          factory.createType("Landroid/adservices/adselection/ReportEventRequest;"));
+      expectedMissingMembers.add(
+          factory.createType(
+              "Landroid/adservices/ondevicepersonalization/FederatedComputeScheduleRequest;"));
+      expectedMissingMembers.add(
+          factory.createType(
+              "Landroid/adservices/ondevicepersonalization/FederatedComputeScheduleResponse;"));
+      expectedMissingMembers.add(
+          factory.createType(
+              "Landroid/adservices/ondevicepersonalization/FederatedComputeScheduler;"));
+      expectedMissingMembers.add(
+          factory.createType("Landroid/adservices/ondevicepersonalization/InferenceInput;"));
+      expectedMissingMembers.add(
+          factory.createType(
+              "Landroid/adservices/ondevicepersonalization/InferenceInput$Builder;"));
+      expectedMissingMembers.add(
+          factory.createType("Landroid/adservices/ondevicepersonalization/InferenceInput$Params;"));
+      expectedMissingMembers.add(
+          factory.createType("Landroid/adservices/ondevicepersonalization/InferenceOutput;"));
+      expectedMissingMembers.add(
+          factory.createType(
+              "Landroid/adservices/ondevicepersonalization/InferenceOutput$Builder;"));
+      expectedMissingMembers.add(
+          factory.createType(
+              "Landroid/adservices/ondevicepersonalization/OnDevicePersonalizationManager;"));
+    }
+    assertThat(missingMemberInformation.keySet(), matchesItemsOneToOne(expectedMissingMembers));
+  }
+
+  private static void mergeCovariantMethods(List<ParsedApiClass> apiClasses, DexItemFactory factory)
+      throws Exception {
+    CovariantMethodsInJarResult covariantMethodsInJar = CovariantMethodsInJarResult.create();
+    for (ParsedApiClass apiClass : apiClasses) {
+      Map<DexMethod, AndroidApiLevel> methodsForApiClass = new HashMap<>();
+      apiClass.forEachMethod(
+          (method, apiLevel) -> methodsForApiClass.put(factory.createMethod(method), apiLevel));
+      covariantMethodsInJar.visitCovariantMethodsForHolder(
+          apiClass.getClassReference(),
+          methodReferenceWithApiLevel -> {
+            DexMethod method =
+                factory.createMethod(methodReferenceWithApiLevel.getMethodReference());
+            if (!methodsForApiClass.containsKey(method)) {
+              apiClass.registerMethod(
+                  methodReferenceWithApiLevel.getMethodReference(),
+                  methodReferenceWithApiLevel.getApiLevel());
+              methodsForApiClass.put(method, methodReferenceWithApiLevel.getApiLevel());
+            }
+          });
+    }
+  }
+
   @Test
   public void testCanParseApiVersionsXml() throws Exception {
     // This tests makes a rudimentary check on the number of classes, fields and methods in
diff --git a/third_party/api_database/api_database.tar.gz.sha1 b/third_party/api_database/api_database.tar.gz.sha1
index f5a7dcf..839dea4 100644
--- a/third_party/api_database/api_database.tar.gz.sha1
+++ b/third_party/api_database/api_database.tar.gz.sha1
@@ -1 +1 @@
-83f980bfe52868bf67129526ea1c626ba5f37fec
\ No newline at end of file
+ebc62b3efc8ffa79035399941c1c3d8bf995b5ec
\ No newline at end of file
