The list dex command should generate an error when used on a non-zip/oat file
diff --git a/baksmali/src/main/java/org/jf/baksmali/ListDexCommand.java b/baksmali/src/main/java/org/jf/baksmali/ListDexCommand.java
index 65aa1ec..435d554 100644
--- a/baksmali/src/main/java/org/jf/baksmali/ListDexCommand.java
+++ b/baksmali/src/main/java/org/jf/baksmali/ListDexCommand.java
@@ -35,20 +35,15 @@
 import com.beust.jcommander.Parameter;
 import com.beust.jcommander.Parameters;
 import com.google.common.collect.Lists;
-import org.jf.dexlib2.dexbacked.OatFile;
-import org.jf.dexlib2.dexbacked.raw.HeaderItem;
-import org.jf.dexlib2.dexbacked.raw.OdexHeaderItem;
+import org.jf.dexlib2.DexFileFactory;
 import org.jf.util.jcommander.Command;
 import org.jf.util.jcommander.ExtendedParameter;
 import org.jf.util.jcommander.ExtendedParameters;
 
 import javax.annotation.Nonnull;
-import java.io.*;
-import java.util.Collections;
+import java.io.File;
+import java.io.IOException;
 import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
 
 @Parameters(commandDescription = "Lists the dex files in an apk/oat file.")
 @ExtendedParameters(
@@ -85,53 +80,18 @@
 
         if (!file.exists()) {
             System.err.println(String.format("Could not find the file: %s", input));
+            System.exit(-1);
         }
 
+        List<String> entries;
         try {
-            ZipFile zipFile = new ZipFile(input);
-
-            byte[] magic = new byte[8];
-
-            for (ZipEntry zipEntry : Collections.list(zipFile.entries())) {
-                try {
-                    InputStream inputStream = zipFile.getInputStream(zipEntry);
-
-                    int totalBytesRead = 0;
-                    while (totalBytesRead < 8) {
-                        int bytesRead = inputStream.read(magic, totalBytesRead, 8 - totalBytesRead);
-                        if (bytesRead == -1) {
-                            break;
-                        }
-                        totalBytesRead += bytesRead;
-                    }
-
-                    if (totalBytesRead == 8) {
-                        if (HeaderItem.verifyMagic(magic, 0) || OdexHeaderItem.verifyMagic(magic)) {
-                            System.out.println(zipEntry.getName());
-                        }
-                    }
-                } catch (ZipException ex) {
-                    // ignore and keep looking
-                    continue;
-                }
-            }
-        } catch (ZipException ex) {
-            // ignore
+            entries = DexFileFactory.getAllDexEntries(file);
         } catch (IOException ex) {
             throw new RuntimeException(ex);
         }
 
-        try {
-            InputStream inputStream = new BufferedInputStream(new FileInputStream(input));
-            OatFile oatFile = OatFile.fromInputStream(inputStream);
-
-            for (OatFile.OatDexFile oatDexFile: oatFile.getDexFiles()) {
-                System.out.println(oatDexFile.filename);
-            }
-        } catch (OatFile.NotAnOatFileException ex) {
-            // just eat it
-        } catch (IOException ex) {
-            throw new RuntimeException(ex);
+        for (String entry: entries) {
+            System.out.println(entry);
         }
     }
 }
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java b/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java
index 4bb9f9f..81c7310 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java
@@ -35,6 +35,7 @@
 import com.google.common.collect.AbstractIterator;
 import com.google.common.collect.Lists;
 import org.jf.dexlib2.dexbacked.DexBackedDexFile;
+import org.jf.dexlib2.dexbacked.DexBackedDexFile.NotADexFile;
 import org.jf.dexlib2.dexbacked.DexBackedOdexFile;
 import org.jf.dexlib2.dexbacked.OatFile;
 import org.jf.dexlib2.dexbacked.OatFile.NotAnOatFileException;
@@ -249,10 +250,10 @@
      *
      * @param file The file to open
      * @param opcodes The set of opcodes to use
-     * @return A DexBackedDexFile for the given file
+     * @return An iterable of DexBackedDexFiles
      * @throws IOException
      * @throws DexFileNotFoundException If the given file does not exist
-     * @throws UnsupportedFileTypeException If the given file is not a dex, odex, zip or oat file
+     * @throws UnsupportedFileTypeException If the given file is not a zip or oat file
      */
     public static Iterable<? extends DexBackedDexFile> loadAllDexFiles(
             @Nonnull File file, @Nonnull final Opcodes opcodes) throws IOException {
@@ -284,6 +285,8 @@
                                     } catch (IOException ex) {
                                         throw new ExceptionWithContext(ex, "Error while reading %s from %s",
                                                 zipEntry.getName(), finalZipFile.getName());
+                                    } catch (NotADexFile ex) {
+                                        // ignore and continue
                                     }
                                 }
                             }
@@ -331,7 +334,80 @@
         }
 
         throw new UnsupportedFileTypeException("%s is not an apk, dex, odex or oat file.", file.getPath());
+    }
 
+    /**
+     * Gets all dex entries from an oat/zip file.
+     *
+     * For zip files, only entries that match classes[0-9]*.dex will be returned.
+     *
+     * @param file The file to get dex entries from
+
+     * @return A list of strings contains the dex entry names
+     * @throws IOException
+     * @throws DexFileNotFoundException If the given file does not exist
+     * @throws UnsupportedFileTypeException If the given file is not a zip or oat file
+     */
+    public static List<String> getAllDexEntries(@Nonnull File file) throws IOException {
+        if (!file.exists()) {
+            throw new DexFileNotFoundException("%s does not exist", file.getName());
+        }
+
+        List<String> entries = Lists.newArrayList();
+        Opcodes opcodes = Opcodes.forApi(15);
+
+        ZipFile zipFile = null;
+        try {
+            zipFile = new ZipFile(file);
+        } catch (IOException ex) {
+            // ignore and continue
+        }
+
+        if (zipFile != null) {
+            Pattern dexPattern = Pattern.compile("classes[0-9]*.dex");
+            Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
+
+            while (zipEntries.hasMoreElements()) {
+                ZipEntry zipEntry = zipEntries.nextElement();
+                if (dexPattern.matcher(zipEntry.getName()).matches()) {
+                    try {
+                        loadDexFromZip(zipFile, zipEntry, opcodes);
+                        entries.add(zipEntry.getName());
+                    } catch (IOException ex) {
+                        throw new IOException(String.format("Error while reading %s from %s",
+                                zipEntry.getName(), zipFile.getName()), ex);
+                    }catch (NotADexFile ex) {
+                        // ignore and continue
+                    }
+                }
+            }
+            return entries;
+        }
+
+        InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
+        try {
+            OatFile oatFile = null;
+            try {
+                oatFile = OatFile.fromInputStream(inputStream);
+            } catch (NotAnOatFileException ex) {
+                // just eat it
+            }
+
+            if (oatFile != null) {
+                if (oatFile.isSupportedVersion() == OatFile.UNSUPPORTED) {
+                    throw new UnsupportedOatVersionException(oatFile);
+                }
+
+                for (OatDexFile oatDexFile: oatFile.getDexFiles()) {
+                    entries.add(oatDexFile.filename);
+                }
+                return entries;
+            }
+        } finally {
+            inputStream.close();
+        }
+
+        throw new UnsupportedFileTypeException("%s is not an apk, oat file.", file.getPath());
     }
 
     /**