diff --git a/dx/etc/mainDexClasses b/dx/etc/mainDexClasses
index 034d47e..28c0f0c 100755
--- a/dx/etc/mainDexClasses
+++ b/dx/etc/mainDexClasses
@@ -155,4 +155,4 @@
   -libraryjars "${shrinkedAndroidJar}" -dontoptimize -dontobfuscate -dontpreverify \
   -include "${baserules}" 1>/dev/null || exit 10
 
-java -cp "$jarpath" com.android.multidex.ClassReferenceListBuilder "${tmpOut}" ${@} ||  exit 11
+java -cp "$jarpath" com.android.multidex.MainDexListBuilder "${tmpOut}" ${@} ||  exit 11
diff --git a/dx/etc/mainDexClasses.bat b/dx/etc/mainDexClasses.bat
index 00b60e8..f6a4b56 100755
--- a/dx/etc/mainDexClasses.bat
+++ b/dx/etc/mainDexClasses.bat
@@ -96,10 +96,10 @@
 call "%proguard%" -injars %params% -dontwarn -forceprocessing  -outjars "%tmpJar%" -libraryjars "%shrinkedAndroidJar%" -dontoptimize -dontobfuscate -dontpreverify -include "%baserules%" 1>nul
 
 if DEFINED output goto redirect
-call "%java_exe%" -Djava.ext.dirs="%frameworkdir%" com.android.multidex.ClassReferenceListBuilder "%tmpJar%" "%params%"
+call "%java_exe%" -Djava.ext.dirs="%frameworkdir%" com.android.multidex.MainDexListBuilder "%tmpJar%" "%params%"
 goto afterClassReferenceListBuilder
 :redirect
-call "%java_exe%" -Djava.ext.dirs="%frameworkdir%" com.android.multidex.ClassReferenceListBuilder "%tmpJar%" "%params%" 1>"%output%"
+call "%java_exe%" -Djava.ext.dirs="%frameworkdir%" com.android.multidex.MainDexListBuilder "%tmpJar%" "%params%" 1>"%output%"
 :afterClassReferenceListBuilder
 
 del %tmpJar%
diff --git a/dx/src/com/android/dx/cf/iface/ClassFile.java b/dx/src/com/android/dx/cf/iface/ClassFile.java
index cb5237a..d6c9ed0 100644
--- a/dx/src/com/android/dx/cf/iface/ClassFile.java
+++ b/dx/src/com/android/dx/cf/iface/ClassFile.java
@@ -28,7 +28,7 @@
  * <p><b>Note:</b> The fields referred to in this documentation are of the
  * {@code ClassFile} structure defined in vmspec-2 sec4.1.
  */
-public interface ClassFile {
+public interface ClassFile extends HasAttribute {
     /**
      * Gets the field {@code magic}.
      *
diff --git a/dx/src/com/android/dx/cf/iface/HasAttribute.java b/dx/src/com/android/dx/cf/iface/HasAttribute.java
new file mode 100644
index 0000000..9f3e48d
--- /dev/null
+++ b/dx/src/com/android/dx/cf/iface/HasAttribute.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.dx.cf.iface;
+
+/**
+ * An element that can have {@link Attribute}
+ */
+public interface HasAttribute {
+
+    /**
+     * Get the element {@code attributes} (along with
+     * {@code attributes_count}).
+     *
+     * @return {@code non-null;} the attributes list
+     */
+    public AttributeList getAttributes();
+
+}
diff --git a/dx/src/com/android/dx/cf/iface/Member.java b/dx/src/com/android/dx/cf/iface/Member.java
index b346de4..1097d19 100644
--- a/dx/src/com/android/dx/cf/iface/Member.java
+++ b/dx/src/com/android/dx/cf/iface/Member.java
@@ -23,7 +23,7 @@
 /**
  * Interface representing members of class files (that is, fields and methods).
  */
-public interface Member {
+public interface Member extends HasAttribute {
     /**
      * Get the defining class.
      *
diff --git a/dx/src/com/android/multidex/ArchivePathElement.java b/dx/src/com/android/multidex/ArchivePathElement.java
index e76993b..05788d1 100644
--- a/dx/src/com/android/multidex/ArchivePathElement.java
+++ b/dx/src/com/android/multidex/ArchivePathElement.java
@@ -19,6 +19,9 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
@@ -27,7 +30,10 @@
  */
 class ArchivePathElement implements ClassPathElement {
 
-    private ZipFile archive;
+    static class DirectoryEntryException extends IOException {
+    }
+
+    private final ZipFile archive;
 
     public ArchivePathElement(ZipFile archive) {
         this.archive = archive;
@@ -37,7 +43,9 @@
     public InputStream open(String path) throws IOException {
         ZipEntry entry = archive.getEntry(path);
         if (entry == null) {
-            throw new FileNotFoundException(path);
+            throw new FileNotFoundException("File \"" + path + "\" not found");
+        } else if (entry.isDirectory()) {
+            throw new DirectoryEntryException();
         } else {
             return archive.getInputStream(entry);
         }
@@ -48,4 +56,45 @@
         archive.close();
     }
 
+    @Override
+    public Iterable<String> list() {
+        return new Iterable<String>() {
+
+            @Override
+            public Iterator<String> iterator() {
+                return new Iterator<String>() {
+                    Enumeration<? extends ZipEntry> delegate = archive.entries();
+                    ZipEntry next = null;
+
+                    @Override
+                    public boolean hasNext() {
+                        while (next == null && delegate.hasMoreElements()) {
+                            next = delegate.nextElement();
+                            if (next.isDirectory()) {
+                                next = null;
+                            }
+                        }
+                        return next != null;
+                    }
+
+                    @Override
+                    public String next() {
+                        if (hasNext()) {
+                            String name = next.getName();
+                            next = null;
+                            return name;
+                        } else {
+                            throw new NoSuchElementException();
+                        }
+                    }
+
+                    @Override
+                    public void remove() {
+                        throw new UnsupportedOperationException();
+                    }
+                };
+            }
+        };
+    }
+
 }
diff --git a/dx/src/com/android/multidex/ClassPathElement.java b/dx/src/com/android/multidex/ClassPathElement.java
index 6c60721..aee81cd 100644
--- a/dx/src/com/android/multidex/ClassPathElement.java
+++ b/dx/src/com/android/multidex/ClassPathElement.java
@@ -36,4 +36,6 @@
 
     void close() throws IOException;
 
+    Iterable<String> list();
+
 }
diff --git a/dx/src/com/android/multidex/ClassReferenceListBuilder.java b/dx/src/com/android/multidex/ClassReferenceListBuilder.java
index 7a9b11d..0434cad 100644
--- a/dx/src/com/android/multidex/ClassReferenceListBuilder.java
+++ b/dx/src/com/android/multidex/ClassReferenceListBuilder.java
@@ -17,114 +17,41 @@
 package com.android.multidex;
 
 import com.android.dx.cf.direct.DirectClassFile;
-import com.android.dx.cf.direct.StdAttributeFactory;
 import com.android.dx.rop.cst.Constant;
 import com.android.dx.rop.cst.ConstantPool;
 import com.android.dx.rop.cst.CstType;
 import com.android.dx.rop.type.Type;
 import com.android.dx.rop.type.TypeList;
 
-import java.io.ByteArrayOutputStream;
-import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
-import java.util.regex.Pattern;
 import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
 import java.util.zip.ZipFile;
 
 /**
- * This is a command line tool used by mainDexClasses script to find direct class references to
- * other classes. First argument of the command line is an archive, each class file contained in
- * this archive is used to identify a class whose references are to be searched, those class files
- * are not opened by this tool only their names matter. Other arguments must be zip files or
- * directories, they constitute in a classpath in with the classes named by the first argument
- * will be searched. Each searched class must be found. On each of this classes are searched for
- * their dependencies to other classes. Finally the tools prints on standard output a list of class
- * files names suitable as content of the file argument --main-dex-list of dx.
+ * Tool to find direct class references to other classes.
  */
 public class ClassReferenceListBuilder {
-
     private static final String CLASS_EXTENSION = ".class";
 
-    private static final int STATUS_ERROR = 1;
-
-    private static final String EOL = System.getProperty("line.separator");
-
-    private static String USAGE_MESSAGE =
-            "Usage:" + EOL + EOL +
-            "Short version: Don't use this." + EOL + EOL +
-            "Slightly longer version: This tool is used by mainDexClasses script to find direct"
-            + EOL +
-            "references of some classes." + EOL;
-
     private Path path;
-    private Set<String> toKeep = new HashSet<String>();
+    private Set<String> classNames = new HashSet<String>();
 
-    /**
-     *
-     * @param inputPath list of path to input jars or folders. Path elements must be separated by
-     * the system path separator: ':' on Unix, ';' on Windows.
-     */
-    public ClassReferenceListBuilder(String inputPath) throws IOException {
-        this(new Path(inputPath));
-    }
-
-    private ClassReferenceListBuilder(Path path) {
+    public ClassReferenceListBuilder(Path path) {
         this.path = path;
     }
 
+    /**
+     * Kept for compatibility with the gradle integration, this method just forwards to
+     * {@link MainDexListBuilder#main(String[])}.
+     * @deprecated use {@link MainDexListBuilder#main(String[])} instead.
+     */
+    @Deprecated
     public static void main(String[] args) {
-
-        if (args.length != 2) {
-            printUsage();
-            System.exit(STATUS_ERROR);
-        }
-
-        ZipFile jarOfRoots;
-        try {
-            jarOfRoots = new ZipFile(args[0]);
-        } catch (IOException e) {
-            System.err.println("\"" + args[0] + "\" can not be read as a zip archive. ("
-                    + e.getMessage() + ")");
-            System.exit(STATUS_ERROR);
-            return;
-        }
-
-        Path path = null;
-        try {
-            path = new Path(args[1]);
-
-            ClassReferenceListBuilder builder = new ClassReferenceListBuilder(path);
-            builder.addRoots(jarOfRoots);
-
-            printList(builder.toKeep);
-        } catch (IOException e) {
-            System.err.println("A fatal error occured: " + e.getMessage());
-            System.exit(STATUS_ERROR);
-            return;
-        } finally {
-            try {
-                jarOfRoots.close();
-            } catch (IOException e) {
-                // ignore
-            }
-            if (path != null) {
-                for (ClassPathElement element : path.elements) {
-                    try {
-                        element.close();
-                    } catch (IOException e) {
-                        // keep going, lets do our best.
-                    }
-                }
-            }
-        }
+        MainDexListBuilder.main(args);
     }
 
     /**
@@ -139,7 +66,7 @@
             ZipEntry entry = entries.nextElement();
             String name = entry.getName();
             if (name.endsWith(CLASS_EXTENSION)) {
-                toKeep.add(name.substring(0, name.length() - CLASS_EXTENSION.length()));
+                classNames.add(name.substring(0, name.length() - CLASS_EXTENSION.length()));
             }
         }
 
@@ -162,41 +89,8 @@
         }
     }
 
-    /**
-     * Returns a list of classes to keep. This can be passed to dx as a file with --main-dex-list.
-     */
-    public Set<String> getMainDexList() {
-        Set<String> resultSet = new HashSet<String>(toKeep.size());
-        for (String classDescriptor : toKeep) {
-            resultSet.add(classDescriptor + CLASS_EXTENSION);
-        }
-
-        return resultSet;
-    }
-
-    private static void printUsage() {
-        System.err.print(USAGE_MESSAGE);
-    }
-
-    private static ClassPathElement getClassPathElement(File file)
-            throws ZipException, IOException {
-        if (file.isDirectory()) {
-            return new FolderPathElement(file);
-        } else if (file.isFile()) {
-            return new ArchivePathElement(new ZipFile(file));
-        } else if (file.exists()) {
-            throw new IOException(file.getAbsolutePath() +
-                    " is not a directory neither a zip file");
-        } else {
-            throw new FileNotFoundException(file.getAbsolutePath());
-        }
-    }
-
-    private static void printList(Set<String> toKeep) {
-        for (String classDescriptor : toKeep) {
-            System.out.print(classDescriptor);
-            System.out.println(CLASS_EXTENSION);
-        }
+    Set<String> getClassNames() {
+        return classNames;
     }
 
     private void addDependencies(ConstantPool pool) {
@@ -220,14 +114,13 @@
     }
 
     private void addClassWithHierachy(String classBinaryName) {
-        if (toKeep.contains(classBinaryName)) {
+        if (classNames.contains(classBinaryName)) {
             return;
         }
 
-        String fileName = classBinaryName + CLASS_EXTENSION;
         try {
-            DirectClassFile classFile = path.getClass(fileName);
-            toKeep.add(classBinaryName);
+            DirectClassFile classFile = path.getClass(classBinaryName + CLASS_EXTENSION);
+            classNames.add(classBinaryName);
             CstType superClass = classFile.getSuperclass();
             if (superClass != null) {
                 addClassWithHierachy(superClass.getClassType().getClassName());
@@ -243,76 +136,4 @@
         }
     }
 
-    private static class Path {
-        private List<ClassPathElement> elements = new ArrayList<ClassPathElement>();
-        private String definition;
-        private ByteArrayOutputStream baos = new ByteArrayOutputStream(40 * 1024);
-        private byte[] readBuffer = new byte[20 * 1024];
-
-        private Path(String definition) throws IOException {
-            this.definition = definition;
-            for (String filePath : definition.split(Pattern.quote(File.pathSeparator))) {
-                try {
-                    addElement(getClassPathElement(new File(filePath)));
-                } catch (IOException e) {
-                    throw new IOException("\"" + filePath + "\" can not be used as a classpath"
-                            + " element. ("
-                            + e.getMessage() + ")", e);
-                }
-            }
-        }
-
-        private static byte[] readStream(InputStream in, ByteArrayOutputStream baos, byte[] readBuffer)
-                throws IOException {
-            try {
-                for (;;) {
-                    int amt = in.read(readBuffer);
-                    if (amt < 0) {
-                        break;
-                    }
-
-                    baos.write(readBuffer, 0, amt);
-                }
-            } finally {
-                in.close();
-            }
-            return baos.toByteArray();
-        }
-
-        @Override
-        public String toString() {
-            return definition;
-        }
-
-        private void addElement(ClassPathElement element) {
-            assert element != null;
-            elements.add(element);
-        }
-
-        private DirectClassFile getClass(String path) throws FileNotFoundException {
-            DirectClassFile classFile = null;
-            for (ClassPathElement element : elements) {
-                try {
-                    InputStream in = element.open(path);
-                    try {
-                        byte[] bytes = readStream(in, baos, readBuffer);
-                        baos.reset();
-                        classFile = new DirectClassFile(bytes, path, false);
-                        classFile.setAttributeFactory(StdAttributeFactory.THE_ONE);
-                        break;
-                    } finally {
-                        in.close();
-                    }
-                } catch (IOException e) {
-                    // search next element
-                }
-            }
-            if (classFile == null) {
-                throw new FileNotFoundException(path);
-            }
-            return classFile;
-        }
-    }
-
-
 }
diff --git a/dx/src/com/android/multidex/FolderPathElement.java b/dx/src/com/android/multidex/FolderPathElement.java
index 2242547..97fb11f 100644
--- a/dx/src/com/android/multidex/FolderPathElement.java
+++ b/dx/src/com/android/multidex/FolderPathElement.java
@@ -20,6 +20,7 @@
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.InputStream;
+import java.util.ArrayList;
 
 /**
  * A folder element.
@@ -42,4 +43,21 @@
     public void close() {
     }
 
+    @Override
+    public Iterable<String> list() {
+        ArrayList<String> result = new ArrayList<String>();
+        collect(baseFolder, "", result);
+        return result;
+    }
+
+    private void collect(File folder, String prefix, ArrayList<String> result) {
+        for (File file : folder.listFiles()) {
+            if (file.isDirectory()) {
+                collect(file, prefix + SEPARATOR_CHAR + file.getName(), result);
+            } else {
+                result.add(prefix + SEPARATOR_CHAR + file.getName());
+            }
+        }
+    }
+
 }
diff --git a/dx/src/com/android/multidex/MainDexListBuilder.java b/dx/src/com/android/multidex/MainDexListBuilder.java
new file mode 100644
index 0000000..c9e1a18
--- /dev/null
+++ b/dx/src/com/android/multidex/MainDexListBuilder.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.multidex;
+
+import com.android.dx.cf.attrib.AttRuntimeVisibleAnnotations;
+import com.android.dx.cf.direct.DirectClassFile;
+import com.android.dx.cf.iface.Attribute;
+import com.android.dx.cf.iface.FieldList;
+import com.android.dx.cf.iface.HasAttribute;
+import com.android.dx.cf.iface.MethodList;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.zip.ZipFile;
+
+/**
+ * This is a command line tool used by mainDexClasses script to build a main dex classes list. First
+ * argument of the command line is an archive, each class file contained in this archive is used to
+ * identify a class that can be used during secondary dex installation, those class files
+ * are not opened by this tool only their names matter. Other arguments must be zip files or
+ * directories, they constitute in a classpath in with the classes named by the first argument
+ * will be searched. Each searched class must be found. On each of this classes are searched for
+ * their dependencies to other classes. The tool also browses for classes annotated by runtime
+ * visible annotations and adds them to the list/ Finally the tools prints on standard output a list
+ * of class files names suitable as content of the file argument --main-dex-list of dx.
+ */
+public class MainDexListBuilder {
+    private static final String CLASS_EXTENSION = ".class";
+
+    private static final int STATUS_ERROR = 1;
+
+    private static final String EOL = System.getProperty("line.separator");
+
+    private static String USAGE_MESSAGE =
+            "Usage:" + EOL + EOL +
+            "Short version: Don't use this." + EOL + EOL +
+            "Slightly longer version: This tool is used by mainDexClasses script to build" + EOL +
+            "the main dex list." + EOL;
+
+    private Set<String> filesToKeep = new HashSet<String>();
+
+    public static void main(String[] args) {
+
+        if (args.length != 2) {
+            printUsage();
+            System.exit(STATUS_ERROR);
+        }
+
+        try {
+
+            MainDexListBuilder builder = new MainDexListBuilder(args[0], args[1]);
+            Set<String> toKeep = builder.getMainDexList();
+            printList(toKeep);
+        } catch (IOException e) {
+            System.err.println("A fatal error occured: " + e.getMessage());
+            System.exit(STATUS_ERROR);
+            return;
+        }
+    }
+
+    public MainDexListBuilder(String rootJar, String pathString) throws IOException {
+        ZipFile jarOfRoots = null;
+        Path path = null;
+        try {
+            try {
+                jarOfRoots = new ZipFile(rootJar);
+            } catch (IOException e) {
+                throw new IOException("\"" + rootJar + "\" can not be read as a zip archive. ("
+                        + e.getMessage() + ")", e);
+            }
+            path = new Path(pathString);
+
+            ClassReferenceListBuilder mainListBuilder = new ClassReferenceListBuilder(path);
+            mainListBuilder.addRoots(jarOfRoots);
+            for (String className : mainListBuilder.getClassNames()) {
+                filesToKeep.add(className + CLASS_EXTENSION);
+            }
+            keepAnnotated(path);
+        } finally {
+            try {
+                jarOfRoots.close();
+            } catch (IOException e) {
+                // ignore
+            }
+            if (path != null) {
+                for (ClassPathElement element : path.elements) {
+                    try {
+                        element.close();
+                    } catch (IOException e) {
+                        // keep going, lets do our best.
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns a list of classes to keep. This can be passed to dx as a file with --main-dex-list.
+     */
+    public Set<String> getMainDexList() {
+        return filesToKeep;
+    }
+
+    private static void printUsage() {
+        System.err.print(USAGE_MESSAGE);
+    }
+
+    private static void printList(Set<String> fileNames) {
+        for (String fileName : fileNames) {
+            System.out.println(fileName);
+        }
+    }
+
+    /**
+     * Keep classes annotated with runtime annotations.
+     */
+    private void keepAnnotated(Path path) throws FileNotFoundException {
+        for (ClassPathElement element : path.getElements()) {
+            forClazz:
+                for (String name : element.list()) {
+                    if (name.endsWith(CLASS_EXTENSION)) {
+                        DirectClassFile clazz = path.getClass(name);
+                        if (hasRuntimeVisibleAnnotation(clazz)) {
+                            filesToKeep.add(name);
+                        } else {
+                            MethodList methods = clazz.getMethods();
+                            for (int i = 0; i<methods.size(); i++) {
+                                if (hasRuntimeVisibleAnnotation(methods.get(i))) {
+                                    filesToKeep.add(name);
+                                    continue forClazz;
+                                }
+                            }
+                            FieldList fields = clazz.getFields();
+                            for (int i = 0; i<fields.size(); i++) {
+                                if (hasRuntimeVisibleAnnotation(fields.get(i))) {
+                                    filesToKeep.add(name);
+                                    continue forClazz;
+                                }
+                            }
+                        }
+                    }
+                }
+        }
+    }
+
+    private boolean hasRuntimeVisibleAnnotation(HasAttribute element) {
+        Attribute att = element.getAttributes().findFirst(
+                AttRuntimeVisibleAnnotations.ATTRIBUTE_NAME);
+        return (att != null && ((AttRuntimeVisibleAnnotations)att).getAnnotations().size()>0);
+    }
+}
diff --git a/dx/src/com/android/multidex/Path.java b/dx/src/com/android/multidex/Path.java
new file mode 100644
index 0000000..155b40f
--- /dev/null
+++ b/dx/src/com/android/multidex/Path.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.multidex;
+
+import com.android.dx.cf.direct.DirectClassFile;
+import com.android.dx.cf.direct.StdAttributeFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+class Path {
+
+    static ClassPathElement getClassPathElement(File file)
+            throws ZipException, IOException {
+        if (file.isDirectory()) {
+            return new FolderPathElement(file);
+        } else if (file.isFile()) {
+            return new ArchivePathElement(new ZipFile(file));
+        } else if (file.exists()) {
+            throw new IOException("\"" + file.getPath() +
+                    "\" is not a directory neither a zip file");
+        } else {
+            throw new FileNotFoundException("File \"" + file.getPath() + "\" not found");
+        }
+    }
+
+    List<ClassPathElement> elements = new ArrayList<ClassPathElement>();
+    private final String definition;
+    private final ByteArrayOutputStream baos = new ByteArrayOutputStream(40 * 1024);
+    private final byte[] readBuffer = new byte[20 * 1024];
+
+    Path(String definition) throws IOException {
+        this.definition = definition;
+        for (String filePath : definition.split(Pattern.quote(File.pathSeparator))) {
+            try {
+                addElement(getClassPathElement(new File(filePath)));
+            } catch (IOException e) {
+                throw new IOException("Wrong classpath: " + e.getMessage(), e);
+            }
+        }
+    }
+
+    private static byte[] readStream(InputStream in, ByteArrayOutputStream baos, byte[] readBuffer)
+            throws IOException {
+        try {
+            for (;;) {
+                int amt = in.read(readBuffer);
+                if (amt < 0) {
+                    break;
+                }
+
+                baos.write(readBuffer, 0, amt);
+            }
+        } finally {
+            in.close();
+        }
+        return baos.toByteArray();
+    }
+
+    @Override
+    public String toString() {
+        return definition;
+    }
+
+    Iterable<ClassPathElement> getElements() {
+      return elements;
+    }
+
+    private void addElement(ClassPathElement element) {
+        assert element != null;
+        elements.add(element);
+    }
+
+    synchronized DirectClassFile getClass(String path) throws FileNotFoundException {
+        DirectClassFile classFile = null;
+        for (ClassPathElement element : elements) {
+            try {
+                InputStream in = element.open(path);
+                try {
+                    byte[] bytes = readStream(in, baos, readBuffer);
+                    baos.reset();
+                    classFile = new DirectClassFile(bytes, path, false);
+                    classFile.setAttributeFactory(StdAttributeFactory.THE_ONE);
+                    break;
+                } finally {
+                    in.close();
+                }
+            } catch (IOException e) {
+                // search next element
+            }
+        }
+        if (classFile == null) {
+            throw new FileNotFoundException("File \"" + path + "\" not found");
+        }
+        return classFile;
+    }
+}
\ No newline at end of file
