auto import from //depot/cupcake/@135843
diff --git a/tools/deadcode.py b/tools/deadcode.py
new file mode 100755
index 0000000..eb71b7c
--- /dev/null
+++ b/tools/deadcode.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+
+import os
+import re
+import sys
+
+def SplitSections(buffer):
+    """Spin through the input buffer looking for section header lines.
+    When found, the name of the section is extracted.  The entire contents
+    of that section is added to a result hashmap with the section name
+    as the key"""
+    
+    # Match lines like
+    #              |section_name:
+    # capturing section_name
+    headerPattern = re.compile(r'^\s+\|([a-z _]+)\:$', re.MULTILINE)
+
+    sections = {}
+    start = 0
+    anchor = -1
+    sectionName = ''
+    
+    while True:
+        # Look for a section header
+        result = headerPattern.search(buffer, start)
+        
+        # If there are no more, add a section from the last header to EOF
+        if result is None:
+            if anchor is not -1:
+                sections[sectionName] = buffer[anchor]
+            return sections
+
+        # Add the lines from the last header, to this one to the sections
+        # map indexed by the section name
+        if anchor is not -1:
+            sections[sectionName] = buffer[anchor:result.start()]
+            
+        sectionName = result.group(1)
+        start = result.end()
+        anchor = start
+        
+    return sections
+
+def FindMethods(section):
+    """Spin through the 'method code index' section and extract all
+    method signatures.  When found, they are added to a result list."""
+    
+    # Match lines like:
+    #             |[abcd] com/example/app/Class.method:(args)return
+    # capturing the method signature
+    methodPattern = re.compile(r'^\s+\|\[\w{4}\] (.*)$', re.MULTILINE)
+
+    start = 0
+    methods = []
+
+    while True:
+        # Look for a method name
+        result = methodPattern.search(section, start)
+        
+        if result is None:
+            return methods
+
+        # Add the captured signature to the method list
+        methods.append(result.group(1))
+        start = result.end()
+
+def CallsMethod(codes, method):
+    """Spin through all the input method signatures.  For each one, return
+    whether or not there is method invokation line in the codes section that
+    lists the method as the target."""
+    
+    start = 0
+    
+    while True:
+        # Find the next reference to the method signature
+        match = codes.find(method, start)
+        
+        if match is -1:
+            break;
+        
+        # Find the beginning of the line the method reference is on
+        startOfLine = codes.rfind("\n", 0, match) + 1
+
+        # If the word 'invoke' comes between the beginning of the line
+        # and the method reference, then it is a call to that method rather
+        # than the beginning of the code section for that method.
+        if codes.find("invoke", startOfLine, match) is not -1:
+            return True
+            
+        start = match + len(method)
+        
+    return False
+
+
+
+def main():
+    if len(sys.argv) is not 2 or not sys.argv[1].endswith(".jar"):
+        print "Usage:", sys.argv[0], "<filename.jar>"
+        sys.exit()
+
+    command = 'dx --dex --dump-width=1000 --dump-to=-"" "%s"' % sys.argv[1]
+
+    pipe = os.popen(command)
+
+    # Read the whole dump file into memory
+    data = pipe.read()
+    sections = SplitSections(data)
+
+    pipe.close()
+    del(data)
+
+    methods = FindMethods(sections['method code index'])
+    codes = sections['codes']
+    del(sections)
+
+    print "Dead Methods:"
+    count = 0
+
+    for method in methods:
+        if not CallsMethod(codes, method):
+            print "\t", method
+            count += 1
+        
+    if count is 0:
+        print "\tNone"
+
+if __name__ == '__main__':
+    main()