diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepEdgeAnnotationsTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepEdgeAnnotationsTest.java
new file mode 100644
index 0000000..fcdab96
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepEdgeAnnotationsTest.java
@@ -0,0 +1,218 @@
+// Copyright (c) 2022, 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.keepanno;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeTrue;
+
+import com.android.tools.r8.JavaCompilerTool;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.keepanno.annotations.KeepConstants.Edge;
+import com.android.tools.r8.keepanno.asm.KeepEdgeReader;
+import com.android.tools.r8.keepanno.asm.KeepEdgeWriter;
+import com.android.tools.r8.keepanno.ast.KeepEdge;
+import com.android.tools.r8.keepanno.keeprules.KeepRuleExtractor;
+import com.android.tools.r8.keepanno.processor.KeepEdgeProcessor;
+import com.android.tools.r8.keepanno.testsource.KeepClassAndDefaultConstructorSource;
+import com.android.tools.r8.keepanno.testsource.KeepFieldSource;
+import com.android.tools.r8.keepanno.testsource.KeepSourceEdges;
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.transformers.ClassTransformer;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.ZipUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.google.common.collect.ImmutableList;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.objectweb.asm.AnnotationVisitor;
+
+@RunWith(Parameterized.class)
+public class KeepEdgeAnnotationsTest extends TestBase {
+
+  private static class ParamWrapper {
+    private final Class<?> clazz;
+    private final TestParameters params;
+
+    public ParamWrapper(Class<?> clazz, TestParameters params) {
+      this.clazz = clazz;
+      this.params = params;
+    }
+
+    @Override
+    public String toString() {
+      return clazz.getSimpleName() + ", " + params.toString();
+    }
+  }
+
+  private static final Path KEEP_ANNO_PATH =
+      Paths.get(ToolHelper.BUILD_DIR, "classes", "java", "keepanno");
+
+  private static List<Class<?>> getTestClasses() {
+    return ImmutableList.of(KeepClassAndDefaultConstructorSource.class, KeepFieldSource.class);
+  }
+
+  private final TestParameters parameters;
+  private final Class<?> source;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static List<ParamWrapper> data() {
+    TestParametersCollection params =
+        getTestParameters().withDefaultRuntimes().withApiLevel(AndroidApiLevel.B).build();
+    return getTestClasses().stream()
+        .flatMap(c -> params.stream().map(p -> new ParamWrapper(c, p)))
+        .collect(Collectors.toList());
+  }
+
+  public KeepEdgeAnnotationsTest(ParamWrapper wrapper) {
+    this.parameters = wrapper.params;
+    this.source = wrapper.clazz;
+  }
+
+  private String getExpected() {
+    return KeepSourceEdges.getExpected(source);
+  }
+
+  @Test
+  public void testProcessorClassfiles() throws Exception {
+    assumeTrue(parameters.isCfRuntime());
+    Path out =
+        JavaCompilerTool.create(parameters.getRuntime().asCf(), temp)
+            .addAnnotationProcessors(typeName(KeepEdgeProcessor.class))
+            .addClasspathFiles(KEEP_ANNO_PATH)
+            .addClassNames(Collections.singletonList(typeName(source)))
+            .addClasspathFiles(Paths.get(ToolHelper.BUILD_DIR, "classes", "java", "test"))
+            .addClasspathFiles(ToolHelper.DEPS)
+            .compile();
+
+    CodeInspector inspector = new CodeInspector(out);
+    checkSynthesizedKeepEdgeClass(inspector, out);
+    // The source is added as a classpath name but not part of the compilation unit output.
+    assertThat(inspector.clazz(source), isAbsent());
+
+    testForJvm()
+        .addProgramClassesAndInnerClasses(source)
+        .addProgramFiles(out)
+        .run(parameters.getRuntime(), source)
+        .assertSuccessWithOutput(getExpected());
+  }
+
+  @Test
+  public void testProcessorJavaSource() throws Exception {
+    assumeTrue(parameters.isCfRuntime());
+    Path out =
+        JavaCompilerTool.create(parameters.getRuntime().asCf(), temp)
+            .addSourceFiles(ToolHelper.getSourceFileForTestClass(source))
+            .addAnnotationProcessors(typeName(KeepEdgeProcessor.class))
+            .addClasspathFiles(KEEP_ANNO_PATH)
+            .addClasspathFiles(ToolHelper.DEPS)
+            .compile();
+    testForJvm()
+        .addProgramFiles(out)
+        .run(parameters.getRuntime(), source)
+        .assertSuccessWithOutput(getExpected())
+        .inspect(
+            inspector -> {
+              assertThat(inspector.clazz(source), isPresent());
+              checkSynthesizedKeepEdgeClass(inspector, out);
+            });
+  }
+
+  @Test
+  public void testAsmReader() throws Exception {
+    assumeTrue(parameters.isCfRuntime());
+    Set<KeepEdge> expectedEdges = KeepSourceEdges.getExpectedEdges(source);
+    ClassReference clazz = Reference.classFromClass(source);
+    // Original bytes of the test class.
+    byte[] original = ToolHelper.getClassAsBytes(source);
+    // Strip out all the annotations to ensure they are actually added again.
+    byte[] stripped =
+        transformer(source)
+            .addClassTransformer(
+                new ClassTransformer() {
+                  @Override
+                  public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
+                    // Ignore all input annotations.
+                    return null;
+                  }
+                })
+            .transform();
+    // Manually add in the expected edges again.
+    byte[] readded =
+        transformer(stripped, clazz)
+            .addClassTransformer(
+                new ClassTransformer() {
+
+                  @Override
+                  public void visitEnd() {
+                    for (KeepEdge edge : expectedEdges) {
+                      KeepEdgeWriter.writeEdge(edge, super::visitAnnotation);
+                    }
+                    super.visitEnd();
+                  }
+                })
+            .transform();
+
+    // Read the edges from each version.
+    Set<KeepEdge> originalEdges = KeepEdgeReader.readKeepEdges(original);
+    Set<KeepEdge> strippedEdges = KeepEdgeReader.readKeepEdges(stripped);
+    Set<KeepEdge> readdedEdges = KeepEdgeReader.readKeepEdges(readded);
+
+    // The edges are compared to the "expected" ast to ensure we don't hide failures in reading or
+    // writing.
+    assertEquals(Collections.emptySet(), strippedEdges);
+    assertEquals(expectedEdges, originalEdges);
+    assertEquals(expectedEdges, readdedEdges);
+  }
+
+  @Test
+  public void testExtractAndRun() throws Exception {
+    List<String> rules = getKeepRulesForClass(source);
+    testForR8(parameters.getBackend())
+        .addClasspathFiles(KEEP_ANNO_PATH)
+        .addProgramClassesAndInnerClasses(source)
+        .addKeepRules(rules)
+        .addKeepMainRule(source)
+        .setMinApi(parameters.getApiLevel())
+        .run(parameters.getRuntime(), source)
+        .assertSuccessWithOutput(getExpected());
+  }
+
+  private List<String> getKeepRulesForClass(Class<?> clazz) throws IOException {
+    Set<KeepEdge> keepEdges = KeepEdgeReader.readKeepEdges(ToolHelper.getClassAsBytes(clazz));
+    List<String> rules = new ArrayList<>();
+    KeepRuleExtractor extractor = new KeepRuleExtractor(rules::add);
+    keepEdges.forEach(extractor::extract);
+    return rules;
+  }
+
+  private void checkSynthesizedKeepEdgeClass(CodeInspector inspector, Path data)
+      throws IOException {
+    String synthesizedEdgesClassName =
+        KeepEdgeProcessor.getClassTypeNameForSynthesizedEdges(source.getTypeName());
+    ClassSubject synthesizedEdgesClass = inspector.clazz(synthesizedEdgesClassName);
+    assertThat(synthesizedEdgesClass, isPresent());
+    assertThat(synthesizedEdgesClass.annotation(Edge.CLASS.getTypeName()), isPresent());
+    String entry = ZipUtils.zipEntryNameForClass(synthesizedEdgesClass.getFinalReference());
+    byte[] bytes = ZipUtils.readSingleEntry(data, entry);
+    Set<KeepEdge> keepEdges = KeepEdgeReader.readKeepEdges(bytes);
+    assertEquals(KeepSourceEdges.getExpectedEdges(source), keepEdges);
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/keepanno/asm/KeepEdgeAsmTest.java b/src/test/java/com/android/tools/r8/keepanno/asm/KeepEdgeAsmTest.java
deleted file mode 100644
index b9ebfa2..0000000
--- a/src/test/java/com/android/tools/r8/keepanno/asm/KeepEdgeAsmTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2022, 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.keepanno.asm;
-
-import static org.junit.Assert.assertEquals;
-
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.keepanno.ast.KeepEdge;
-import com.android.tools.r8.keepanno.testsource.KeepClassAndDefaultConstructorSource;
-import com.android.tools.r8.keepanno.testsource.KeepSourceEdges;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.Reference;
-import com.android.tools.r8.transformers.ClassTransformer;
-import java.util.Collections;
-import java.util.Set;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.objectweb.asm.AnnotationVisitor;
-
-@RunWith(Parameterized.class)
-public class KeepEdgeAsmTest extends TestBase {
-
-  private static final Class<?> SOURCE = KeepClassAndDefaultConstructorSource.class;
-
-  @Parameterized.Parameters(name = "{0}")
-  public static TestParametersCollection data() {
-    return getTestParameters().withNoneRuntime().build();
-  }
-
-  public KeepEdgeAsmTest(TestParameters parameters) {
-    parameters.assertNoneRuntime();
-  }
-
-  @Test
-  public void testAsmReader() throws Exception {
-    Set<KeepEdge> expectedEdges = KeepSourceEdges.getExpectedEdges(SOURCE);
-    ClassReference clazz = Reference.classFromClass(SOURCE);
-    // Original bytes of the test class.
-    byte[] original = ToolHelper.getClassAsBytes(SOURCE);
-    // Strip out all the annotations to ensure they are actually added again.
-    byte[] stripped =
-        transformer(SOURCE)
-            .addClassTransformer(
-                new ClassTransformer() {
-                  @Override
-                  public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
-                    // Ignore all input annotations.
-                    return null;
-                  }
-                })
-            .transform();
-    // Manually add in the expected edges again.
-    byte[] readded =
-        transformer(stripped, clazz)
-            .addClassTransformer(
-                new ClassTransformer() {
-
-                  @Override
-                  public void visitEnd() {
-                    for (KeepEdge edge : expectedEdges) {
-                      KeepEdgeWriter.writeEdge(edge, super::visitAnnotation);
-                    }
-                    super.visitEnd();
-                  }
-                })
-            .transform();
-
-    // Read the edges from each version.
-    Set<KeepEdge> originalEdges = KeepEdgeReader.readKeepEdges(original);
-    Set<KeepEdge> strippedEdges = KeepEdgeReader.readKeepEdges(stripped);
-    Set<KeepEdge> readdedEdges = KeepEdgeReader.readKeepEdges(readded);
-
-    // The edges are compared to the "expected" ast to ensure we don't hide failures in reading or
-    // writing.
-    assertEquals(Collections.emptySet(), strippedEdges);
-    assertEquals(expectedEdges, originalEdges);
-    assertEquals(expectedEdges, readdedEdges);
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/keepanno/keeprules/KeepRuleExtractorTest.java b/src/test/java/com/android/tools/r8/keepanno/keeprules/KeepRuleExtractorTest.java
deleted file mode 100644
index 4fa9b42..0000000
--- a/src/test/java/com/android/tools/r8/keepanno/keeprules/KeepRuleExtractorTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) 2022, 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.keepanno.keeprules;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assume.assumeTrue;
-
-import com.android.tools.r8.JavaCompilerTool;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.keepanno.asm.KeepEdgeReader;
-import com.android.tools.r8.keepanno.ast.KeepEdge;
-import com.android.tools.r8.keepanno.processor.KeepEdgeProcessor;
-import com.android.tools.r8.keepanno.testsource.KeepClassAndDefaultConstructorSource;
-import com.android.tools.r8.keepanno.testsource.KeepFieldSource;
-import com.android.tools.r8.keepanno.testsource.KeepSourceEdges;
-import com.android.tools.r8.references.Reference;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.ZipUtils;
-import com.google.common.collect.ImmutableList;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public class KeepRuleExtractorTest extends TestBase {
-
-  private static class ParamWrapper {
-    private final Class<?> clazz;
-    private final TestParameters params;
-
-    public ParamWrapper(Class<?> clazz, TestParameters params) {
-      this.clazz = clazz;
-      this.params = params;
-    }
-
-    @Override
-    public String toString() {
-      return clazz.getSimpleName() + ", " + params.toString();
-    }
-  }
-
-  private static final Path KEEP_ANNO_PATH =
-      Paths.get(ToolHelper.BUILD_DIR, "classes", "java", "keepanno");
-
-  private static List<Class<?>> getTestClasses() {
-    return ImmutableList.of(KeepClassAndDefaultConstructorSource.class, KeepFieldSource.class);
-  }
-
-  private final TestParameters parameters;
-  private final Class<?> source;
-
-  @Parameterized.Parameters(name = "{0}")
-  public static List<ParamWrapper> data() {
-    TestParametersCollection params =
-        getTestParameters().withDefaultRuntimes().withApiLevel(AndroidApiLevel.B).build();
-    return getTestClasses().stream()
-        .flatMap(c -> params.stream().map(p -> new ParamWrapper(c, p)))
-        .collect(Collectors.toList());
-  }
-
-  public KeepRuleExtractorTest(ParamWrapper wrapper) {
-    this.parameters = wrapper.params;
-    this.source = wrapper.clazz;
-  }
-
-  @Test
-  public void testProcessor() throws Exception {
-    assumeTrue(parameters.isCfRuntime());
-    Path out =
-        JavaCompilerTool.create(parameters.getRuntime().asCf(), temp)
-            .addAnnotationProcessors(typeName(KeepEdgeProcessor.class))
-            .addClasspathFiles(KEEP_ANNO_PATH)
-            .addClassNames(Collections.singletonList(typeName(source)))
-            .addClasspathFiles(Paths.get(ToolHelper.BUILD_DIR, "classes", "java", "test"))
-            .addClasspathFiles(ToolHelper.DEPS)
-            .compile();
-
-    String synthesizedEdgesClassName =
-        KeepEdgeProcessor.getClassTypeNameForSynthesizedEdges(source.getTypeName());
-    String entry =
-        ZipUtils.zipEntryNameForClass(Reference.classFromTypeName(synthesizedEdgesClassName));
-    byte[] bytes = ZipUtils.readSingleEntry(out, entry);
-    Set<KeepEdge> keepEdges = KeepEdgeReader.readKeepEdges(bytes);
-    assertEquals(KeepSourceEdges.getExpectedEdges(source), keepEdges);
-  }
-
-  @Test
-  public void testExtract() throws Exception {
-    List<String> rules = getKeepRulesForClass(source);
-    testForR8(parameters.getBackend())
-        .addClasspathFiles(KEEP_ANNO_PATH)
-        .addProgramClassesAndInnerClasses(source)
-        .addKeepRules(rules)
-        .addKeepMainRule(source)
-        .setMinApi(parameters.getApiLevel())
-        .run(parameters.getRuntime(), source)
-        .assertSuccessWithOutput(KeepSourceEdges.getExpected(source));
-  }
-
-  private List<String> getKeepRulesForClass(Class<?> clazz) throws IOException {
-    Set<KeepEdge> keepEdges = KeepEdgeReader.readKeepEdges(ToolHelper.getClassAsBytes(clazz));
-    List<String> rules = new ArrayList<>();
-    KeepRuleExtractor extractor = new KeepRuleExtractor(rules::add);
-    keepEdges.forEach(extractor::extract);
-    return rules;
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/keepanno/processor/KeepEdgeProcessorTest.java b/src/test/java/com/android/tools/r8/keepanno/processor/KeepEdgeProcessorTest.java
deleted file mode 100644
index 83f60a3..0000000
--- a/src/test/java/com/android/tools/r8/keepanno/processor/KeepEdgeProcessorTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2022, 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.keepanno.processor;
-
-import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-
-import com.android.tools.r8.JavaCompilerTool;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.keepanno.annotations.KeepConstants.Edge;
-import com.android.tools.r8.keepanno.asm.KeepEdgeReader;
-import com.android.tools.r8.keepanno.ast.KeepEdge;
-import com.android.tools.r8.keepanno.testsource.KeepClassAndDefaultConstructorSource;
-import com.android.tools.r8.keepanno.testsource.KeepSourceEdges;
-import com.android.tools.r8.utils.ZipUtils;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Collections;
-import java.util.Set;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public class KeepEdgeProcessorTest extends TestBase {
-
-  private static final Path KEEP_ANNO_PATH =
-      Paths.get(ToolHelper.BUILD_DIR, "classes", "java", "keepanno");
-  private static final Class<?> SOURCE = KeepClassAndDefaultConstructorSource.class;
-  private static final String EXPECTED = KeepSourceEdges.getExpected(SOURCE);
-
-  private final TestParameters parameters;
-
-  @Parameterized.Parameters(name = "{0}")
-  public static TestParametersCollection data() {
-    return getTestParameters().withDefaultCfRuntime().build();
-  }
-
-  public KeepEdgeProcessorTest(TestParameters parameters) {
-    this.parameters = parameters;
-  }
-
-  @Test
-  public void testClassfile() throws Exception {
-    Path out =
-        JavaCompilerTool.create(parameters.getRuntime().asCf(), temp)
-            .addAnnotationProcessors(typeName(KeepEdgeProcessor.class))
-            .addClasspathFiles(KEEP_ANNO_PATH)
-            .addClassNames(Collections.singletonList(typeName(SOURCE)))
-            .addClasspathFiles(Paths.get(ToolHelper.BUILD_DIR, "classes", "java", "test"))
-            .addClasspathFiles(ToolHelper.DEPS)
-            .compile();
-
-    CodeInspector inspector = new CodeInspector(out);
-    checkSynthesizedKeepEdgeClass(inspector, out);
-    // The source is added as a classpath name but not part of the compilation unit output.
-    assertThat(inspector.clazz(SOURCE), isAbsent());
-
-    testForJvm()
-        .addProgramClasses(SOURCE, KeepClassAndDefaultConstructorSource.A.class)
-        .addProgramFiles(out)
-        .run(parameters.getRuntime(), SOURCE)
-        .assertSuccessWithOutput(EXPECTED);
-  }
-
-  @Test
-  public void testJavaSource() throws Exception {
-    Path out =
-        JavaCompilerTool.create(parameters.getRuntime().asCf(), temp)
-            .addSourceFiles(ToolHelper.getSourceFileForTestClass(SOURCE))
-            .addAnnotationProcessors(typeName(KeepEdgeProcessor.class))
-            .addClasspathFiles(KEEP_ANNO_PATH)
-            .addClasspathFiles(ToolHelper.DEPS)
-            .compile();
-
-    testForJvm()
-        .addProgramFiles(out)
-        .run(parameters.getRuntime(), SOURCE)
-        .assertSuccessWithOutput(EXPECTED)
-        .inspect(
-            inspector -> {
-              assertThat(inspector.clazz(SOURCE), isPresent());
-              checkSynthesizedKeepEdgeClass(inspector, out);
-            });
-  }
-
-  private void checkSynthesizedKeepEdgeClass(CodeInspector inspector, Path data)
-      throws IOException {
-    String synthesizedEdgesClassName =
-        KeepEdgeProcessor.getClassTypeNameForSynthesizedEdges(SOURCE.getTypeName());
-    ClassSubject synthesizedEdgesClass = inspector.clazz(synthesizedEdgesClassName);
-    assertThat(synthesizedEdgesClass, isPresent());
-    assertThat(synthesizedEdgesClass.annotation(Edge.CLASS.getTypeName()), isPresent());
-    String entry = ZipUtils.zipEntryNameForClass(synthesizedEdgesClass.getFinalReference());
-    byte[] bytes = ZipUtils.readSingleEntry(data, entry);
-    Set<KeepEdge> keepEdges = KeepEdgeReader.readKeepEdges(bytes);
-    assertEquals(KeepSourceEdges.getExpectedEdges(SOURCE), keepEdges);
-  }
-}
