diff --git a/src/main/java/com/android/tools/r8/SwissArmyKnife.java b/src/main/java/com/android/tools/r8/SwissArmyKnife.java
index dd7da82..f079277 100644
--- a/src/main/java/com/android/tools/r8/SwissArmyKnife.java
+++ b/src/main/java/com/android/tools/r8/SwissArmyKnife.java
@@ -5,7 +5,6 @@
 
 import com.android.tools.r8.bisect.Bisect;
 import com.android.tools.r8.compatproguard.CompatProguard;
-import com.android.tools.r8.dexfilemerger.DexFileMerger;
 import com.android.tools.r8.dexsplitter.DexSplitter;
 import com.android.tools.r8.relocator.RelocatorCommandLine;
 import java.util.Arrays;
@@ -37,9 +36,6 @@
       case "d8":
         D8.main(shift(args));
         break;
-      case "dexfilemerger":
-        DexFileMerger.main(shift(args));
-        break;
       case "dexsegments":
         DexSegments.main(shift(args));
         break;
diff --git a/src/main/java/com/android/tools/r8/dexfilemerger/DexFileMerger.java b/src/main/java/com/android/tools/r8/dexfilemerger/DexFileMerger.java
deleted file mode 100644
index 7cbf816..0000000
--- a/src/main/java/com/android/tools/r8/dexfilemerger/DexFileMerger.java
+++ /dev/null
@@ -1,403 +0,0 @@
-// Copyright (c) 2017, 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.dexfilemerger;
-
-import com.android.tools.r8.ByteDataView;
-import com.android.tools.r8.CompilationFailedException;
-import com.android.tools.r8.D8Command;
-import com.android.tools.r8.DexFileMergerHelper;
-import com.android.tools.r8.DexIndexedConsumer;
-import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.origin.PathOrigin;
-import com.android.tools.r8.utils.ExceptionDiagnostic;
-import com.android.tools.r8.utils.FileUtils;
-import com.android.tools.r8.utils.OptionsParsing;
-import com.android.tools.r8.utils.OptionsParsing.ParseContext;
-import com.android.tools.r8.utils.StringDiagnostic;
-import com.android.tools.r8.utils.ZipUtils;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-public class DexFileMerger {
-  /** File name prefix of a {@code .dex} file automatically loaded in an archive. */
-  private static final String DEX_PREFIX = "classes";
-
-  private static final String DEFAULT_OUTPUT_ARCHIVE_FILENAME = "classes.dex.jar";
-
-  private static final boolean PRINT_ARGS = false;
-
-  /** Strategies for outputting multiple {@code .dex} files supported by {@link DexFileMerger}. */
-  private enum MultidexStrategy {
-    /** Create exactly one .dex file. The operation will fail if .dex limits are exceeded. */
-    OFF,
-    /** Create exactly one &lt;prefixN&gt;.dex file with N taken from the (single) input archive. */
-    GIVEN_SHARD,
-    /**
-     * Assemble .dex files similar to {@link com.android.dx.command.dexer.Main dx}, with all but one
-     * file as large as possible.
-     */
-    MINIMAL,
-    /**
-     * Allow some leeway and sometimes use additional .dex files to speed up processing. This option
-     * exists to give flexibility but it often (or always) may be identical to {@link #MINIMAL}.
-     */
-    BEST_EFFORT;
-
-    public boolean isMultidexAllowed() {
-      switch (this) {
-        case OFF:
-        case GIVEN_SHARD:
-          return false;
-        case MINIMAL:
-        case BEST_EFFORT:
-          return true;
-      }
-      throw new AssertionError("Unknown: " + this);
-    }
-
-    public static MultidexStrategy parse(String value) {
-      switch (value) {
-        case "off":
-          return OFF;
-        case "given_shard":
-          return GIVEN_SHARD;
-        case "minimal":
-          return MINIMAL;
-        case "best_effort":
-          return BEST_EFFORT;
-        default:
-          throw new RuntimeException(
-              "Multidex argument must be either 'off', 'given_shard', 'minimal' or 'best_effort'.");
-      }
-    }
-  }
-
-  private static class Options {
-    List<String> inputArchives = new ArrayList<>();
-    String outputArchive = DEFAULT_OUTPUT_ARCHIVE_FILENAME;
-    MultidexStrategy multidexMode = MultidexStrategy.OFF;
-    String mainDexListFile = null;
-    boolean minimalMainDex = false;
-    boolean verbose = false;
-    String dexPrefix = DEX_PREFIX;
-  }
-
-
-  private static Options parseArguments(String[] args) throws IOException {
-    // We may have a single argument which is a parameter file path, prefixed with '@'.
-    if (args.length == 1 && args[0].startsWith("@")) {
-      // TODO(tamaskenez) Implement more sophisticated processing
-      // which is aligned with Blaze's
-      // com.google.devtools.common.options.ShellQuotedParamsFilePreProcessor
-      Path paramsFile = Paths.get(args[0].substring(1));
-      List<String> argsList = new ArrayList<>();
-      for (String s : Files.readAllLines(paramsFile)) {
-        s = s.trim();
-        if (s.isEmpty()) {
-          continue;
-        }
-        // Trim optional enclosing single quotes. Unescaping omitted for now.
-        if (s.length() >= 2 && s.startsWith("'") && s.endsWith("'")) {
-          s = s.substring(1, s.length() - 1);
-        }
-        argsList.add(s);
-      }
-      args = argsList.toArray(new String[argsList.size()]);
-    }
-
-    Options options = new Options();
-    ParseContext context = new ParseContext(args);
-    List<String> strings;
-    String string;
-    Boolean b;
-    while (context.head() != null) {
-      if (context.head().startsWith("@")) {
-        throw new RuntimeException("A params file must be the only argument: " + context.head());
-      }
-      strings = OptionsParsing.tryParseMulti(context, "--input");
-      if (strings != null) {
-        options.inputArchives.addAll(strings);
-        continue;
-      }
-      string = OptionsParsing.tryParseSingle(context, "--output", "-o");
-      if (string != null) {
-        options.outputArchive = string;
-        continue;
-      }
-      string = OptionsParsing.tryParseSingle(context, "--multidex", null);
-      if (string != null) {
-        options.multidexMode = MultidexStrategy.parse(string);
-        continue;
-      }
-      string = OptionsParsing.tryParseSingle(context, "--main-dex-list", null);
-      if (string != null) {
-        options.mainDexListFile = string;
-        continue;
-      }
-      b = OptionsParsing.tryParseBoolean(context, "--minimal-main-dex");
-      if (b != null) {
-        options.minimalMainDex = b;
-        continue;
-      }
-      b = OptionsParsing.tryParseBoolean(context, "--verbose");
-      if (b != null) {
-        options.verbose = b;
-        continue;
-      }
-      string = OptionsParsing.tryParseSingle(context, "--max-bytes-wasted-per-file", null);
-      if (string != null) {
-        System.err.println("Warning: '--max-bytes-wasted-per-file' is ignored.");
-        continue;
-      }
-      string = OptionsParsing.tryParseSingle(context, "--set-max-idx-number", null);
-      if (string != null) {
-        System.err.println("Warning: The '--set-max-idx-number' option is ignored.");
-        continue;
-      }
-      b = OptionsParsing.tryParseBoolean(context, "--forceJumbo");
-      if (b != null) {
-        System.err.println(
-            "Warning: '--forceJumbo' can be safely omitted. Strings will only use "
-                + "jumbo-string indexing if necessary.");
-        continue;
-      }
-      string = OptionsParsing.tryParseSingle(context, "--dex_prefix", null);
-      if (string != null) {
-        options.dexPrefix = string;
-        continue;
-      }
-      throw new RuntimeException(String.format("Unknown options: '%s'.", context.head()));
-    }
-    return options;
-  }
-
-  /**
-   * Implements a DexIndexedConsumer writing into a ZipStream with support for custom dex file name
-   * prefix, reindexing a single dex output file to a nonzero index and reporting if any data has
-   * been written.
-   */
-  private static class ArchiveConsumer implements DexIndexedConsumer {
-    private final Path path;
-    private final String prefix;
-    private final Integer singleFixedFileIndex;
-    private final Origin origin;
-    private ZipOutputStream stream = null;
-
-    private int highestIndexWritten = -1;
-    private final Map<Integer, Runnable> writers = new TreeMap<>();
-    private boolean hasWrittenSomething = false;
-
-    /** If singleFixedFileIndex is not null then we expect only one output dex file */
-    private ArchiveConsumer(Path path, String prefix, Integer singleFixedFileIndex) {
-      this.path = path;
-      this.prefix = prefix;
-      this.singleFixedFileIndex = singleFixedFileIndex;
-      this.origin = new PathOrigin(path);
-    }
-
-    private boolean hasWrittenSomething() {
-      return hasWrittenSomething;
-    }
-
-    private String getDexFileName(int fileIndex) {
-      if (singleFixedFileIndex != null) {
-        fileIndex = singleFixedFileIndex;
-      }
-      return prefix + (fileIndex == 0 ? "" : (fileIndex + 1)) + FileUtils.DEX_EXTENSION;
-    }
-
-    @Override
-    public synchronized void accept(
-        int fileIndex, ByteDataView data, Set<String> descriptors, DiagnosticsHandler handler) {
-      if (singleFixedFileIndex != null && fileIndex != 0) {
-        handler.error(new StringDiagnostic("Result does not fit into a single dex file."));
-        return;
-      }
-      // Make a copy of the actual bytes as they will possibly be accessed later by the runner.
-      final byte[] bytes = data.copyByteData();
-      writers.put(fileIndex, () -> writeEntry(fileIndex, bytes, descriptors, handler));
-
-      while (writers.containsKey(highestIndexWritten + 1)) {
-        ++highestIndexWritten;
-        writers.get(highestIndexWritten).run();
-        writers.remove(highestIndexWritten);
-      }
-    }
-
-    /** Get or open the zip output stream. */
-    private synchronized ZipOutputStream getStream(DiagnosticsHandler handler) {
-      if (stream == null) {
-        try {
-          stream =
-              new ZipOutputStream(
-                  Files.newOutputStream(
-                      path, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING));
-        } catch (IOException e) {
-          handler.error(new ExceptionDiagnostic(e, origin));
-        }
-      }
-      return stream;
-    }
-
-    private void writeEntry(
-        int fileIndex, byte[] data, Set<String> descriptors, DiagnosticsHandler handler) {
-      try {
-        ZipUtils.writeToZipStream(
-            getStream(handler),
-            getDexFileName(fileIndex),
-            ByteDataView.of(data),
-            ZipEntry.DEFLATED);
-        hasWrittenSomething = true;
-      } catch (IOException e) {
-        handler.error(new ExceptionDiagnostic(e, origin));
-      }
-    }
-
-    @Override
-    public void finished(DiagnosticsHandler handler) {
-      if (!writers.isEmpty()) {
-        handler.error(
-            new StringDiagnostic(
-                "Failed to write zip, for a multidex output some of the classes.dex files were"
-                    + " not produced."));
-      }
-      try {
-        if (stream != null) {
-          stream.close();
-          stream = null;
-        }
-      } catch (IOException e) {
-        handler.error(new ExceptionDiagnostic(e, origin));
-      }
-    }
-  }
-
-  private static int parseFileIndexFromShardFilename(String inputArchive) {
-    Pattern namingPattern = Pattern.compile("([0-9]+)\\..*");
-    String name = new File(inputArchive).getName();
-    Matcher matcher = namingPattern.matcher(name);
-    if (!matcher.matches()) {
-      throw new RuntimeException(
-          String.format(
-              "Expect input named <N>.xxx.zip for --multidex=given_shard but got %s.", name));
-    }
-    int shard = Integer.parseInt(matcher.group(1));
-    if (shard <= 0) {
-      throw new RuntimeException(
-          String.format("Expect positive N in input named <N>.xxx.zip but got %d.", shard));
-    }
-    return shard;
-  }
-
-  public static void run(String[] args) throws CompilationFailedException, IOException {
-    Options options = parseArguments(args);
-
-    if (options.inputArchives.isEmpty()) {
-      throw new RuntimeException("Need at least one --input");
-    }
-
-    if (options.mainDexListFile != null && options.inputArchives.size() != 1) {
-      throw new RuntimeException(
-          "--main-dex-list only supported with exactly one --input, use DexFileSplitter for more");
-    }
-
-    if (!options.multidexMode.isMultidexAllowed()) {
-      if (options.mainDexListFile != null) {
-        throw new RuntimeException(
-            "--main-dex-list is only supported with multidex enabled, but mode is: "
-                + options.multidexMode.toString());
-      }
-      if (options.minimalMainDex) {
-        throw new RuntimeException(
-            "--minimal-main-dex is only supported with multidex enabled, but mode is: "
-                + options.multidexMode.toString());
-      }
-    }
-
-    D8Command.Builder builder = D8Command.builder();
-
-    Map<String, Integer> inputOrdering = new HashMap<>(options.inputArchives.size());
-    int sequenceNumber = 0;
-    for (String s : options.inputArchives) {
-      builder.addProgramFiles(Paths.get(s));
-      inputOrdering.put(s, sequenceNumber++);
-    }
-
-    // Determine enabling multidexing and file indexing.
-    Integer singleFixedFileIndex = null;
-    switch (options.multidexMode) {
-      case OFF:
-        singleFixedFileIndex = 0;
-        break;
-      case GIVEN_SHARD:
-        if (options.inputArchives.size() != 1) {
-          throw new RuntimeException("'--multidex=given_shard' requires exactly one --input.");
-        }
-        singleFixedFileIndex = parseFileIndexFromShardFilename(options.inputArchives.get(0)) - 1;
-        break;
-      case MINIMAL:
-      case BEST_EFFORT:
-        // Nothing to do.
-        break;
-      default:
-        throw new Unreachable("Unexpected enum: " + options.multidexMode);
-    }
-
-    if (options.mainDexListFile != null) {
-      builder.addMainDexListFiles(Paths.get(options.mainDexListFile));
-    }
-
-    ArchiveConsumer consumer =
-        new ArchiveConsumer(
-            Paths.get(options.outputArchive), options.dexPrefix, singleFixedFileIndex);
-    builder.setProgramConsumer(consumer);
-
-    DexFileMergerHelper.run(builder.build(), options.minimalMainDex, inputOrdering);
-
-    // If input was empty we still need to write out an empty zip.
-    if (!consumer.hasWrittenSomething()) {
-      File f = new File(options.outputArchive);
-      ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f));
-      out.close();
-    }
-  }
-
-  public static void main(String[] args) {
-    try {
-      if (PRINT_ARGS) {
-        printArgs(args);
-      }
-      run(args);
-    } catch (CompilationFailedException | IOException e) {
-      System.err.println("Merge failed: " + e.getMessage());
-      System.exit(1);
-    }
-  }
-
-  private static void printArgs(String[] args) {
-    System.err.print("r8.DexFileMerger");
-    for (String s : args) {
-      System.err.printf(" %s", s);
-    }
-    System.err.println("");
-  }
-}
diff --git a/src/main/keep.txt b/src/main/keep.txt
index 083584f..7791d4e 100644
--- a/src/main/keep.txt
+++ b/src/main/keep.txt
@@ -8,7 +8,6 @@
 -keep public class com.android.tools.r8.D8 { public static void main(java.lang.String[]); }
 -keep public class com.android.tools.r8.R8 { public static void main(java.lang.String[]); }
 -keep public class com.android.tools.r8.ExtractMarker { public static void main(java.lang.String[]); }
--keep public class com.android.tools.r8.dexfilemerger.DexFileMerger { public static void main(java.lang.String[]); }
 -keep public class com.android.tools.r8.dexsplitter.DexSplitter { public static void main(java.lang.String[]); }
 
 -keep public class com.android.tools.r8.Version { public static java.lang.String getVersionString(); }
diff --git a/src/test/java/com/android/tools/r8/dexfilemerger/DexFileMergerTests.java b/src/test/java/com/android/tools/r8/dexfilemerger/DexFileMergerTests.java
deleted file mode 100644
index 91364d4..0000000
--- a/src/test/java/com/android/tools/r8/dexfilemerger/DexFileMergerTests.java
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright (c) 2017, 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.dexfilemerger;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import com.android.tools.r8.CompilationFailedException;
-import com.android.tools.r8.D8;
-import com.android.tools.r8.D8Command;
-import com.android.tools.r8.DexFileMergerHelper;
-import com.android.tools.r8.ExtractMarker;
-import com.android.tools.r8.OutputMode;
-import com.android.tools.r8.ResourceException;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.ToolHelper.ArtCommandBuilder;
-import com.android.tools.r8.dex.Constants;
-import com.android.tools.r8.dex.Marker;
-import com.android.tools.r8.maindexlist.MainDexListTests;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.AndroidApp;
-import com.google.common.collect.ImmutableList;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Collection;
-import java.util.concurrent.ExecutionException;
-import org.junit.Test;
-
-public class DexFileMergerTests extends TestBase {
-
-  private static final String CLASS_DIR = ToolHelper.EXAMPLES_BUILD_DIR + "classes/dexmergesample";
-  private static final String CLASS1_CLASS = CLASS_DIR + "/Class1.class";
-  private static final String CLASS2_CLASS = CLASS_DIR + "/Class2.class";
-  private static final int MAX_METHOD_COUNT = Constants.U16BIT_MAX;
-
-  private Path createMergerInputWithTwoClasses(OutputMode outputMode, boolean addMarker)
-      throws CompilationFailedException, IOException {
-    // Compile Class1 and Class2
-    Path mergerInputZip = temp.newFolder().toPath().resolve("merger-input.zip");
-    D8Command command =
-        D8Command.builder()
-            .setOutput(mergerInputZip, outputMode)
-            .addProgramFiles(Paths.get(CLASS1_CLASS))
-            .addProgramFiles(Paths.get(CLASS2_CLASS))
-            .build();
-
-    DexFileMergerHelper.runD8ForTesting(command, !addMarker);
-
-    return mergerInputZip;
-  }
-
-  private void testMarker(boolean addMarkerToInput)
-      throws CompilationFailedException, IOException, ResourceException, ExecutionException {
-    Path mergerInputZip = createMergerInputWithTwoClasses(OutputMode.DexIndexed, addMarkerToInput);
-    int expectedNumberOfMarkers = addMarkerToInput ? 1 : 0;
-
-    Collection<Marker> inputMarkers = ExtractMarker.extractMarkerFromDexFile(mergerInputZip);
-    assertEquals(expectedNumberOfMarkers, inputMarkers.size());
-
-    // Test that the DexFileMerger preserves markers.
-    Path mergerOutputZip = temp.getRoot().toPath().resolve("merger-out.zip");
-    DexFileMerger.main(
-        new String[] {
-          "--input", mergerInputZip.toString(), "--output", mergerOutputZip.toString()
-        });
-    Collection<Marker> outputMarkers = ExtractMarker.extractMarkerFromDexFile(mergerOutputZip);
-    assertEquals(expectedNumberOfMarkers, outputMarkers.size());
-
-    // Test that D8 when used for merging preserves markers.
-    D8.main(new String[] { mergerInputZip.toString(), "--output", mergerOutputZip.toString() });
-    Collection<Marker> d8OutputMarkers = ExtractMarker.extractMarkerFromDexFile((mergerOutputZip));
-    assertEquals(expectedNumberOfMarkers, d8OutputMarkers.size());
-  }
-
-  @Test
-  public void testMarkerPreserved()
-      throws CompilationFailedException, IOException, ResourceException, ExecutionException {
-    testMarker(true);
-  }
-
-  @Test
-  public void testMarkerNotAdded()
-      throws CompilationFailedException, IOException, ResourceException, ExecutionException {
-    testMarker(false);
-  }
-
-  @Test
-  public void mergeTwoFiles() throws CompilationFailedException, IOException {
-    Path mergerInputZip = createMergerInputWithTwoClasses(OutputMode.DexFilePerClassFile, false);
-
-    Path mergerOutputZip = temp.getRoot().toPath().resolve("merger-out.zip");
-    DexFileMerger.main(
-        new String[] {
-          "--input", mergerInputZip.toString(), "--output", mergerOutputZip.toString()
-        });
-
-    // Test by running methods of Class1 and Class2
-    for (String className : new String[] {"Class1", "Class2"}) {
-      ArtCommandBuilder builder = new ArtCommandBuilder();
-      builder.appendClasspath(mergerOutputZip.toString());
-      builder.setMainClass("dexmergesample." + className);
-      String out = ToolHelper.runArt(builder);
-      assertEquals(out, className + "\n");
-    }
-  }
-
-  private void generateClassesAndTest(int extraMethodCount, int programResourcesSize)
-      throws IOException, ExecutionException, CompilationFailedException {
-    AndroidApp generatedApp =
-        MainDexListTests.generateApplication(
-            ImmutableList.of("A", "B"),
-            AndroidApiLevel.N.getLevel(),
-            MAX_METHOD_COUNT / 2 + 1 + extraMethodCount);
-    Path appDir = temp.newFolder().toPath().resolve("merger-input.zip");
-    assertEquals(programResourcesSize, generatedApp.getDexProgramResourcesForTesting().size());
-    generatedApp.write(appDir, OutputMode.DexIndexed);
-
-    Path outZip = temp.getRoot().toPath().resolve("out.zip");
-    DexFileMerger.run(
-        new String[] {
-          "--input", appDir.toString(), "--output", outZip.toString(), "--multidex=off"
-        });
-  }
-
-  @Test
-  public void failIfTooBig() throws IOException, ExecutionException {
-    // Generates an application with two classes, each with the number of methods just enough not to
-    // fit into a single dex file.
-    try {
-      generateClassesAndTest(1, 2);
-      fail("Expect to fail");
-    } catch (CompilationFailedException e) {
-      assertThat(e.getCause().getMessage(), containsString("does not fit into a single dex file"));
-    }
-  }
-
-  @Test
-  public void failIfTooBigControl()
-      throws IOException, ExecutionException, CompilationFailedException {
-    // Control test for failIfTooBig to make sure we don't fail with less methods.
-    generateClassesAndTest(0, 1);
-  }
-}
