Revert "Delete DX Tests"

This reverts commit 9ba909f8ab7f3abd082bfdf7ffcdeba930ed1b9a.
diff --git a/tools/dx-tests/src/dxconvext/ClassFileParser.java b/tools/dx-tests/src/dxconvext/ClassFileParser.java
new file mode 100644
index 0000000..8a43396
--- /dev/null
+++ b/tools/dx-tests/src/dxconvext/ClassFileParser.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2008 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 dxconvext;
+
+import com.android.dx.cf.direct.ClassPathOpener;
+import com.android.dx.cf.direct.DirectClassFile;
+import com.android.dx.cf.direct.StdAttributeFactory;
+import com.android.dx.cf.iface.Member;
+import com.android.dx.cf.iface.ParseObserver;
+import com.android.dx.util.ByteArray;
+import com.android.dx.util.FileUtils;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+public class ClassFileParser {
+
+    private BufferedWriter bw; // the writer to write the result to.
+
+    /**
+     * Parses a .class file and outputs a .cfh (class file in hex format) file.
+     * 
+     * args[0] is the absolute path to the java src directory e.g.
+     * /home/fjost/android/workspace/dxconverter/src
+     * 
+     * args[1] is the absolute path to the classes directory e.g.
+     * /home/fjost/android/workspace/out/classes_javac this is the place where
+     * 
+     * args[2] is the absolute path to the java source file, e.g.
+     * /home/fjost/android/workspace/dxconverter/src/test/MyTest.java
+     * 
+     * 
+     * 
+     * @param args
+     */
+    public static void main(String[] args) throws IOException {
+        ClassFileParser cfp = new ClassFileParser();
+        cfp.process(args[0], args[1], args[2]);
+    }
+
+    private void process(final String srcDir, final String classesDir,
+            final String absSrcFilePath) throws IOException {
+        ClassPathOpener opener;
+
+        String fileName = absSrcFilePath;
+        // e.g. test/p1/MyTest.java
+        String pckPath = fileName.substring(srcDir.length() + 1);
+        // e.g. test/p1
+        String pck = pckPath.substring(0, pckPath.lastIndexOf("/"));
+        // e.g. MyTest
+        String cName = pckPath.substring(pck.length() + 1);
+        cName = cName.substring(0, cName.lastIndexOf("."));
+        String cfName = pck+"/"+cName+".class";
+        // 2. calculate the target file name:
+        // e.g. <out-path>/test/p1/MyTest.class
+        String inFile = classesDir + "/" + pck + "/" + cName + ".class";
+        if (!new File(inFile).exists()) {
+            throw new RuntimeException("cannot read:" + inFile);
+        }
+        byte[] bytes = FileUtils.readFile(inFile);
+        // write the outfile to the same directory as the corresponding .java
+        // file
+        String outFile = absSrcFilePath.substring(0, absSrcFilePath
+                .lastIndexOf("/"))+ "/" + cName + ".cfh";
+        Writer w;
+        try {
+            w = new OutputStreamWriter(new FileOutputStream(new File(outFile)));
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException("cannot write to file:"+outFile, e);
+        }
+        // Writer w = new OutputStreamWriter(System.out);
+        ClassFileParser.this.processFileBytes(w, cfName, bytes);
+
+    }
+
+    /**
+     * 
+     * @param w the writer to write the generated .cfh file to
+     * @param name the relative name of the java src file, e.g.
+     *        dxc/util/Util.java
+     * @param allbytes the bytes of this java src file
+     * @return true if everthing went alright
+     */
+    void processFileBytes(Writer w, String name, final byte[] allbytes) throws IOException {
+        String fixedPathName = fixPath(name);
+        DirectClassFile cf = new DirectClassFile(allbytes, fixedPathName, true);
+        bw = new BufferedWriter(w);
+        String className = fixedPathName.substring(0, fixedPathName.lastIndexOf("."));
+        out("//@class:" + className, 0);
+        cf.setObserver(new ParseObserver() {
+            private int cur_indent = 0;
+            private int checkpos = 0;
+
+            /**
+             * Indicate that the level of indentation for a dump should increase
+             * or decrease (positive or negative argument, respectively).
+             * 
+             * @param indentDelta the amount to change indentation
+             */
+            public void changeIndent(int indentDelta) {
+                cur_indent += indentDelta;
+            }
+
+            /**
+             * Indicate that a particular member is now being parsed.
+             * 
+             * @param bytes non-null; the source that is being parsed
+             * @param offset offset into <code>bytes</code> for the start of
+             *        the member
+             * @param name non-null; name of the member
+             * @param descriptor non-null; descriptor of the member
+             */
+            public void startParsingMember(ByteArray bytes, int offset,
+                    String name, String descriptor) {
+                // ByteArray ba = bytes.slice(offset, bytes.size());
+                out("// ========== start-ParseMember:" + name + ", offset "
+                        + offset + ", len:" + (bytes.size() - offset)
+                        + ",desc: " + descriptor);
+                // out("// "+dumpReadableString(ba));
+                // out(" "+dumpBytes(ba));
+            }
+
+            /**
+             * Indicate that a particular member is no longer being parsed.
+             * 
+             * @param bytes non-null; the source that was parsed
+             * @param offset offset into <code>bytes</code> for the end of the
+             *        member
+             * @param name non-null; name of the member
+             * @param descriptor non-null; descriptor of the member
+             * @param member non-null; the actual member that was parsed
+             */
+            public void endParsingMember(ByteArray bytes, int offset,
+                    String name, String descriptor, Member member) {
+                ByteArray ba = bytes.slice(offset, bytes.size());
+                out("// ========== end-ParseMember:" + name + ", desc: "
+                        + descriptor);
+                // out("// "+dumpReadableString(ba));
+                // out(" "+dumpBytes(ba));
+            }
+
+            /**
+             * Indicate that some parsing happened.
+             * 
+             * @param bytes non-null; the source that was parsed
+             * @param offset offset into <code>bytes</code> for what was
+             *        parsed
+             * @param len number of bytes parsed
+             * @param human non-null; human form for what was parsed
+             */
+            public void parsed(ByteArray bytes, int offset, int len,
+                    String human) {
+                human = human.replace('\n', ' ');
+                out("// parsed:" + ", offset " + offset + ", len " + len
+                        + ", h: " + human);
+                if (len > 0) {
+                    ByteArray ba = bytes.slice(offset, offset + len);
+                    check(ba);
+                    out("// " + dumpReadableString(ba));
+                    out("   " + dumpBytes(ba));
+                }
+            }
+
+            private void out(String msg) {
+                ClassFileParser.this.out(msg, cur_indent);
+
+            }
+
+            private void check(ByteArray ba) {
+                int len = ba.size();
+                int offset = checkpos;
+                for (int i = 0; i < len; i++) {
+                    int b = ba.getByte(i);
+                    byte b2 = allbytes[i + offset];
+                    if (b != b2)
+                        throw new RuntimeException("byte dump mismatch at pos "
+                                + (i + offset));
+                }
+                checkpos += len;
+            }
+
+
+
+            private String dumpBytes(ByteArray ba) {
+                String s = "";
+                for (int i = 0; i < ba.size(); i++) {
+                    int byt = ba.getUnsignedByte(i);
+                    String hexVal = Integer.toHexString(byt);
+                    if (hexVal.length() == 1) {
+                        hexVal = "0" + hexVal;
+                    }
+                    s += hexVal + " ";
+                }
+                return s;
+            }
+
+            private String dumpReadableString(ByteArray ba) {
+                String s = "";
+                for (int i = 0; i < ba.size(); i++) {
+                    int bb = ba.getUnsignedByte(i);
+                    if (bb > 31 && bb < 127) {
+                        s += (char) bb;
+                    } else {
+                        s += ".";
+                    }
+                    s += "  ";
+                }
+                return s;
+            }
+
+
+        });
+        cf.setAttributeFactory(StdAttributeFactory.THE_ONE);
+        // what is needed to force parsing to the end?
+        cf.getMagic();
+        // cf.getFields();
+        // cf.getAttributes();
+        // cf.getMethods();        
+        bw.close();
+    }
+
+
+    private String getIndent(int indent) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < indent * 4; i++) {
+            sb.append(' ');
+        }
+        return sb.toString();
+    }
+
+    private void out(String msg, int cur_indent) {
+        try {
+            bw.write(getIndent(cur_indent) + msg);
+            bw.newLine();
+        } catch (IOException ioe) {
+            throw new RuntimeException("error while writing to the writer", ioe);
+        }
+    }
+
+    private static String fixPath(String path) {
+        /*
+         * If the path separator is \ (like on windows), we convert the path to
+         * a standard '/' separated path.
+         */
+        if (File.separatorChar == '\\') {
+            path = path.replace('\\', '/');
+        }
+
+        int index = path.lastIndexOf("/./");
+
+        if (index != -1) {
+            return path.substring(index + 3);
+        }
+
+        if (path.startsWith("./")) {
+            return path.substring(2);
+        }
+
+        return path;
+    }
+
+
+
+}