diff --git a/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseBuilderTemplate.java b/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseBuilderTemplate.java
deleted file mode 100644
index 4b21f6e..0000000
--- a/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseBuilderTemplate.java
+++ /dev/null
@@ -1,32 +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 com.android.tools.r8.androidapi.AndroidApiClass;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.utils.DescriptorUtils;
-import java.util.function.Consumer;
-
-/** This is a template for generating the AndroidApiDatabaseBuilder. */
-public class AndroidApiDatabaseBuilderTemplate /* AndroidApiDatabaseBuilder */ {
-
-  public static void visitApiClasses(Consumer<String> classDescriptorConsumer) {
-    // Code added dynamically in AndroidApiDatabaseBuilderGenerator.
-    placeHolderForVisitApiClasses();
-  }
-
-  public static AndroidApiClass buildClass(ClassReference classReference) {
-    String descriptor = classReference.getDescriptor();
-    String packageName = DescriptorUtils.getPackageNameFromDescriptor(descriptor);
-    String simpleClassName = DescriptorUtils.getSimpleClassNameFromDescriptor(descriptor);
-    // Code added dynamically in AndroidApiDatabaseBuilderGenerator.
-    placeHolderForBuildClass();
-    return null;
-  }
-
-  private static void placeHolderForVisitApiClasses() {}
-
-  private static void placeHolderForBuildClass() {}
-}
diff --git a/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseClassTemplate.java b/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseClassTemplate.java
deleted file mode 100644
index 1a8b7e3..0000000
--- a/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabaseClassTemplate.java
+++ /dev/null
@@ -1,71 +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 com.android.tools.r8.androidapi.AndroidApiClass;
-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.references.Reference;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.TraversalContinuation;
-import java.util.function.BiFunction;
-
-/** This is a template for generating AndroidApiDatabaseClass extending AndroidApiClass */
-public class AndroidApiDatabaseClassTemplate extends AndroidApiClass {
-
-  protected AndroidApiDatabaseClassTemplate() {
-    // Code added dynamically in AndroidApiDatabaseBuilderGenerator.
-    super(Reference.classFromDescriptor(placeHolderForInit()));
-  }
-
-  @Override
-  public AndroidApiLevel getApiLevel() {
-    // Code added dynamically in AndroidApiDatabaseBuilderGenerator.
-    return placeHolderForGetApiLevel();
-  }
-
-  @Override
-  public int getMemberCount() {
-    // Code added dynamically in AndroidApiDatabaseBuilderGenerator.
-    return placeHolderForGetMemberCount();
-  }
-
-  @Override
-  public TraversalContinuation visitFields(
-      BiFunction<FieldReference, AndroidApiLevel, TraversalContinuation> visitor,
-      ClassReference holder,
-      int minApi) {
-    // Code added dynamically in AndroidApiDatabaseBuilderGenerator.
-    placeHolderForVisitFields();
-    return TraversalContinuation.CONTINUE;
-  }
-
-  @Override
-  public TraversalContinuation visitMethods(
-      BiFunction<MethodReference, AndroidApiLevel, TraversalContinuation> visitor,
-      ClassReference holder,
-      int minApi) {
-    // Code added dynamically in AndroidApiDatabaseBuilderGenerator.
-    placeHolderForVisitMethods();
-    return TraversalContinuation.CONTINUE;
-  }
-
-  private static String placeHolderForInit() {
-    return null;
-  }
-
-  private static AndroidApiLevel placeHolderForGetApiLevel() {
-    return null;
-  }
-
-  private static int placeHolderForGetMemberCount() {
-    return 0;
-  }
-
-  private static void placeHolderForVisitFields() {}
-
-  private static void placeHolderForVisitMethods() {}
-}
diff --git a/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabasePackageTemplate.java b/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabasePackageTemplate.java
deleted file mode 100644
index 3919d11..0000000
--- a/src/test/java/com/android/tools/r8/apimodel/AndroidApiDatabasePackageTemplate.java
+++ /dev/null
@@ -1,19 +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 com.android.tools.r8.androidapi.AndroidApiClass;
-
-/** This is a template for generating the AndroidApiDatabasePackage. */
-public class AndroidApiDatabasePackageTemplate {
-
-  public static AndroidApiClass buildClass(String className) {
-    // Code added dynamically in AndroidApiDatabaseBuilderGenerator.
-    placeHolder();
-    return null;
-  }
-
-  private static void placeHolder() {}
-}
diff --git a/src/test/java/com/android/tools/r8/apimodel/AndroidApiObjectDatabaseBuilderGenerator.java b/src/test/java/com/android/tools/r8/apimodel/AndroidApiObjectDatabaseBuilderGenerator.java
deleted file mode 100644
index c8b6c24..0000000
--- a/src/test/java/com/android/tools/r8/apimodel/AndroidApiObjectDatabaseBuilderGenerator.java
+++ /dev/null
@@ -1,593 +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.utils.FunctionUtils.ignoreArgument;
-import static org.objectweb.asm.Opcodes.AASTORE;
-import static org.objectweb.asm.Opcodes.ACONST_NULL;
-import static org.objectweb.asm.Opcodes.ALOAD;
-import static org.objectweb.asm.Opcodes.ANEWARRAY;
-import static org.objectweb.asm.Opcodes.ARETURN;
-import static org.objectweb.asm.Opcodes.DUP;
-import static org.objectweb.asm.Opcodes.F_SAME1;
-import static org.objectweb.asm.Opcodes.IFEQ;
-import static org.objectweb.asm.Opcodes.ILOAD;
-import static org.objectweb.asm.Opcodes.INVOKEINTERFACE;
-import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
-import static org.objectweb.asm.Opcodes.INVOKESTATIC;
-import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
-import static org.objectweb.asm.Opcodes.NEW;
-import static org.objectweb.asm.Opcodes.POP;
-
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.apimodel.AndroidApiVersionsXmlParser.ParsedApiClass;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.Reference;
-import com.android.tools.r8.references.TypeReference;
-import com.android.tools.r8.transformers.ClassFileTransformer.MethodPredicate;
-import com.android.tools.r8.transformers.MethodTransformer;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.DescriptorUtils;
-import com.android.tools.r8.utils.IntBox;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.Opcodes;
-
-public class AndroidApiObjectDatabaseBuilderGenerator extends TestBase {
-
-  public static String generatedMainDescriptor() {
-    return descriptor(AndroidApiDatabaseBuilderTemplate.class).replace("Template", "");
-  }
-
-  public static ClassReference ANDROID_API_LEVEL =
-      Reference.classFromBinaryName("com/android/tools/r8/utils/AndroidApiLevel");
-  public static ClassReference ANDROID_API_CLASS =
-      Reference.classFromBinaryName("com/android/tools/r8/androidapi/AndroidApiClass");
-  public static ClassReference TRAVERSAL_CONTINUATION =
-      Reference.classFromBinaryName("com/android/tools/r8/utils/TraversalContinuation");
-
-  /**
-   * Generate the classes needed for looking up api level of references in the android.jar.
-   *
-   * <p>For each api class we generate a from AndroidApiDatabaseClassTemplate, extending
-   * AndroidApiClass, such that all members can be traversed. Looking up the class reference
-   * directly in one method will generate to much code and would probably be inefficient so we first
-   * do a case on the package and then do a check on the simple name.
-   *
-   * <p>We therefore create a class file for each package, based on
-   * AndroidApiDatabasePackageTemplate, that will do the dispatch to create a new
-   * AndroidApiDatabaseClass for class in the package.
-   *
-   * <p>We then have a single entry-point, AndroidApiDatabaseBuilder, based on
-   * AndroidApiDatabaseBuilderTemplate, that will do the dispatch to AndroidApiDatabasePackage based
-   * on the package name.
-   */
-  public static void generate(List<ParsedApiClass> apiClasses, BiConsumer<String, byte[]> consumer)
-      throws Exception {
-    Map<String, List<ParsedApiClass>> packageToClassesMap = new HashMap<>();
-    List<String> packages =
-        apiClasses.stream()
-            .map(
-                apiClass -> {
-                  String packageName =
-                      DescriptorUtils.getPackageNameFromDescriptor(
-                          apiClass.getClassReference().getDescriptor());
-                  packageToClassesMap
-                      .computeIfAbsent(packageName, ignoreArgument(ArrayList::new))
-                      .add(apiClass);
-                  return packageName;
-                })
-            .sorted()
-            .distinct()
-            .collect(Collectors.toList());
-
-    for (ParsedApiClass apiClass : apiClasses) {
-      String apiClassDescriptor = getApiClassReference(apiClass).getDescriptor();
-      consumer.accept(
-          apiClassDescriptor,
-          transformer(AndroidApiDatabaseClassTemplate.class)
-              .setClassDescriptor(apiClassDescriptor)
-              .addMethodTransformer(getInitTransformer(apiClass))
-              .addMethodTransformer(getApiLevelTransformer(apiClass))
-              .addMethodTransformer(getGetMemberCountTransformer(apiClass))
-              .addMethodTransformer(getVisitFieldsTransformer(apiClass))
-              .addMethodTransformer(getVisitMethodsTransformer(apiClass))
-              .removeMethods(MethodPredicate.onName("placeHolderForInit"))
-              .removeMethods(MethodPredicate.onName("placeHolderForGetApiLevel"))
-              .removeMethods(MethodPredicate.onName("placeHolderForGetMemberCount"))
-              .removeMethods(MethodPredicate.onName("placeHolderForVisitFields"))
-              .removeMethods(MethodPredicate.onName("placeHolderForVisitMethods"))
-              .setSourceFile(
-                  DescriptorUtils.getSimpleClassNameFromDescriptor(apiClassDescriptor) + ".java")
-              .computeMaxs()
-              .transform(ClassWriter.COMPUTE_MAXS));
-    }
-
-    for (String pkg : packages) {
-      consumer.accept(
-          getPackageBuilderDescriptor(pkg),
-          transformer(AndroidApiDatabasePackageTemplate.class)
-              .setClassDescriptor(getPackageBuilderDescriptor(pkg))
-              .addMethodTransformer(getBuildClassTransformer(packageToClassesMap.get(pkg)))
-              .removeMethods(MethodPredicate.onName("placeHolder"))
-              .computeMaxs()
-              .transform(ClassWriter.COMPUTE_MAXS));
-    }
-
-    consumer.accept(
-        generatedMainDescriptor(),
-        transformer(AndroidApiDatabaseBuilderTemplate.class)
-            .setClassDescriptor(generatedMainDescriptor())
-            .addMethodTransformer(getVisitApiClassesTransformer(apiClasses))
-            .addMethodTransformer(getBuildPackageTransformer(packages))
-            .removeMethods(MethodPredicate.onName("placeHolderForVisitApiClasses"))
-            .removeMethods(MethodPredicate.onName("placeHolderForBuildClass"))
-            .computeMaxs()
-            .transform(ClassWriter.COMPUTE_MAXS));
-  }
-
-  private static String getPackageBuilderDescriptor(String pkg) {
-    return DescriptorUtils.javaTypeToDescriptor(
-        AndroidApiDatabasePackageTemplate.class
-            .getTypeName()
-            .replace("Template", "ForPackage_" + pkg.replace(".", "_")));
-  }
-
-  private static ClassReference getApiClassReference(ParsedApiClass apiClass) {
-    return fromTemplate(apiClass.getClassReference());
-  }
-
-  private static ClassReference fromTemplate(ClassReference classReference) {
-    String descriptor =
-        DescriptorUtils.javaTypeToDescriptor(
-            AndroidApiDatabaseClassTemplate.class
-                .getTypeName()
-                .replace("Template", "ForClass_" + classReference.getTypeName().replace(".", "_")));
-    return Reference.classFromDescriptor(descriptor);
-  }
-
-  // The transformer below changes AndroidApiDatabaseClassTemplate.<init> from:
-  //     super(Reference.classFromDescriptor(placeHolderForInit()));
-  // into
-  //     super(Reference.classFromDescriptor("<class-descriptor>"));
-  private static MethodTransformer getInitTransformer(ParsedApiClass apiClass) {
-    return replaceCode(
-        "placeHolderForInit",
-        transformer -> {
-          transformer.visitLdcInsn(apiClass.getClassReference().getDescriptor());
-        });
-  }
-
-  // The transformer below changes AndroidApiDatabaseClassTemplate.getApiLevel from:
-  //     return placeHolderForGetApiLevel();
-  // into
-  //    return AndroidApiLevel.getAndroidApiLevel(<apiLevel>);
-  private static MethodTransformer getApiLevelTransformer(ParsedApiClass apiClass) {
-    return replaceCode(
-        "placeHolderForGetApiLevel",
-        transformer -> {
-          transformer.visitLdcInsn(apiClass.getApiLevel().getLevel());
-          transformer.visitMethodInsn(
-              INVOKESTATIC,
-              ANDROID_API_LEVEL.getBinaryName(),
-              "getAndroidApiLevel",
-              "(I)" + ANDROID_API_LEVEL.getDescriptor(),
-              false);
-        });
-  }
-
-  // The transformer below changes AndroidApiDatabaseClassTemplate.getMemberCount from:
-  //     return placeHolderForGetMemberCount();
-  // into
-  //    return <memberCount>;
-  private static MethodTransformer getGetMemberCountTransformer(ParsedApiClass apiClass) {
-    return replaceCode(
-        "placeHolderForGetMemberCount",
-        transformer -> transformer.visitLdcInsn(apiClass.getTotalMemberCount()));
-  }
-
-  // The transformer below changes AndroidApiDatabaseClassTemplate.visitFields from:
-  //     placeHolder();
-  //     return TraversalContinuation.CONTINUE;
-  // into
-  //    TraversalContinuation s1 = visitField(visitor, holder, minApiClass, apiLevel1, "field1",
-  //        "descriptor1")
-  //    if (s1.shouldBreak()) {
-  //       return s1;
-  //    }
-  //    TraversalContinuation s2 = visitField(visitor, holder, minApiClass, apiLevel2, "field2",
-  //   //        "descriptor2")
-  //    if (s2.shouldBreak()) {
-  //       return s2;
-  //    }
-  //    ...
-  //    AndroidApiClassForClass_class_name1() super1 = new AndroidApiClassForClass_class_name1();
-  //    TraversalContinuation sN = super1.visitFields(
-  //        visitor, holder, max(minApiClass, minApiForLink));
-  //    ...
-  //    return TraversalContinuation.CONTINUE;
-  private static MethodTransformer getVisitFieldsTransformer(ParsedApiClass apiClass) {
-    IntBox lineNumberBox = new IntBox(0);
-    return replaceCode(
-        "placeHolderForVisitFields",
-        transformer -> {
-          apiClass.visitFieldReferences(
-              (apiLevel, references) -> {
-                references.forEach(
-                    reference -> {
-                      Label labelStart = new Label();
-                      transformer.visitLabel(labelStart);
-                      transformer.visitLineNumber(lineNumberBox.getAndIncrement(), labelStart);
-                      transformer.visitVarInsn(ALOAD, 0);
-                      transformer.visitVarInsn(ALOAD, 1);
-                      transformer.visitVarInsn(ALOAD, 2);
-                      transformer.visitVarInsn(ILOAD, 3);
-                      transformer.visitLdcInsn(apiLevel.getLevel());
-                      transformer.visitLdcInsn(reference.getFieldName());
-                      transformer.visitLdcInsn(reference.getFieldType().getDescriptor());
-                      transformer.visitMethodInsn(
-                          INVOKEVIRTUAL,
-                          ANDROID_API_CLASS.getBinaryName(),
-                          "visitField",
-                          "(Ljava/util/function/BiFunction;"
-                              + descriptor(ClassReference.class)
-                              + "I"
-                              + "I"
-                              + "Ljava/lang/String;"
-                              + "Ljava/lang/String;)"
-                              + TRAVERSAL_CONTINUATION.getDescriptor(),
-                          false);
-                      // Note that instead of storing the result here, we dup it on the stack.
-                      transformer.visitInsn(DUP);
-                      transformer.visitMethodInsn(
-                          INVOKEVIRTUAL,
-                          TRAVERSAL_CONTINUATION.getBinaryName(),
-                          "shouldBreak",
-                          "()Z",
-                          false);
-                      Label label = new Label();
-                      transformer.visitJumpInsn(IFEQ, label);
-                      transformer.visitInsn(ARETURN);
-                      transformer.visitLabel(label);
-                      transformer.visitFrame(
-                          F_SAME1,
-                          0,
-                          new Object[] {},
-                          1,
-                          new Object[] {TRAVERSAL_CONTINUATION.getBinaryName()});
-                      // The pop here is needed to remove the dupped value in the case we do not
-                      // return.
-                      transformer.visitInsn(POP);
-                    });
-              });
-          if (!apiClass.isInterface()) {
-            apiClass.visitSuperType(
-                (superType, apiLevel) -> {
-                  addMembersForParent(
-                      transformer,
-                      superType,
-                      "visitFields",
-                      apiLevel,
-                      lineNumberBox.getAndIncrement());
-                });
-          }
-          // No need to visit fields on interfaces since they have to be static and should not be
-          // called on a super instance.
-        });
-  }
-
-  // The transformer below changes AndroidApiDatabaseClassTemplate.visitMethods from:
-  //     placeHolderForVisitMethods();
-  //     return TraversalContinuation.CONTINUE;
-  // into
-  //    TraversalContinuation s1 = visitMethod(visitor, holder, minApiClass, apiLevel1,
-  //      "method1", new String[] { "param11", ... , "param1X" }, null/return1)
-  //    if (s1.shouldBreak()) {
-  //       return s1;
-  //    }
-  //    TraversalContinuation s1 = visitMethod(visitor, holder, minApiClass, apiLevel2,
-  //      "method2", new String[] { "param21", ... , "param2X" }, null/return2)
-  //    if (s2.shouldBreak()) {
-  //       return s2;
-  //    }
-  //    ...
-  //    AndroidApiClassForClass_class_name1() super1 = new AndroidApiClassForClass_class_name1();
-  //    TraversalContinuation sN = super1.visitMethods(
-  //      visitor, holder, max(minApiClass, minApiForLink));
-  //    ...
-  //    return TraversalContinuation.CONTINUE;
-  private static MethodTransformer getVisitMethodsTransformer(ParsedApiClass apiClass) {
-    IntBox lineNumberBox = new IntBox(0);
-    return replaceCode(
-        "placeHolderForVisitMethods",
-        transformer -> {
-          apiClass.visitMethodReferences(
-              (apiLevel, references) -> {
-                references.forEach(
-                    reference -> {
-                      Label labelStart = new Label();
-                      transformer.visitLabel(labelStart);
-                      transformer.visitLineNumber(lineNumberBox.getAndIncrement(), labelStart);
-                      transformer.visitVarInsn(ALOAD, 0);
-                      transformer.visitVarInsn(ALOAD, 1);
-                      transformer.visitVarInsn(ALOAD, 2);
-                      transformer.visitVarInsn(ILOAD, 3);
-                      transformer.visitLdcInsn(apiLevel.getLevel());
-                      transformer.visitLdcInsn(reference.getMethodName());
-                      List<TypeReference> formalTypes = reference.getFormalTypes();
-                      transformer.visitLdcInsn(formalTypes.size());
-                      transformer.visitTypeInsn(ANEWARRAY, binaryName(String.class));
-                      for (int i = 0; i < formalTypes.size(); i++) {
-                        transformer.visitInsn(DUP);
-                        transformer.visitLdcInsn(i);
-                        transformer.visitLdcInsn(formalTypes.get(i).getDescriptor());
-                        transformer.visitInsn(AASTORE);
-                      }
-                      if (reference.getReturnType() != null) {
-                        transformer.visitLdcInsn(reference.getReturnType().getDescriptor());
-                      } else {
-                        transformer.visitInsn(ACONST_NULL);
-                      }
-                      transformer.visitMethodInsn(
-                          INVOKEVIRTUAL,
-                          ANDROID_API_CLASS.getBinaryName(),
-                          "visitMethod",
-                          "(Ljava/util/function/BiFunction;"
-                              + descriptor(ClassReference.class)
-                              + "I"
-                              + "I"
-                              + "Ljava/lang/String;"
-                              + "[Ljava/lang/String;"
-                              + "Ljava/lang/String;)"
-                              + TRAVERSAL_CONTINUATION.getDescriptor(),
-                          false);
-                      // Note that instead of storing the result here, we dup it on the stack.
-                      transformer.visitInsn(DUP);
-                      transformer.visitMethodInsn(
-                          INVOKEVIRTUAL,
-                          TRAVERSAL_CONTINUATION.getBinaryName(),
-                          "shouldBreak",
-                          "()Z",
-                          false);
-                      Label label = new Label();
-                      transformer.visitJumpInsn(IFEQ, label);
-                      transformer.visitInsn(ARETURN);
-                      transformer.visitLabel(label);
-                      transformer.visitFrame(
-                          F_SAME1,
-                          0,
-                          new Object[] {},
-                          1,
-                          new Object[] {TRAVERSAL_CONTINUATION.getBinaryName()});
-                      // The pop here is needed to remove the dupped value in the case we do not
-                      // return.
-                      transformer.visitInsn(POP);
-                    });
-              });
-          if (!apiClass.isInterface()) {
-            // Visit super types before interfaces emulating a poor man's resolutions.
-            apiClass.visitSuperType(
-                (superType, apiLevel) -> {
-                  addMembersForParent(
-                      transformer,
-                      superType,
-                      "visitMethods",
-                      apiLevel,
-                      lineNumberBox.getAndIncrement());
-                });
-          }
-          apiClass.visitInterface(
-              (classReference, apiLevel) -> {
-                addMembersForParent(
-                    transformer,
-                    classReference,
-                    "visitMethods",
-                    apiLevel,
-                    lineNumberBox.getAndIncrement());
-              });
-        });
-  }
-
-  private static void addMembersForParent(
-      MethodTransformer transformer,
-      ClassReference classReference,
-      String methodName,
-      AndroidApiLevel minApiLevel,
-      int lineNumber) {
-    String binaryName = fromTemplate(classReference).getBinaryName();
-    Label labelStart = new Label();
-    transformer.visitLabel(labelStart);
-    transformer.visitLineNumber(lineNumber, labelStart);
-    transformer.visitTypeInsn(NEW, binaryName);
-    transformer.visitInsn(DUP);
-    transformer.visitMethodInsn(INVOKESPECIAL, binaryName, "<init>", "()V", false);
-    transformer.visitVarInsn(ALOAD, 1);
-    transformer.visitVarInsn(ALOAD, 2);
-    // Compute the max api level compared to what is passed in.
-    transformer.visitLdcInsn(minApiLevel.getLevel());
-    transformer.visitVarInsn(ILOAD, 3);
-    transformer.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "max", "(II)I", false);
-    transformer.visitMethodInsn(
-        INVOKEVIRTUAL,
-        binaryName,
-        methodName,
-        "(Ljava/util/function/BiFunction;"
-            + descriptor(ClassReference.class)
-            + "I)"
-            + TRAVERSAL_CONTINUATION.getDescriptor(),
-        false);
-    // Note that instead of storing the result here, we dup it on the stack.
-    transformer.visitInsn(DUP);
-    transformer.visitMethodInsn(
-        INVOKEVIRTUAL, TRAVERSAL_CONTINUATION.getBinaryName(), "shouldBreak", "()Z", false);
-    Label label = new Label();
-    transformer.visitJumpInsn(IFEQ, label);
-    transformer.visitInsn(ARETURN);
-    transformer.visitLabel(label);
-    transformer.visitFrame(
-        F_SAME1, 0, new Object[] {}, 1, new Object[] {TRAVERSAL_CONTINUATION.getBinaryName()});
-    // The pop here is needed to remove the dupped value in the case we do not return.
-    transformer.visitInsn(POP);
-  }
-
-  // The transformer below changes AndroidApiDatabasePackageTemplate.buildClass from:
-  //    placeHolder();
-  //    return null;
-  // into
-  //    if ("<simple_class1>".equals(className)) {
-  //      return new AndroidApiClassForClass_class_name1();
-  //    }
-  //    if ("<simple_class2>".equals(className)) {
-  //      return new AndroidApiClassForClass_class_name2();
-  //    }
-  //    ...
-  //    return null;
-  private static MethodTransformer getBuildClassTransformer(List<ParsedApiClass> classesForPackage)
-      throws NoSuchMethodException {
-    Method equals = Object.class.getMethod("equals", Object.class);
-    return replaceCode(
-        "placeHolder",
-        transformer -> {
-          classesForPackage.forEach(
-              apiClass -> {
-                transformer.visitLdcInsn(
-                    DescriptorUtils.getSimpleClassNameFromDescriptor(
-                        apiClass.getClassReference().getDescriptor()));
-                transformer.visitVarInsn(ALOAD, 0);
-                transformer.visitMethodInsn(
-                    INVOKEVIRTUAL,
-                    binaryName(String.class),
-                    equals.getName(),
-                    methodDescriptor(equals),
-                    false);
-                Label label = new Label();
-                transformer.visitJumpInsn(IFEQ, label);
-                String binaryName = getApiClassReference(apiClass).getBinaryName();
-                transformer.visitTypeInsn(NEW, binaryName);
-                transformer.visitInsn(DUP);
-                transformer.visitMethodInsn(INVOKESPECIAL, binaryName, "<init>", "()V", false);
-                transformer.visitInsn(ARETURN);
-                transformer.visitLabel(label);
-                transformer.visitFrame(Opcodes.F_SAME, 0, new Object[] {}, 0, new Object[0]);
-              });
-        });
-  }
-
-  // The transformer below changes AndroidApiDatabaseBuilderTemplate.buildClass from:
-  //    String descriptor = classReference.getDescriptor();
-  //    String packageName = DescriptorUtils.getPackageNameFromDescriptor(descriptor);
-  //    String simpleClassName = DescriptorUtils.getSimpleClassNameFromDescriptor(descriptor);
-  //    placeHolderForBuildClass();
-  //    return null;
-  // into
-  //    String descriptor = classReference.getDescriptor();
-  //    String packageName = DescriptorUtils.getPackageNameFromDescriptor(descriptor);
-  //    String simpleClassName = DescriptorUtils.getSimpleClassNameFromDescriptor(descriptor);
-  //    if ("<package_name1>".equals(packageName)) {
-  //      return AndroidApiClassForPackage_package_name1(simpleClassName);
-  //    }
-  //    if ("<package_name2>".equals(simpleClassName)) {
-  //      return AndroidApiClassForPackage_package_name2(simpleClassName);
-  //    }
-  //    ...
-  //    return null;
-  private static MethodTransformer getBuildPackageTransformer(List<String> packages)
-      throws NoSuchMethodException {
-    Method equals = String.class.getMethod("equals", Object.class);
-    Method buildClass =
-        AndroidApiDatabasePackageTemplate.class.getMethod("buildClass", String.class);
-    return replaceCode(
-        "placeHolderForBuildClass",
-        transformer -> {
-          packages.forEach(
-              pkg -> {
-                transformer.visitLdcInsn(pkg);
-                transformer.visitVarInsn(ALOAD, 2);
-                transformer.visitMethodInsn(
-                    INVOKEVIRTUAL,
-                    binaryName(String.class),
-                    equals.getName(),
-                    methodDescriptor(equals),
-                    false);
-                Label label = new Label();
-                transformer.visitJumpInsn(IFEQ, label);
-                transformer.visitVarInsn(ALOAD, 3);
-                transformer.visitMethodInsn(
-                    INVOKESTATIC,
-                    DescriptorUtils.getBinaryNameFromDescriptor(getPackageBuilderDescriptor(pkg)),
-                    buildClass.getName(),
-                    methodDescriptor(buildClass),
-                    false);
-                transformer.visitInsn(ARETURN);
-                transformer.visitLabel(label);
-                transformer.visitFrame(
-                    Opcodes.F_FULL,
-                    4,
-                    new Object[] {
-                      binaryName(ClassReference.class),
-                      binaryName(String.class),
-                      binaryName(String.class),
-                      binaryName(String.class)
-                    },
-                    0,
-                    new Object[0]);
-              });
-        });
-  }
-
-  // The transformer below changes AndroidApiDatabaseBuilderTemplate.buildClass from:
-  //    placeHolderForVisitApiClasses();
-  // into
-  //    classDescriptorConsumer.accept("<descriptor_class_1>");
-  //    classDescriptorConsumer.accept("<descriptor_class_2>");
-  //    ...
-  //    return null;
-  private static MethodTransformer getVisitApiClassesTransformer(List<ParsedApiClass> apiClasses) {
-    return replaceCode(
-        "placeHolderForVisitApiClasses",
-        transformer -> {
-          apiClasses.forEach(
-              apiClass -> {
-                transformer.visitVarInsn(ALOAD, 0);
-                transformer.visitLdcInsn(apiClass.getClassReference().getDescriptor());
-                transformer.visitMethodInsn(
-                    INVOKEINTERFACE,
-                    binaryName(Consumer.class),
-                    "accept",
-                    "(Ljava/lang/Object;)V",
-                    true);
-              });
-        });
-  }
-
-  private static MethodTransformer replaceCode(
-      String placeholderName, Consumer<MethodTransformer> consumer) {
-    return new MethodTransformer() {
-
-      @Override
-      public void visitMaxs(int maxStack, int maxLocals) {
-        super.visitMaxs(-1, maxLocals);
-      }
-
-      @Override
-      public void visitMethodInsn(
-          int opcode, String owner, String name, String descriptor, boolean isInterface) {
-        if (name.equals(placeholderName)) {
-          consumer.accept(this);
-        } else {
-          super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
-        }
-      }
-    };
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/apimodel/AndroidApiObjectDatabaseBuilderGeneratorTest.java b/src/test/java/com/android/tools/r8/apimodel/AndroidApiObjectDatabaseBuilderGeneratorTest.java
deleted file mode 100644
index 40b57c5..0000000
--- a/src/test/java/com/android/tools/r8/apimodel/AndroidApiObjectDatabaseBuilderGeneratorTest.java
+++ /dev/null
@@ -1,421 +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.apimodel.AndroidApiObjectDatabaseBuilderGenerator.generatedMainDescriptor;
-import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
-import static org.junit.Assert.assertEquals;
-
-import com.android.tools.r8.CompilationFailedException;
-import com.android.tools.r8.JvmTestBuilder;
-import com.android.tools.r8.JvmTestRunResult;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.TestRuntime;
-import com.android.tools.r8.TestState;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.apimodel.AndroidApiVersionsXmlParser.ParsedApiClass;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.Reference;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.BooleanBox;
-import com.android.tools.r8.utils.DescriptorUtils;
-import com.android.tools.r8.utils.IntBox;
-import com.android.tools.r8.utils.ListUtils;
-import com.android.tools.r8.utils.StringUtils;
-import com.android.tools.r8.utils.TraversalContinuation;
-import com.android.tools.r8.utils.ZipUtils;
-import com.android.tools.r8.utils.ZipUtils.ZipBuilder;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.google.common.collect.ImmutableList;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-import java.util.function.BiFunction;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class AndroidApiObjectDatabaseBuilderGeneratorTest extends TestBase {
-
-  protected final TestParameters parameters;
-  private static final Path API_VERSIONS_XML =
-      Paths.get(ToolHelper.THIRD_PARTY_DIR, "android_jar", "api-versions", "api-versions.xml");
-  private static final Path API_DATABASE_JAR =
-      Paths.get(ToolHelper.THIRD_PARTY_DIR, "android_jar", "api-database", "api-database.jar");
-  private static final AndroidApiLevel API_LEVEL = AndroidApiLevel.S;
-
-  @Parameters(name = "{0}")
-  public static TestParametersCollection data() {
-    return getTestParameters().withNoneRuntime().build();
-  }
-
-  public AndroidApiObjectDatabaseBuilderGeneratorTest(TestParameters parameters) {
-    this.parameters = parameters;
-  }
-
-  private static Path generateJar() throws Exception {
-    return generateJar(
-        AndroidApiVersionsXmlParser.getParsedApiClasses(API_VERSIONS_XML.toFile(), API_LEVEL));
-  }
-
-  private static Path generateJar(List<ParsedApiClass> apiClasses) throws Exception {
-    TemporaryFolder temp = new TemporaryFolder();
-    temp.create();
-    ZipBuilder builder = ZipBuilder.builder(temp.newFile("out.jar").toPath());
-    AndroidApiObjectDatabaseBuilderGenerator.generate(
-        apiClasses,
-        (descriptor, content) -> {
-          try {
-            String binaryName = DescriptorUtils.getBinaryNameFromDescriptor(descriptor) + ".class";
-            builder.addBytes(binaryName, content);
-          } catch (IOException exception) {
-            throw new RuntimeException(exception);
-          }
-        });
-    return builder.build();
-  }
-
-  @Test
-  public void testCanParseApiVersionsXml() throws Exception {
-    // This tests makes a rudimentary check on the number of classes, fields and methods in
-    // api-versions.xml to ensure that the runtime tests do not vacuously succeed.
-    List<ParsedApiClass> parsedApiClasses =
-        AndroidApiVersionsXmlParser.getParsedApiClasses(API_VERSIONS_XML.toFile(), API_LEVEL);
-    IntBox numberOfFields = new IntBox(0);
-    IntBox numberOfMethods = new IntBox(0);
-    parsedApiClasses.forEach(
-        apiClass -> {
-          apiClass.visitFieldReferences(
-              ((apiLevel, fieldReferences) -> {
-                fieldReferences.forEach(field -> numberOfFields.increment());
-              }));
-          apiClass.visitMethodReferences(
-              ((apiLevel, methodReferences) -> {
-                methodReferences.forEach(field -> numberOfMethods.increment());
-              }));
-        });
-    // These numbers will change when updating api-versions.xml
-    assertEquals(5037, parsedApiClasses.size());
-    assertEquals(26362, numberOfFields.get());
-    assertEquals(40416, numberOfMethods.get());
-  }
-
-  @Test
-  public void testDatabaseGenerationUpToDate() throws Exception {
-    TestBase.filesAreEqual(generateJar(), API_DATABASE_JAR);
-  }
-
-  /**
-   * Main entry point for building a database over references in framework to the api level they
-   * were introduced. Running main will generate a new jar and run tests on it to ensure it is
-   * compatible with R8 sources and works as expected.
-   *
-   * <p>The generated jar depends on r8NoManifestWithoutDeps.
-   *
-   * <p>If the generated jar passes tests it will be moved to third_party/android_jar/api-database/
-   * and override the current file in there.
-   */
-  public static void main(String[] args) throws Exception {
-    List<ParsedApiClass> parsedApiClasses =
-        AndroidApiVersionsXmlParser.getParsedApiClasses(API_VERSIONS_XML.toFile(), API_LEVEL);
-    Path generatedJar = generateJar(parsedApiClasses);
-    validateJar(generatedJar, parsedApiClasses);
-    Files.move(generatedJar, API_DATABASE_JAR, REPLACE_EXISTING);
-  }
-
-  private static void validateJar(Path generated, List<ParsedApiClass> apiClasses) {
-    List<BiFunction<Path, List<ParsedApiClass>, Boolean>> tests =
-        ImmutableList.of(
-            AndroidApiObjectDatabaseBuilderGeneratorTest::testGeneratedOutputForVisitClasses,
-            AndroidApiObjectDatabaseBuilderGeneratorTest::testBuildClassesContinue,
-            AndroidApiObjectDatabaseBuilderGeneratorTest::testBuildClassesBreak,
-            AndroidApiObjectDatabaseBuilderGeneratorTest::testNoPlaceHolder);
-    tests.forEach(
-        test -> {
-          try {
-            if (!test.apply(generated, apiClasses)) {
-              throw new RuntimeException("Generated jar did not pass tests");
-            }
-          } catch (Exception e) {
-            throw new RuntimeException("Generated jar did not pass tests", e);
-          }
-        });
-  }
-
-  private static boolean testGeneratedOutputForVisitClasses(
-      Path generated, List<ParsedApiClass> parsedApiClasses) {
-    String expectedOutput =
-        StringUtils.lines(
-            ListUtils.map(
-                parsedApiClasses, apiClass -> apiClass.getClassReference().getDescriptor()));
-    return runTest(generated, TestGeneratedMainVisitClasses.class)
-        .getStdOut()
-        .equals(expectedOutput);
-  }
-
-  private static boolean testBuildClassesContinue(
-      Path generated, List<ParsedApiClass> parsedApiClasses) {
-    return runTest(generated, TestBuildClassesContinue.class)
-        .getStdOut()
-        .equals(getExpected(parsedApiClasses, false));
-  }
-
-  private static boolean testBuildClassesBreak(
-      Path generated, List<ParsedApiClass> parsedApiClasses) {
-    return runTest(generated, TestBuildClassesBreak.class)
-        .getStdOut()
-        .equals(getExpected(parsedApiClasses, true));
-  }
-
-  private static boolean testNoPlaceHolder(Path generated, List<ParsedApiClass> parsedApiClasses) {
-    try {
-      CodeInspector inspector = new CodeInspector(generated);
-      inspector
-          .allClasses()
-          .forEach(
-              clazz -> {
-                clazz.forAllMethods(
-                    methods -> {
-                      if (methods.getFinalName().startsWith("placeHolder")) {
-                        throw new RuntimeException("Found placeHolder method in generated jar");
-                      }
-                    });
-              });
-    } catch (Exception ex) {
-      throw new RuntimeException(ex);
-    }
-    return true;
-  }
-
-  private static JvmTestRunResult runTest(Path generated, Class<?> testClass) {
-    try {
-      TemporaryFolder temporaryFolder = new TemporaryFolder();
-      temporaryFolder.create();
-      return JvmTestBuilder.create(new TestState(temporaryFolder))
-          .addProgramClassFileData(
-              transformer(testClass)
-                  .replaceClassDescriptorInMethodInstructions(
-                      descriptor(AndroidApiDatabaseBuilderTemplate.class),
-                      generatedMainDescriptor())
-                  .transform())
-          .addLibraryFiles(
-              generated,
-              ToolHelper.R8_WITHOUT_DEPS_JAR,
-              getDepsWithoutGeneratedApiModelClasses(),
-              ToolHelper.getJava8RuntimeJar())
-          .run(TestRuntime.getSystemRuntime(), testClass)
-          .apply(
-              result -> {
-                if (result.getExitCode() != 0) {
-                  throw new RuntimeException(result.getStdErr());
-                }
-              });
-    } catch (IOException | ExecutionException | CompilationFailedException ex) {
-      throw new RuntimeException(ex);
-    }
-  }
-
-  private static Path getDepsWithoutGeneratedApiModelClasses() throws IOException {
-    Path tempDeps = Files.createTempDirectory("temp_deps");
-    ZipUtils.unzip(
-        ToolHelper.DEPS.toString(),
-        tempDeps.toFile(),
-        entry -> !entry.getName().startsWith("com/android/tools/r8/apimodel/"));
-    Path modifiedDeps = Files.createTempFile("modified_deps", ".jar");
-    ZipUtils.zip(modifiedDeps, tempDeps);
-    return modifiedDeps;
-  }
-
-  private static String getExpected(List<ParsedApiClass> parsedApiClasses, boolean abort) {
-    Map<ClassReference, ParsedApiClass> parsedApiClassMap = new HashMap<>(parsedApiClasses.size());
-    parsedApiClasses.forEach(
-        parsedClass -> parsedApiClassMap.put(parsedClass.getClassReference(), parsedClass));
-    List<String> expected = new ArrayList<>();
-    parsedApiClasses.forEach(
-        apiClass -> {
-          expected.add("CLASS: " + apiClass.getClassReference().getDescriptor());
-          expected.add(apiClass.getApiLevel().getName());
-          expected.add(apiClass.getTotalMemberCount() + "");
-          visitApiClass(expected, parsedApiClassMap, apiClass, apiClass.getApiLevel(), true, abort);
-          visitApiClass(
-              expected, parsedApiClassMap, apiClass, apiClass.getApiLevel(), false, abort);
-        });
-    return StringUtils.lines(expected);
-  }
-
-  private static boolean visitApiClass(
-      List<String> expected,
-      Map<ClassReference, ParsedApiClass> parsedApiClassMap,
-      ParsedApiClass apiClass,
-      AndroidApiLevel apiLevel,
-      boolean visitFields,
-      boolean abort) {
-    BooleanBox added = new BooleanBox(false);
-    if (visitFields) {
-      added.set(visitFields(expected, apiClass, apiLevel, abort));
-    } else {
-      added.set(visitMethods(expected, apiClass, apiLevel, abort));
-    }
-    if (added.isTrue() && abort) {
-      return true;
-    }
-    // Go through super type methods if not interface.
-    if (!apiClass.isInterface()) {
-      apiClass.visitSuperType(
-          (classReference, linkApiLevel) -> {
-            if (added.isTrue() && abort) {
-              return;
-            }
-            ParsedApiClass superApiClass = parsedApiClassMap.get(classReference);
-            assert superApiClass != null;
-            added.set(
-                visitApiClass(
-                    expected,
-                    parsedApiClassMap,
-                    superApiClass,
-                    linkApiLevel.max(apiLevel),
-                    visitFields,
-                    abort));
-          });
-    }
-    if (!visitFields) {
-      apiClass.visitInterface(
-          (classReference, linkApiLevel) -> {
-            if (added.isTrue() && abort) {
-              return;
-            }
-            ParsedApiClass ifaceApiClass = parsedApiClassMap.get(classReference);
-            assert ifaceApiClass != null;
-            added.set(
-                visitApiClass(
-                    expected,
-                    parsedApiClassMap,
-                    ifaceApiClass,
-                    linkApiLevel.max(apiLevel),
-                    visitFields,
-                    abort));
-          });
-    }
-    return added.get();
-  }
-
-  private static boolean visitFields(
-      List<String> expected, ParsedApiClass apiClass, AndroidApiLevel minApiLevel, boolean abort) {
-    BooleanBox added = new BooleanBox(false);
-    apiClass.visitFieldReferences(
-        (apiLevel, fieldReferences) -> {
-          fieldReferences.forEach(
-              fieldReference -> {
-                if (added.isTrue() && abort) {
-                  return;
-                }
-                added.set();
-                expected.add(fieldReference.getFieldType().getDescriptor());
-                expected.add(fieldReference.getFieldName());
-                expected.add(apiLevel.max(minApiLevel).getName());
-              });
-        });
-    return added.get();
-  }
-
-  private static boolean visitMethods(
-      List<String> expected, ParsedApiClass apiClass, AndroidApiLevel minApiLevel, boolean abort) {
-    BooleanBox added = new BooleanBox(false);
-    apiClass.visitMethodReferences(
-        (apiLevel, methodReferences) -> {
-          methodReferences.forEach(
-              methodReference -> {
-                if (added.isTrue() && abort) {
-                  return;
-                }
-                added.set();
-                expected.add(methodReference.getMethodDescriptor());
-                expected.add(methodReference.getMethodName());
-                expected.add(apiLevel.max(minApiLevel).getName());
-              });
-        });
-    return added.get();
-  }
-
-  public static class TestGeneratedMainVisitClasses {
-
-    public static void main(String[] args) {
-      AndroidApiDatabaseBuilderTemplate.visitApiClasses(System.out::println);
-    }
-  }
-
-  public static class TestBuildClassesContinue {
-
-    public static void main(String[] args) {
-      AndroidApiDatabaseBuilderTemplate.visitApiClasses(
-          descriptor -> {
-            com.android.tools.r8.androidapi.AndroidApiClass apiClass =
-                AndroidApiDatabaseBuilderTemplate.buildClass(
-                    Reference.classFromDescriptor(descriptor));
-            if (apiClass != null) {
-              System.out.println("CLASS: " + descriptor);
-              System.out.println(apiClass.getApiLevel().getName());
-              System.out.println(apiClass.getMemberCount());
-              apiClass.visitFields(
-                  (reference, apiLevel) -> {
-                    System.out.println(reference.getFieldType().getDescriptor());
-                    System.out.println(reference.getFieldName());
-                    System.out.println(apiLevel.getName());
-                    return TraversalContinuation.CONTINUE;
-                  });
-              apiClass.visitMethods(
-                  (reference, apiLevel) -> {
-                    System.out.println(reference.getMethodDescriptor());
-                    System.out.println(reference.getMethodName());
-                    System.out.println(apiLevel.getName());
-                    return TraversalContinuation.CONTINUE;
-                  });
-            }
-          });
-    }
-  }
-
-  public static class TestBuildClassesBreak {
-
-    public static void main(String[] args) {
-      AndroidApiDatabaseBuilderTemplate.visitApiClasses(
-          descriptor -> {
-            com.android.tools.r8.androidapi.AndroidApiClass apiClass =
-                AndroidApiDatabaseBuilderTemplate.buildClass(
-                    Reference.classFromDescriptor(descriptor));
-            if (apiClass != null) {
-              System.out.println("CLASS: " + descriptor);
-              System.out.println(apiClass.getApiLevel().getName());
-              System.out.println(apiClass.getMemberCount());
-              apiClass.visitFields(
-                  (reference, apiLevel) -> {
-                    System.out.println(reference.getFieldType().getDescriptor());
-                    System.out.println(reference.getFieldName());
-                    System.out.println(apiLevel.getName());
-                    return TraversalContinuation.BREAK;
-                  });
-              apiClass.visitMethods(
-                  (reference, apiLevel) -> {
-                    System.out.println(reference.getMethodDescriptor());
-                    System.out.println(reference.getMethodName());
-                    System.out.println(apiLevel.getName());
-                    return TraversalContinuation.BREAK;
-                  });
-            }
-          });
-    }
-  }
-}
