Rename DexFile to DexCache

Change-Id: I93fa3e4f7cf87fbaac974f0d2577628a23f0d8c2
diff --git a/build/Android.common.mk b/build/Android.common.mk
index 5dab0fd..7d5ef2b 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -34,6 +34,7 @@
 	src/assembler.cc \
 	src/calling_convention.cc \
 	src/class_linker.cc \
+	src/dex_cache.cc \
 	src/dex_file.cc \
 	src/dex_instruction.cc \
 	src/dex_verifier.cc \
@@ -47,7 +48,6 @@
 	src/object.cc \
 	src/object_bitmap.cc \
 	src/offsets.cc \
-	src/raw_dex_file.cc \
 	src/runtime.cc \
 	src/space.cc \
 	src/stringpiece.cc \
@@ -77,11 +77,11 @@
 
 TEST_COMMON_SRC_FILES := \
 	src/class_linker_test.cc \
+	src/dex_cache_test.cc \
 	src/dex_file_test.cc \
 	src/dex_instruction_visitor_test.cc \
 	src/jni_compiler_test.cc \
 	src/object_test.cc \
-	src/raw_dex_file_test.cc \
 	src/space_test.cc
 
 TEST_TARGET_SRC_FILES := \
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 20960d2..bacc9a3 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -7,13 +7,13 @@
 #include <utility>
 
 #include "casts.h"
-#include "dex_file.h"
+#include "dex_cache.h"
 #include "dex_verifier.h"
 #include "heap.h"
 #include "logging.h"
 #include "monitor.h"
 #include "object.h"
-#include "raw_dex_file.h"
+#include "dex_file.h"
 #include "scoped_ptr.h"
 #include "thread.h"
 #include "utils.h"
@@ -86,13 +86,13 @@
   CHECK(object_array_class_ != NULL);
 }
 
-DexFile* ClassLinker::AllocDexFile() {
-  return down_cast<DexFile*>(Heap::AllocObjectArray(object_array_class_, DexFile::kMax));
+DexCache* ClassLinker::AllocDexCache() {
+  return down_cast<DexCache*>(Heap::AllocObjectArray(object_array_class_, DexCache::kMax));
 }
 
-Class* ClassLinker::AllocClass(DexFile* dex_file) {
+Class* ClassLinker::AllocClass(DexCache* dex_cache) {
   Class* klass = down_cast<Class*>(Heap::AllocObject(java_lang_Class_));
-  klass->dex_file_ = dex_file;
+  klass->dex_cache_ = dex_cache;
   return klass;
 }
 
@@ -141,37 +141,37 @@
     }
     const RawDexFile* raw_dex_file = pair.first;
     const RawDexFile::ClassDef* class_def = pair.second;
-    DexFile* dex_file = FindDexFile(raw_dex_file);
+    DexCache* dex_cache = FindDexCache(raw_dex_file);
     // Load the class from the dex file.
     if (descriptor == "Ljava/lang/Object;") {
       klass = java_lang_Object_;
-      klass->dex_file_ = dex_file;
+      klass->dex_cache_ = dex_cache;
       klass->object_size_ = sizeof(Object);
       char_array_class_->super_class_idx_ = class_def->class_idx_;
     } else if (descriptor == "Ljava/lang/Class;") {
       klass = java_lang_Class_;
-      klass->dex_file_ = dex_file;
+      klass->dex_cache_ = dex_cache;
       klass->object_size_ = sizeof(Class);
     } else if (descriptor == "Ljava/lang/ref/Field;") {
       klass = java_lang_ref_Field_;
-      klass->dex_file_ = dex_file;
+      klass->dex_cache_ = dex_cache;
       klass->object_size_ = sizeof(Field);
     } else if (descriptor == "Ljava/lang/ref/Method;") {
       klass = java_lang_ref_Method_;
-      klass->dex_file_ = dex_file;
+      klass->dex_cache_ = dex_cache;
       klass->object_size_ = sizeof(Method);
     } else if (descriptor == "Ljava/lang/Cloneable;") {
       klass = java_lang_Cloneable_;
-      klass->dex_file_ = dex_file;
+      klass->dex_cache_ = dex_cache;
     } else if (descriptor == "Ljava/io/Serializable;") {
       klass = java_io_Serializable_;
-      klass->dex_file_ = dex_file;
+      klass->dex_cache_ = dex_cache;
     } else if (descriptor == "Ljava/lang/String;") {
       klass = java_lang_String_;
-      klass->dex_file_ = dex_file;
+      klass->dex_cache_ = dex_cache;
       klass->object_size_ = sizeof(String);
     } else {
-      klass = AllocClass(dex_file);
+      klass = AllocClass(dex_cache);
     }
     LoadClass(*raw_dex_file, *class_def, klass);
     // Check for a pending exception during load
@@ -227,7 +227,7 @@
                             const RawDexFile::ClassDef& class_def,
                             Class* klass) {
   CHECK(klass != NULL);
-  CHECK(klass->dex_file_ != NULL);
+  CHECK(klass->dex_cache_ != NULL);
   const byte* class_data = raw_dex_file.GetClassData(class_def);
   RawDexFile::ClassDataHeader header = raw_dex_file.ReadClassDataHeader(&class_data);
 
@@ -387,19 +387,19 @@
 
 void ClassLinker::RegisterDexFile(RawDexFile* raw_dex_file) {
   raw_dex_files_.push_back(raw_dex_file);
-  DexFile* dex_file = AllocDexFile();
-  CHECK(dex_file != NULL);
-  dex_file->Init(AllocObjectArray(raw_dex_file->NumStringIds()),
-                 AllocObjectArray(raw_dex_file->NumTypeIds()),
-                 AllocObjectArray(raw_dex_file->NumMethodIds()),
-                 AllocObjectArray(raw_dex_file->NumFieldIds()));
-  dex_files_.push_back(dex_file);
+  DexCache* dex_cache = AllocDexCache();
+  CHECK(dex_cache != NULL);
+  dex_cache->Init(AllocObjectArray(raw_dex_file->NumStringIds()),
+                  AllocObjectArray(raw_dex_file->NumTypeIds()),
+                  AllocObjectArray(raw_dex_file->NumMethodIds()),
+                  AllocObjectArray(raw_dex_file->NumFieldIds()));
+  dex_caches_.push_back(dex_cache);
 }
 
-const RawDexFile* ClassLinker::FindRawDexFile(const DexFile* dex_file) const {
-  CHECK(dex_file != NULL);
-  for (size_t i = 0; i != dex_files_.size(); ++i) {
-    if (dex_files_[i] == dex_file) {
+const RawDexFile* ClassLinker::FindRawDexFile(const DexCache* dex_cache) const {
+  CHECK(dex_cache != NULL);
+  for (size_t i = 0; i != dex_caches_.size(); ++i) {
+    if (dex_caches_[i] == dex_cache) {
         return raw_dex_files_[i];
     }
   }
@@ -407,14 +407,14 @@
   return NULL;
 }
 
-DexFile* ClassLinker::FindDexFile(const RawDexFile* raw_dex_file) const {
+DexCache* ClassLinker::FindDexCache(const RawDexFile* raw_dex_file) const {
   CHECK(raw_dex_file != NULL);
   for (size_t i = 0; i != raw_dex_files_.size(); ++i) {
     if (raw_dex_files_[i] == raw_dex_file) {
-        return dex_files_[i];
+        return dex_caches_[i];
     }
   }
-  CHECK(false) << "Could not find DexFile";
+  CHECK(false) << "Could not find DexCache";
   return NULL;
 }
 
@@ -799,7 +799,7 @@
 bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method,
                                                  const Class* klass1,
                                                  const Class* klass2) {
-  const RawDexFile* raw = FindRawDexFile(method->GetClass()->GetDexFile());
+  const RawDexFile* raw = FindRawDexFile(method->GetClass()->GetDexCache());
   const RawDexFile::ProtoId& proto_id = raw->GetProtoId(method->proto_idx_);
   RawDexFile::ParameterIterator *it;
   for (it = raw->GetParameterIterator(proto_id); it->HasNext(); it->Next()) {
@@ -851,8 +851,8 @@
 }
 
 bool ClassLinker::HasSameArgumentTypes(const Method* m1, const Method* m2) const {
-  const RawDexFile* raw1 = FindRawDexFile(m1->GetClass()->GetDexFile());
-  const RawDexFile* raw2 = FindRawDexFile(m2->GetClass()->GetDexFile());
+  const RawDexFile* raw1 = FindRawDexFile(m1->GetClass()->GetDexCache());
+  const RawDexFile* raw2 = FindRawDexFile(m2->GetClass()->GetDexCache());
   const RawDexFile::ProtoId& proto1 = raw1->GetProtoId(m1->proto_idx_);
   const RawDexFile::ProtoId& proto2 = raw2->GetProtoId(m2->proto_idx_);
 
@@ -879,8 +879,8 @@
 }
 
 bool ClassLinker::HasSameReturnType(const Method* m1, const Method* m2) const {
-  const RawDexFile* raw1 = FindRawDexFile(m1->GetClass()->GetDexFile());
-  const RawDexFile* raw2 = FindRawDexFile(m2->GetClass()->GetDexFile());
+  const RawDexFile* raw1 = FindRawDexFile(m1->GetClass()->GetDexCache());
+  const RawDexFile* raw2 = FindRawDexFile(m2->GetClass()->GetDexCache());
   const RawDexFile::ProtoId& proto1 = raw1->GetProtoId(m1->proto_idx_);
   const RawDexFile::ProtoId& proto2 = raw2->GetProtoId(m2->proto_idx_);
   const char* type1 = raw1->dexStringByTypeIdx(proto1.return_type_idx_);
@@ -914,7 +914,7 @@
   if (num_static_fields == 0) {
     return;
   }
-  DexFile* dex_file = klass->GetDexFile();
+  DexCache* dex_file = klass->GetDexCache();
   if (dex_file == NULL) {
     return;
   }
@@ -1454,8 +1454,8 @@
 Class* ClassLinker::ResolveClass(const Class* referrer,
                                  uint32_t class_idx,
                                  const RawDexFile* raw_dex_file) {
-  DexFile* dex_file = referrer->GetDexFile();
-  Class* resolved = dex_file->GetResolvedClass(class_idx);
+  DexCache* dex_cache = referrer->GetDexCache();
+  Class* resolved = dex_cache->GetResolvedClass(class_idx);
   if (resolved != NULL) {
     return resolved;
   }
@@ -1467,13 +1467,13 @@
   }
   if (resolved != NULL) {
     Class* check = resolved->IsArray() ? resolved->component_type_ : resolved;
-    if (referrer->GetDexFile() != check->GetDexFile()) {
+    if (referrer->GetDexCache() != check->GetDexCache()) {
       if (check->GetClassLoader() != NULL) {
         LG << "Class resolved by unexpected DEX";  // TODO: IllegalAccessError
         return NULL;
       }
     }
-    dex_file->SetResolvedClass(class_idx, resolved);
+    dex_cache->SetResolvedClass(class_idx, resolved);
   } else {
     DCHECK(Thread::Current()->IsExceptionPending());
   }
@@ -1488,14 +1488,14 @@
 
 String* ClassLinker::ResolveString(const Class* referring,
                                    uint32_t string_idx) {
-  const RawDexFile* raw = FindRawDexFile(referring->GetDexFile());
+  const RawDexFile* raw = FindRawDexFile(referring->GetDexCache());
   const RawDexFile::StringId& string_id = raw->GetStringId(string_idx);
   const char* string_data = raw->GetStringData(string_id);
   String* new_string = Heap::AllocStringFromModifiedUtf8(java_lang_String_,
                                                          char_array_class_,
                                                          string_data);
   // TODO: intern the new string
-  referring->GetDexFile()->SetResolvedString(string_idx, new_string);
+  referring->GetDexCache()->SetResolvedString(string_idx, new_string);
   return new_string;
 }
 
diff --git a/src/class_linker.h b/src/class_linker.h
index d7bb191..9d6c53e 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -8,7 +8,7 @@
 #include <vector>
 
 #include "macros.h"
-#include "raw_dex_file.h"
+#include "dex_file.h"
 #include "thread.h"
 #include "object.h"
 #include "gtest/gtest.h"
@@ -22,8 +22,8 @@
 
   ~ClassLinker() {}
 
-  DexFile* AllocDexFile();
-  Class* AllocClass(DexFile* dex_file);
+  DexCache* AllocDexCache();
+  Class* AllocClass(DexCache* dex_cache);
   StaticField* AllocStaticField();
   InstanceField* AllocInstanceField();
   Method* AllocMethod();
@@ -64,9 +64,9 @@
 
   Class* FindPrimitiveClass(char type);
 
-  const RawDexFile* FindRawDexFile(const DexFile* dex_file) const;
+  const RawDexFile* FindRawDexFile(const DexCache* dex_file) const;
 
-  DexFile* FindDexFile(const RawDexFile* raw_dex_file) const;
+  DexCache* FindDexCache(const RawDexFile* raw_dex_file) const;
 
   typedef std::pair<const RawDexFile*, const RawDexFile::ClassDef*> ClassPathEntry;
 
@@ -148,7 +148,7 @@
 
   std::vector<RawDexFile*> raw_dex_files_;
 
-  std::vector<DexFile*> dex_files_;
+  std::vector<DexCache*> dex_caches_;
 
   // TODO: multimap
   typedef std::map<const StringPiece, Class*> Table;
diff --git a/src/dex_cache.cc b/src/dex_cache.cc
new file mode 100644
index 0000000..f2a4768
--- /dev/null
+++ b/src/dex_cache.cc
@@ -0,0 +1,21 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#include "dex_cache.h"
+#include "heap.h"
+#include "globals.h"
+#include "logging.h"
+#include "object.h"
+
+namespace art {
+
+void DexCache::Init(ObjectArray* strings,
+                    ObjectArray* classes,
+                    ObjectArray* methods,
+                    ObjectArray* fields) {
+  Set(kStrings, strings);
+  Set(kClasses, classes);
+  Set(kMethods, methods);
+  Set(kFields,  fields);
+}
+
+}  // namespace art
diff --git a/src/dex_cache.h b/src/dex_cache.h
new file mode 100644
index 0000000..2892e29
--- /dev/null
+++ b/src/dex_cache.h
@@ -0,0 +1,100 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#ifndef ART_SRC_DEX_CACHE_H_
+#define ART_SRC_DEX_CACHE_H_
+
+#include "globals.h"
+#include "macros.h"
+#include "object.h"
+
+namespace art {
+
+class Class;
+class Field;
+class Method;
+class String;
+union JValue;
+
+class DexCache : public ObjectArray {
+ public:
+
+  enum ArrayIndexes {
+    kStrings = 0,
+    kClasses = 1,
+    kMethods = 2,
+    kFields  = 3,
+    kMax     = 4,
+  };
+
+  void Init(ObjectArray* strings,
+            ObjectArray* classes,
+            ObjectArray* methods,
+            ObjectArray* fields);
+
+  size_t NumStrings() const {
+    return GetStrings()->GetLength();
+  }
+
+  size_t NumClasses() const {
+    return GetClasses()->GetLength();
+  }
+
+  size_t NumMethods() const {
+    return GetMethods()->GetLength();
+  }
+
+  size_t NumFields() const {
+    return GetFields()->GetLength();
+  }
+
+  String* GetResolvedString(uint32_t string_idx) const {
+    return down_cast<String*>(GetStrings()->Get(string_idx));
+  }
+
+  void SetResolvedString(uint32_t string_idx, String* resolved) {
+    GetStrings()->Set(string_idx, resolved);
+  }
+
+  Class* GetResolvedClass(uint32_t class_idx) const {
+    return down_cast<Class*>(GetClasses()->Get(class_idx));
+  }
+
+  void SetResolvedClass(uint32_t class_idx, Class* resolved) {
+    GetClasses()->Set(class_idx, resolved);
+  }
+
+  Method* GetResolvedMethod(uint32_t method_idx) const {
+    return down_cast<Method*>(GetMethods()->Get(method_idx));
+  }
+
+  void SetResolvedMethod(uint32_t method_idx, Method* resolved) {
+    GetMethods()->Set(method_idx, resolved);
+  }
+
+  Field* GetResolvedField(uint32_t field_idx) const {
+    return down_cast<Field*>(GetFields()->Get(field_idx));
+  }
+
+  void SetResolvedfield(uint32_t field_idx, Field* resolved) {
+    GetFields()->Set(field_idx, resolved);
+  }
+
+ private:
+  ObjectArray* GetStrings() const {
+      return down_cast<ObjectArray*>(Get(kStrings));
+  }
+  ObjectArray* GetClasses() const {
+      return down_cast<ObjectArray*>(Get(kClasses));
+  }
+  ObjectArray* GetMethods() const {
+      return down_cast<ObjectArray*>(Get(kMethods));
+  }
+  ObjectArray* GetFields() const {
+      return down_cast<ObjectArray*>(Get(kFields));
+  }
+  DexCache();
+};
+
+}  // namespace art
+
+#endif  // ART_SRC_DEX_CACHE_H_
diff --git a/src/dex_cache_test.cc b/src/dex_cache_test.cc
new file mode 100644
index 0000000..7cfb634
--- /dev/null
+++ b/src/dex_cache_test.cc
@@ -0,0 +1,31 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#include "class_linker.h"
+#include "common_test.h"
+#include "dex_cache.h"
+#include "heap.h"
+#include "object.h"
+#include "scoped_ptr.h"
+
+#include <stdio.h>
+#include "gtest/gtest.h"
+
+namespace art {
+
+class DexCacheTest : public RuntimeTest {};
+
+TEST_F(DexCacheTest, Open) {
+
+  DexCache* dex_cache = down_cast<DexCache*>(class_linker_->AllocObjectArray(DexCache::kMax));
+  ASSERT_TRUE(dex_cache != NULL);
+  dex_cache->Init(class_linker_->AllocObjectArray(1),
+                  class_linker_->AllocObjectArray(2),
+                  class_linker_->AllocObjectArray(3),
+                  class_linker_->AllocObjectArray(4));
+  EXPECT_EQ(1U, dex_cache->NumStrings());
+  EXPECT_EQ(2U, dex_cache->NumClasses());
+  EXPECT_EQ(3U, dex_cache->NumMethods());
+  EXPECT_EQ(4U, dex_cache->NumFields());
+}
+
+}  // namespace art
diff --git a/src/dex_file.cc b/src/dex_file.cc
index e3c8fa0..506ae39 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -1,19 +1,270 @@
 // Copyright 2011 Google Inc. All Rights Reserved.
 
 #include "dex_file.h"
-#include "heap.h"
+
+#include <fcntl.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <map>
+
 #include "globals.h"
 #include "logging.h"
 #include "object.h"
-#include "raw_dex_file.h"
+#include "scoped_ptr.h"
+#include "utils.h"
 
 namespace art {
 
-void DexFile::Init(ObjectArray* strings, ObjectArray* classes, ObjectArray* methods, ObjectArray* fields) {
-  Set(kStrings, strings);
-  Set(kClasses, classes);
-  Set(kMethods, methods);
-  Set(kFields,  fields);
+const byte RawDexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
+const byte RawDexFile::kDexMagicVersion[] = { '0', '3', '5', '\0' };
+
+RawDexFile::Closer::~Closer() {}
+
+RawDexFile::MmapCloser::MmapCloser(void* addr, size_t length) : addr_(addr), length_(length) {
+  CHECK(addr != NULL);
+}
+RawDexFile::MmapCloser::~MmapCloser() {
+  if (munmap(addr_, length_) == -1) {
+    PLOG(INFO) << "munmap failed";
+  }
+}
+
+RawDexFile::PtrCloser::PtrCloser(byte* addr) : addr_(addr) {}
+RawDexFile::PtrCloser::~PtrCloser() { delete[] addr_; }
+
+RawDexFile* RawDexFile::OpenFile(const char* filename) {
+  CHECK(filename != NULL);
+  int fd = open(filename, O_RDONLY);  // TODO: scoped_fd
+  if (fd == -1) {
+    PLOG(ERROR) << "open(\"" << filename << "\", O_RDONLY) failed";
+    return NULL;
+  }
+  struct stat sbuf;
+  memset(&sbuf, 0, sizeof(sbuf));
+  if (fstat(fd, &sbuf) == -1) {
+    PLOG(ERROR) << "fstat \"" << filename << "\" failed";
+    close(fd);
+    return NULL;
+  }
+  size_t length = sbuf.st_size;
+  void* addr = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0);
+  if (addr == MAP_FAILED) {
+    PLOG(ERROR) << "mmap \"" << filename << "\" failed";
+    close(fd);
+    return NULL;
+  }
+  close(fd);
+  byte* dex_file = reinterpret_cast<byte*>(addr);
+  Closer* closer = new MmapCloser(addr, length);
+  return Open(dex_file, length, closer);
+}
+
+RawDexFile* RawDexFile::OpenPtr(byte* ptr, size_t length) {
+  CHECK(ptr != NULL);
+  RawDexFile::Closer* closer = new PtrCloser(ptr);
+  return Open(ptr, length, closer);
+}
+
+RawDexFile* RawDexFile::Open(const byte* dex_file, size_t length,
+                             Closer* closer) {
+  scoped_ptr<RawDexFile> raw(new RawDexFile(dex_file, length, closer));
+  if (!raw->Init()) {
+    return NULL;
+  } else {
+    return raw.release();
+  }
+}
+
+RawDexFile::~RawDexFile() {}
+
+bool RawDexFile::Init() {
+  InitMembers();
+  if (!IsMagicValid()) {
+    return false;
+  }
+  InitIndex();
+  return true;
+}
+
+void RawDexFile::InitMembers() {
+  const byte* b = base_;
+  header_ = reinterpret_cast<const Header*>(b);
+  const Header* h = header_;
+  string_ids_ = reinterpret_cast<const StringId*>(b + h->string_ids_off_);
+  type_ids_ = reinterpret_cast<const TypeId*>(b + h->type_ids_off_);
+  field_ids_ = reinterpret_cast<const FieldId*>(b + h->field_ids_off_);
+  method_ids_ = reinterpret_cast<const MethodId*>(b + h->method_ids_off_);
+  proto_ids_ = reinterpret_cast<const ProtoId*>(b + h->proto_ids_off_);
+  class_defs_ = reinterpret_cast<const ClassDef*>(b + h->class_defs_off_);
+}
+
+bool RawDexFile::IsMagicValid() {
+  return CheckMagic(header_->magic_);
+}
+
+bool RawDexFile::CheckMagic(const byte* magic) {
+  CHECK(magic != NULL);
+  if (memcmp(magic, kDexMagic, sizeof(kDexMagic)) != 0) {
+    LOG(WARNING) << "Unrecognized magic number:"
+            << " " << magic[0]
+            << " " << magic[1]
+            << " " << magic[2]
+            << " " << magic[3];
+    return false;
+  }
+  const byte* version = &magic[sizeof(kDexMagic)];
+  if (memcmp(version, kDexMagicVersion, sizeof(kDexMagicVersion)) != 0) {
+    LOG(WARNING) << "Unrecognized version number:"
+            << " " << version[0]
+            << " " << version[1]
+            << " " << version[2]
+            << " " << version[3];
+    return false;
+  }
+  return true;
+}
+
+void RawDexFile::InitIndex() {
+  CHECK_EQ(index_.size(), 0U);
+  for (size_t i = 0; i < NumClassDefs(); ++i) {
+    const ClassDef& class_def = GetClassDef(i);
+    const char* descriptor = GetClassDescriptor(class_def);
+    index_[descriptor] = &class_def;
+  }
+}
+
+const RawDexFile::ClassDef* RawDexFile::FindClassDef(const StringPiece& descriptor) const {
+  CHECK(descriptor != NULL);
+  Index::const_iterator it = index_.find(descriptor);
+  if (it == index_.end()) {
+    return NULL;
+  } else {
+    return it->second;
+  }
+}
+
+// Read a signed integer.  "zwidth" is the zero-based byte count.
+static int32_t ReadSignedInt(const byte* ptr, int zwidth)
+{
+  int32_t val = 0;
+  for (int i = zwidth; i >= 0; --i) {
+    val = ((uint32_t)val >> 8) | (((int32_t)*ptr++) << 24);
+  }
+  val >>= (3 - zwidth) * 8;
+  return val;
+}
+
+// Read an unsigned integer.  "zwidth" is the zero-based byte count,
+// "fill_on_right" indicates which side we want to zero-fill from.
+static uint32_t ReadUnsignedInt(const byte* ptr, int zwidth,
+                                bool fill_on_right) {
+  uint32_t val = 0;
+  if (!fill_on_right) {
+    for (int i = zwidth; i >= 0; --i) {
+      val = (val >> 8) | (((uint32_t)*ptr++) << 24);
+    }
+    val >>= (3 - zwidth) * 8;
+  } else {
+    for (int i = zwidth; i >= 0; --i) {
+      val = (val >> 8) | (((uint32_t)*ptr++) << 24);
+    }
+  }
+  return val;
+}
+
+// Read a signed long.  "zwidth" is the zero-based byte count.
+static int64_t ReadSignedLong(const byte* ptr, int zwidth) {
+  int64_t val = 0;
+  for (int i = zwidth; i >= 0; --i) {
+    val = ((uint64_t)val >> 8) | (((int64_t)*ptr++) << 56);
+  }
+  val >>= (7 - zwidth) * 8;
+  return val;
+}
+
+// Read an unsigned long.  "zwidth" is the zero-based byte count,
+// "fill_on_right" indicates which side we want to zero-fill from.
+static uint64_t ReadUnsignedLong(const byte* ptr, int zwidth,
+                                 bool fill_on_right) {
+  uint64_t val = 0;
+  if (!fill_on_right) {
+    for (int i = zwidth; i >= 0; --i) {
+      val = (val >> 8) | (((uint64_t)*ptr++) << 56);
+    }
+    val >>= (7 - zwidth) * 8;
+  } else {
+    for (int i = zwidth; i >= 0; --i) {
+      val = (val >> 8) | (((uint64_t)*ptr++) << 56);
+    }
+  }
+  return val;
+}
+
+RawDexFile::ValueType RawDexFile::ReadEncodedValue(const byte** stream,
+                                                   JValue* value) const {
+  const byte* ptr = *stream;
+  byte value_type = *ptr++;
+  byte value_arg = value_type >> kEncodedValueArgShift;
+  size_t width = value_arg + 1;  // assume and correct later
+  int type = value_type & kEncodedValueTypeMask;
+  switch (type) {
+    case RawDexFile::kByte: {
+      int32_t b = ReadSignedInt(ptr, value_arg);
+      CHECK(IsInt(8, b));
+      value->i = b;
+      break;
+    }
+    case RawDexFile::kShort: {
+      int32_t s = ReadSignedInt(ptr, value_arg);
+      CHECK(IsInt(16, s));
+      value->i = s;
+      break;
+    }
+    case RawDexFile::kChar: {
+      uint32_t c = ReadUnsignedInt(ptr, value_arg, false);
+      CHECK(IsUint(16, c));
+      value->i = c;
+      break;
+    }
+    case RawDexFile::kInt:
+      value->i = ReadSignedInt(ptr, value_arg);
+      break;
+    case RawDexFile::kLong:
+      value->j = ReadSignedLong(ptr, value_arg);
+      break;
+    case RawDexFile::kFloat:
+      value->i = ReadUnsignedInt(ptr, value_arg, true);
+      break;
+    case RawDexFile::kDouble:
+      value->j = ReadUnsignedLong(ptr, value_arg, true);
+      break;
+    case RawDexFile::kBoolean:
+      value->i = (value_arg != 0);
+      width = 0;
+      break;
+    case RawDexFile::kString:
+    case RawDexFile::kType:
+    case RawDexFile::kMethod:
+    case RawDexFile::kEnum:
+      value->i = ReadUnsignedInt(ptr, value_arg, false);
+      break;
+    case RawDexFile::kField:
+    case RawDexFile::kArray:
+    case RawDexFile::kAnnotation:
+      LOG(FATAL) << "Unimplemented";
+      break;
+    case RawDexFile::kNull:
+      value->i = 0;
+      width = 0;
+      break;
+    default:
+      LOG(FATAL) << "Unreached";
+  }
+  ptr += width;
+  *stream = ptr;
+  return static_cast<ValueType>(type);
 }
 
 }  // namespace art
diff --git a/src/dex_file.h b/src/dex_file.h
index 6339317..e677b42 100644
--- a/src/dex_file.h
+++ b/src/dex_file.h
@@ -3,93 +3,521 @@
 #ifndef ART_SRC_DEX_FILE_H_
 #define ART_SRC_DEX_FILE_H_
 
+#include <map>
+
 #include "globals.h"
-#include "macros.h"
-#include "object.h"
+#include "leb128.h"
+#include "logging.h"
+#include "scoped_ptr.h"
+#include "stringpiece.h"
+#include "strutil.h"
 
 namespace art {
 
-class Class;
-class Field;
-class Method;
-class String;
 union JValue;
 
-class DexFile : public ObjectArray {
+// TODO: move all of the macro functionality into the DexCache class.
+class RawDexFile {
  public:
+  static const byte kDexMagic[];
+  static const byte kDexMagicVersion[];
+  static const size_t kSha1DigestSize = 20;
 
-  enum ArrayIndexes {
-    kStrings = 0,
-    kClasses = 1,
-    kMethods = 2,
-    kFields  = 3,
-    kMax     = 4,
+  static const byte kEncodedValueTypeMask = 0x1f;  // 0b11111
+  static const byte kEncodedValueArgShift = 5;
+
+  // The value of an invalid index.
+  static const uint32_t kDexNoIndex = 0xFFFFFFFF;
+
+  enum ValueType {
+    kByte = 0x00,
+    kShort = 0x02,
+    kChar = 0x03,
+    kInt = 0x04,
+    kLong = 0x06,
+    kFloat = 0x10,
+    kDouble = 0x11,
+    kString = 0x17,
+    kType = 0x18,
+    kField = 0x19,
+    kMethod = 0x1a,
+    kEnum = 0x1b,
+    kArray = 0x1c,
+    kAnnotation = 0x1d,
+    kNull = 0x1e,
+    kBoolean = 0x1f
   };
 
-  void Init(ObjectArray* strings, ObjectArray* classes,  ObjectArray* methods,  ObjectArray* fields);
+  // Raw header_item.
+  struct Header {
+    uint8_t magic_[8];
+    uint32_t checksum_;
+    uint8_t signature_[kSha1DigestSize];
+    uint32_t file_size_;  // length of entire file
+    uint32_t header_size_;  // offset to start of next section
+    uint32_t endian_tag_;
+    uint32_t link_size_;
+    uint32_t link_off_;
+    uint32_t map_off_;
+    uint32_t string_ids_size_;
+    uint32_t string_ids_off_;
+    uint32_t type_ids_size_;
+    uint32_t type_ids_off_;
+    uint32_t proto_ids_size_;
+    uint32_t proto_ids_off_;
+    uint32_t field_ids_size_;
+    uint32_t field_ids_off_;
+    uint32_t method_ids_size_;
+    uint32_t method_ids_off_;
+    uint32_t class_defs_size_;
+    uint32_t class_defs_off_;
+    uint32_t data_size_;
+    uint32_t data_off_;
+  };
 
-  size_t NumStrings() const {
-    return GetStrings()->GetLength();
+  // Raw string_id_item.
+  struct StringId {
+    uint32_t string_data_off_;  // offset in bytes from the base address
+  };
+
+  // Raw type_id_item.
+  struct TypeId {
+    uint32_t descriptor_idx_;  // index into string_ids
+  };
+
+  // Raw field_id_item.
+  struct FieldId {
+    uint16_t class_idx_;  // index into typeIds list for defining class
+    uint16_t type_idx_;  // index into typeIds for field type
+    uint32_t name_idx_;  // index into stringIds for field name
+  };
+
+  // Raw method_id_item.
+  struct MethodId {
+    uint16_t class_idx_;  // index into typeIds list for defining class
+    uint16_t proto_idx_;  // index into protoIds for method prototype
+    uint32_t name_idx_;  // index into stringIds for method name
+  };
+
+  // Raw proto_id_item.
+  struct ProtoId {
+    uint32_t shorty_idx_;  // index into string_ids for shorty descriptor
+    uint32_t return_type_idx_;  // index into type_ids list for return type
+    uint32_t parameters_off_;  // file offset to type_list for parameter types
+  };
+
+  // Raw class_def_item.
+  struct ClassDef {
+    uint32_t class_idx_;  // index into typeIds for this class
+    uint32_t access_flags_;
+    uint32_t superclass_idx_;  // index into typeIds for superclass
+    uint32_t interfaces_off_;  // file offset to TypeList
+    uint32_t source_file_idx_;  // index into stringIds for source file name
+    uint32_t annotations_off_;  // file offset to annotations_directory_item
+    uint32_t class_data_off_;  // file offset to class_data_item
+    uint32_t static_values_off_;  // file offset to EncodedArray
+  };
+
+  // Raw type_item.
+  struct TypeItem {
+    uint16_t type_idx_;  // index into type_ids section
+  };
+
+  // Raw type_list.
+  class TypeList {
+   public:
+    uint32_t Size() const {
+      return size_;
+    }
+
+    const TypeItem& GetTypeItem(uint32_t idx) const {
+      CHECK_LT(idx, this->size_);
+      return this->list_[idx];
+    }
+
+   private:
+    uint32_t size_;  // size of the list, in entries
+    TypeItem list_[1];  // elements of the list
+  };
+
+  class ParameterIterator {  // TODO: stream
+   public:
+    ParameterIterator(const RawDexFile& raw, const ProtoId& proto_id)
+        : raw_(raw), size_(0), pos_(0) {
+      type_list_ = raw_.GetProtoParameters(proto_id);
+      if (type_list_ != NULL) {
+        size_ = type_list_->Size();
+      }
+    }
+    bool HasNext() const { return pos_ != size_; }
+    void Next() { ++pos_; }
+    const char* GetDescriptor() {
+      uint32_t type_idx = type_list_->GetTypeItem(pos_).type_idx_;
+      return raw_.dexStringByTypeIdx(type_idx);
+    }
+   private:
+    const RawDexFile& raw_;
+    const TypeList* type_list_;
+    uint32_t size_;
+    uint32_t pos_;
+    DISALLOW_IMPLICIT_CONSTRUCTORS(ParameterIterator);
+  };
+
+  ParameterIterator* GetParameterIterator(const ProtoId& proto_id) const {
+    return new ParameterIterator(*this, proto_id);
   }
 
-  size_t NumClasses() const {
-    return GetClasses()->GetLength();
+  const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const {
+    return dexStringByTypeIdx(proto_id.return_type_idx_);
   }
 
-  size_t NumMethods() const {
-    return GetMethods()->GetLength();
+  // Raw code_item.
+  struct CodeItem {
+    uint16_t registers_size_;
+    uint16_t ins_size_;
+    uint16_t outs_size_;
+    uint16_t tries_size_;
+    uint32_t debug_info_off_;  // file offset to debug info stream
+    uint32_t insns_size_;  // size of the insns array, in 2 byte code units
+    uint16_t insns_[1];
+  };
+
+  // Partially decoded form of class_data_item.
+  struct ClassDataHeader {
+    uint32_t static_fields_size_;  // the number of static fields
+    uint32_t instance_fields_size_;  // the number of instance fields
+    uint32_t direct_methods_size_;  // the number of direct methods
+    uint32_t virtual_methods_size_;  // the number of virtual methods
+  };
+
+  // Decoded form of encoded_field.
+  struct Field {
+    uint32_t field_idx_;  // index into the field_ids list for the identity of this field
+    uint32_t access_flags_;  // access flags for the field
+  };
+
+  // Decoded form of encoded_method.
+  struct Method {
+    uint32_t method_idx_;
+    uint32_t access_flags_;
+    uint32_t code_off_;
+  };
+
+  // Opens a .dex file from the file system.
+  static RawDexFile* OpenFile(const char* filename);
+
+  // Opens a .dex file from a new allocated pointer
+  static RawDexFile* OpenPtr(byte* ptr, size_t length);
+
+  // Closes a .dex file.
+  virtual ~RawDexFile();
+
+  const Header& GetHeader() {
+    CHECK(header_ != NULL);
+    return *header_;
   }
 
-  size_t NumFields() const {
-    return GetFields()->GetLength();
+  // Looks up a class definition by its class descriptor.
+  const ClassDef* FindClassDef(const StringPiece& descriptor) const;
+
+  // Returns the number of string identifiers in the .dex file.
+  size_t NumStringIds() const {
+    CHECK(header_ != NULL);
+    return header_->string_ids_size_;
   }
 
-  String* GetResolvedString(uint32_t string_idx) const {
-    return down_cast<String*>(GetStrings()->Get(string_idx));
+  // Returns the number of type identifiers in the .dex file.
+  size_t NumTypeIds() const {
+    CHECK(header_ != NULL);
+    return header_->type_ids_size_;
   }
 
-  void SetResolvedString(uint32_t string_idx, String* resolved) {
-    GetStrings()->Set(string_idx, resolved);
+  // Returns the number of prototype identifiers in the .dex file.
+  size_t NumProtoIds() const {
+    CHECK(header_ != NULL);
+    return header_->proto_ids_size_;
   }
 
-  Class* GetResolvedClass(uint32_t class_idx) const {
-    return down_cast<Class*>(GetClasses()->Get(class_idx));
+  // Returns the number of field identifiers in the .dex file.
+  size_t NumFieldIds() const {
+    CHECK(header_ != NULL);
+    return header_->field_ids_size_;
   }
 
-  void SetResolvedClass(uint32_t class_idx, Class* resolved) {
-    GetClasses()->Set(class_idx, resolved);
+  // Returns the number of method identifiers in the .dex file.
+  size_t NumMethodIds() const {
+    CHECK(header_ != NULL);
+    return header_->method_ids_size_;
   }
 
-  Method* GetResolvedMethod(uint32_t method_idx) const {
-    return down_cast<Method*>(GetMethods()->Get(method_idx));
+  // Returns the number of class definitions in the .dex file.
+  size_t NumClassDefs() const {
+    CHECK(header_ != NULL);
+    return header_->class_defs_size_;
   }
 
-  void SetResolvedMethod(uint32_t method_idx, Method* resolved) {
-    GetMethods()->Set(method_idx, resolved);
+  // Returns a pointer to the memory mapped class data.
+  // TODO: return a stream
+  const byte* GetClassData(const ClassDef& class_def) const {
+    if (class_def.class_data_off_ == 0) {
+      return NULL;
+    } else {
+      return base_ + class_def.class_data_off_;
+    }
   }
 
-  Field* GetResolvedField(uint32_t field_idx) const {
-    return down_cast<Field*>(GetFields()->Get(field_idx));
+  // Decodes the header section from the raw class data bytes.
+  ClassDataHeader ReadClassDataHeader(const byte** class_data) const {
+    CHECK(class_data != NULL);
+    ClassDataHeader header;
+    memset(&header, 0, sizeof(ClassDataHeader));
+    if (*class_data != NULL) {
+      header.static_fields_size_ = DecodeUnsignedLeb128(class_data);
+      header.instance_fields_size_ = DecodeUnsignedLeb128(class_data);
+      header.direct_methods_size_ = DecodeUnsignedLeb128(class_data);
+      header.virtual_methods_size_ = DecodeUnsignedLeb128(class_data);
+    }
+    return header;
   }
 
-  void SetResolvedfield(uint32_t field_idx, Field* resolved) {
-    GetFields()->Set(field_idx, resolved);
+  // Returns the class descriptor string of a class definition.
+  const char* GetClassDescriptor(const ClassDef& class_def) const {
+    return dexStringByTypeIdx(class_def.class_idx_);
+  }
+
+  // Returns the StringId at the specified index.
+  const StringId& GetStringId(uint32_t idx) const {
+    CHECK_LT(idx, NumStringIds());
+    return string_ids_[idx];
+  }
+
+  // Returns the TypeId at the specified index.
+  const TypeId& GetTypeId(uint32_t idx) const {
+    CHECK_LT(idx, NumTypeIds());
+    return type_ids_[idx];
+  }
+
+  // Returns the FieldId at the specified index.
+  const FieldId& GetFieldId(uint32_t idx) const {
+    CHECK_LT(idx, NumFieldIds());
+    return field_ids_[idx];
+  }
+
+  // Returns the MethodId at the specified index.
+  const MethodId& GetMethodId(uint32_t idx) const {
+    CHECK_LT(idx, NumMethodIds());
+    return method_ids_[idx];
+  }
+
+  // Returns the ProtoId at the specified index.
+  const ProtoId& GetProtoId(uint32_t idx) const {
+    CHECK_LT(idx, NumProtoIds());
+    return proto_ids_[idx];
+  }
+
+  // Returns the ClassDef at the specified index.
+  const ClassDef& GetClassDef(uint32_t idx) const {
+    CHECK_LT(idx, NumClassDefs());
+    return class_defs_[idx];
+  }
+
+  const TypeList* GetInterfacesList(const ClassDef& class_def) const {
+    if (class_def.interfaces_off_ == 0) {
+        return NULL;
+    } else {
+      const byte* addr = base_ + class_def.interfaces_off_;
+      return reinterpret_cast<const TypeList*>(addr);
+    }
+  }
+
+  const CodeItem* GetCodeItem(const Method& method) const {
+    if (method.code_off_ == 0) {
+      return NULL;  // native or abstract method
+    } else {
+      const byte* addr = base_ + method.code_off_;
+      return reinterpret_cast<const CodeItem*>(addr);
+    }
+  }
+
+  // Returns the short form method descriptor for the given prototype.
+  const char* GetShorty(uint32_t proto_idx) const {
+    const ProtoId& proto_id = GetProtoId(proto_idx);
+    return dexStringById(proto_id.shorty_idx_);
+  }
+
+  const TypeList* GetProtoParameters(const ProtoId& proto_id) const {
+    if (proto_id.parameters_off_ == 0) {
+      return NULL;
+    } else {
+      const byte* addr = base_ + proto_id.parameters_off_;
+      return reinterpret_cast<const TypeList*>(addr);
+    }
+  }
+
+  const byte* GetEncodedArray(const ClassDef& class_def) const {
+    if (class_def.static_values_off_ == 0) {
+      return 0;
+    } else {
+      return base_ + class_def.static_values_off_;
+    }
+  }
+
+  int32_t GetStringLength(const StringId& string_id) const {
+    const byte* ptr = base_ + string_id.string_data_off_;
+    return DecodeUnsignedLeb128(&ptr);
+  }
+
+  ValueType ReadEncodedValue(const byte** encoded_value, JValue* value) const;
+
+  // From libdex...
+
+  // Returns a pointer to the UTF-8 string data referred to by the
+  // given string_id.
+  const char* GetStringData(const StringId& string_id) const {
+    const byte* ptr = base_ + string_id.string_data_off_;
+    // Skip the uleb128 length.
+    while (*(ptr++) > 0x7f) /* empty */ ;
+    return (const char*) ptr;
+  }
+
+  // return the UTF-8 encoded string with the specified string_id index
+  const char* dexStringById(uint32_t idx) const {
+    const StringId& string_id = GetStringId(idx);
+    return GetStringData(string_id);
+  }
+
+  // Get the descriptor string associated with a given type index.
+  const char* dexStringByTypeIdx(uint32_t idx) const {
+    const TypeId& type_id = GetTypeId(idx);
+    return dexStringById(type_id.descriptor_idx_);
+  }
+
+  // TODO: encoded_field is actually a stream of bytes
+  void dexReadClassDataField(const byte** encoded_field,
+                             RawDexFile::Field* field,
+                             uint32_t* last_idx) const {
+    uint32_t idx = *last_idx + DecodeUnsignedLeb128(encoded_field);
+    field->access_flags_ = DecodeUnsignedLeb128(encoded_field);
+    field->field_idx_ = idx;
+    *last_idx = idx;
+  }
+
+  // TODO: encoded_method is actually a stream of bytes
+  void dexReadClassDataMethod(const byte** encoded_method,
+                              RawDexFile::Method* method,
+                              uint32_t* last_idx) const {
+    uint32_t idx = *last_idx + DecodeUnsignedLeb128(encoded_method);
+    method->access_flags_ = DecodeUnsignedLeb128(encoded_method);
+    method->code_off_ = DecodeUnsignedLeb128(encoded_method);
+    method->method_idx_ = idx;
+    *last_idx = idx;
+  }
+
+
+  // TODO: const reference
+  uint32_t dexGetIndexForClassDef(const ClassDef* class_def) const {
+    CHECK_GE(class_def, class_defs_);
+    CHECK_LT(class_def, class_defs_ + header_->class_defs_size_);
+    return class_def - class_defs_;
+  }
+
+  const char* dexGetSourceFile(const ClassDef& class_def) const {
+    if (class_def.source_file_idx_ == 0xffffffff) {
+      return NULL;
+    } else {
+      return dexStringById(class_def.source_file_idx_);
+    }
   }
 
  private:
-  ObjectArray* GetStrings() const {
-      return down_cast<ObjectArray*>(Get(kStrings));
-  }
-  ObjectArray* GetClasses() const {
-      return down_cast<ObjectArray*>(Get(kClasses));
-  }
-  ObjectArray* GetMethods() const {
-      return down_cast<ObjectArray*>(Get(kMethods));
-  }
-  ObjectArray* GetFields() const {
-      return down_cast<ObjectArray*>(Get(kFields));
-  }
-  DexFile();
+  // Helper class to deallocate underlying storage.
+  class Closer {
+   public:
+    virtual ~Closer();
+  };
+
+  // Helper class to deallocate mmap-backed .dex files.
+  class MmapCloser : public Closer {
+   public:
+    MmapCloser(void* addr, size_t length);
+    virtual ~MmapCloser();
+   private:
+    void* addr_;
+    size_t length_;
+  };
+
+  // Helper class for deallocating new/delete-backed .dex files.
+  class PtrCloser : public Closer {
+   public:
+    PtrCloser(byte* addr);
+    virtual ~PtrCloser();
+   private:
+    byte* addr_;
+  };
+
+  // Opens a .dex file at a the given address.
+  static RawDexFile* Open(const byte* dex_file, size_t length, Closer* closer);
+
+  RawDexFile(const byte* addr, size_t length, Closer* closer)
+      : base_(addr),
+        length_(length),
+        closer_(closer),
+        header_(0),
+        string_ids_(0),
+        type_ids_(0),
+        field_ids_(0),
+        method_ids_(0),
+        proto_ids_(0),
+        class_defs_(0) {}
+
+  // Top-level initializer that calls other Init methods.
+  bool Init();
+
+  // Caches pointers into to the various file sections.
+  void InitMembers();
+
+  // Builds the index of descriptors to class definitions.
+  void InitIndex();
+
+  // Returns true if the byte string equals the magic value.
+  bool CheckMagic(const byte* magic);
+
+  // Returns true if the header magic is of the expected value.
+  bool IsMagicValid();
+
+  // The index of descriptors to class definitions.
+  typedef std::map<const StringPiece, const RawDexFile::ClassDef*> Index;
+  Index index_;
+
+  // The base address of the memory mapping.
+  const byte* base_;
+
+  // The size of the underlying memory allocation in bytes.
+  size_t length_;
+
+  // Helper object to free the underlying allocation.
+  scoped_ptr<Closer> closer_;
+
+  // Points to the header section.
+  const Header* header_;
+
+  // Points to the base of the string identifier list.
+  const StringId* string_ids_;
+
+  // Points to the base of the type identifier list.
+  const TypeId* type_ids_;
+
+  // Points to the base of the field identifier list.
+  const FieldId* field_ids_;
+
+  // Points to the base of the method identifier list.
+  const MethodId* method_ids_;
+
+  // Points to the base of the prototype identifier list.
+  const ProtoId* proto_ids_;
+
+  // Points to the base of the class definition list.
+  const ClassDef* class_defs_;
 };
 
 }  // namespace art
diff --git a/src/dex_file_test.cc b/src/dex_file_test.cc
index 0ad0b3b..b6a7e77 100644
--- a/src/dex_file_test.cc
+++ b/src/dex_file_test.cc
@@ -1,10 +1,7 @@
 // Copyright 2011 Google Inc. All Rights Reserved.
 
-#include "class_linker.h"
 #include "common_test.h"
 #include "dex_file.h"
-#include "heap.h"
-#include "object.h"
 #include "scoped_ptr.h"
 
 #include <stdio.h>
@@ -12,20 +9,49 @@
 
 namespace art {
 
-class DexFileTest : public RuntimeTest {};
+TEST(RawDexFileTest, Open) {
+  scoped_ptr<RawDexFile> raw(OpenRawDexFileBase64(kNestedDex));
+  ASSERT_TRUE(raw != NULL);
+}
 
-TEST_F(DexFileTest, Open) {
+TEST(RawDexFileTest, Header) {
+  scoped_ptr<RawDexFile> raw(OpenRawDexFileBase64(kNestedDex));
+  ASSERT_TRUE(raw != NULL);
 
-  DexFile* dex_file = down_cast<DexFile*>(class_linker_->AllocObjectArray(DexFile::kMax));
-  ASSERT_TRUE(dex_file != NULL);
-  dex_file->Init(class_linker_->AllocObjectArray(1),
-                 class_linker_->AllocObjectArray(2),
-                 class_linker_->AllocObjectArray(3),
-                 class_linker_->AllocObjectArray(4));
-  EXPECT_EQ(1U, dex_file->NumStrings());
-  EXPECT_EQ(2U, dex_file->NumClasses());
-  EXPECT_EQ(3U, dex_file->NumMethods());
-  EXPECT_EQ(4U, dex_file->NumFields());
+  const RawDexFile::Header& header = raw->GetHeader();
+  // TODO: header.magic_
+  EXPECT_EQ(0x00d87910U, header.checksum_);
+  // TODO: header.signature_
+  EXPECT_EQ(904U, header.file_size_);
+  EXPECT_EQ(112U, header.header_size_);
+  EXPECT_EQ(0U, header.link_size_);
+  EXPECT_EQ(0U, header.link_off_);
+  EXPECT_EQ(15U, header.string_ids_size_);
+  EXPECT_EQ(112U, header.string_ids_off_);
+  EXPECT_EQ(7U, header.type_ids_size_);
+  EXPECT_EQ(172U, header.type_ids_off_);
+  EXPECT_EQ(2U, header.proto_ids_size_);
+  EXPECT_EQ(200U, header.proto_ids_off_);
+  EXPECT_EQ(1U, header.field_ids_size_);
+  EXPECT_EQ(224U, header.field_ids_off_);
+  EXPECT_EQ(3U, header.method_ids_size_);
+  EXPECT_EQ(232U, header.method_ids_off_);
+  EXPECT_EQ(2U, header.class_defs_size_);
+  EXPECT_EQ(256U, header.class_defs_off_);
+  EXPECT_EQ(584U, header.data_size_);
+  EXPECT_EQ(320U, header.data_off_);
+}
+
+TEST(RawDexFileTest, ClassDefs) {
+  scoped_ptr<RawDexFile> raw(OpenRawDexFileBase64(kNestedDex));
+  ASSERT_TRUE(raw != NULL);
+  EXPECT_EQ(2U, raw->NumClassDefs());
+
+  const RawDexFile::ClassDef& c0 = raw->GetClassDef(0);
+  EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c0));
+
+  const RawDexFile::ClassDef& c1 = raw->GetClassDef(1);
+  EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
 }
 
 }  // namespace art
diff --git a/src/object.cc b/src/object.cc
index fb80fb9..6d18beb 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -7,8 +7,8 @@
 
 #include "globals.h"
 #include "logging.h"
+#include "dex_cache.h"
 #include "dex_file.h"
-#include "raw_dex_file.h"
 
 namespace art {
 
diff --git a/src/object.h b/src/object.h
index abbf6ca..770e8bb 100644
--- a/src/object.h
+++ b/src/object.h
@@ -16,7 +16,7 @@
 
 class Array;
 class Class;
-class DexFile;
+class DexCache;
 class InstanceField;
 class InterfaceEntry;
 class Monitor;
@@ -385,7 +385,7 @@
   }
 
   // const char* GetReturnTypeDescriptor() const {
-  //   return declaring_class_->GetDexFile_->GetRaw()
+  //   return FindDexFile(declaring_class_->GetDexCache()
   //          ->dexStringByTypeIdx(proto_id_.return_type_id_);
   // }
 
@@ -596,8 +596,8 @@
     return class_loader_;
   }
 
-  DexFile* GetDexFile() const {
-    return dex_file_;
+  DexCache* GetDexCache() const {
+    return dex_cache_;
   }
 
   Class* GetComponentType() const {
@@ -779,9 +779,9 @@
   // access flags; low 16 bits are defined by VM spec
   uint32_t access_flags_;  // TODO: make an instance field?
 
-  // DexFile from which we came; needed to resolve constant pool entries
+  // DexCache of resolved constant pool entries
   // (will be NULL for VM-generated, e.g. arrays and primitive classes)
-  DexFile* dex_file_;
+  DexCache* dex_cache_;
 
   // state of class initialization
   Status status_;
@@ -924,7 +924,7 @@
 
 class CharArray : public Array {
  private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(CharArray);
+  CharArray();
 };
 
 class ObjectArray : public Array {
diff --git a/src/raw_dex_file.cc b/src/raw_dex_file.cc
deleted file mode 100644
index 21badb4..0000000
--- a/src/raw_dex_file.cc
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-
-#include "raw_dex_file.h"
-
-#include <fcntl.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <map>
-
-#include "globals.h"
-#include "logging.h"
-#include "object.h"
-#include "scoped_ptr.h"
-#include "utils.h"
-
-namespace art {
-
-const byte RawDexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
-const byte RawDexFile::kDexMagicVersion[] = { '0', '3', '5', '\0' };
-
-RawDexFile::Closer::~Closer() {}
-
-RawDexFile::MmapCloser::MmapCloser(void* addr, size_t length) : addr_(addr), length_(length) {
-  CHECK(addr != NULL);
-}
-RawDexFile::MmapCloser::~MmapCloser() {
-  if (munmap(addr_, length_) == -1) {
-    PLOG(INFO) << "munmap failed";
-  }
-}
-
-RawDexFile::PtrCloser::PtrCloser(byte* addr) : addr_(addr) {}
-RawDexFile::PtrCloser::~PtrCloser() { delete[] addr_; }
-
-RawDexFile* RawDexFile::OpenFile(const char* filename) {
-  CHECK(filename != NULL);
-  int fd = open(filename, O_RDONLY);  // TODO: scoped_fd
-  if (fd == -1) {
-    PLOG(ERROR) << "open(\"" << filename << "\", O_RDONLY) failed";
-    return NULL;
-  }
-  struct stat sbuf;
-  memset(&sbuf, 0, sizeof(sbuf));
-  if (fstat(fd, &sbuf) == -1) {
-    PLOG(ERROR) << "fstat \"" << filename << "\" failed";
-    close(fd);
-    return NULL;
-  }
-  size_t length = sbuf.st_size;
-  void* addr = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0);
-  if (addr == MAP_FAILED) {
-    PLOG(ERROR) << "mmap \"" << filename << "\" failed";
-    close(fd);
-    return NULL;
-  }
-  close(fd);
-  byte* dex_file = reinterpret_cast<byte*>(addr);
-  Closer* closer = new MmapCloser(addr, length);
-  return Open(dex_file, length, closer);
-}
-
-RawDexFile* RawDexFile::OpenPtr(byte* ptr, size_t length) {
-  CHECK(ptr != NULL);
-  RawDexFile::Closer* closer = new PtrCloser(ptr);
-  return Open(ptr, length, closer);
-}
-
-RawDexFile* RawDexFile::Open(const byte* dex_file, size_t length,
-                             Closer* closer) {
-  scoped_ptr<RawDexFile> raw(new RawDexFile(dex_file, length, closer));
-  if (!raw->Init()) {
-    return NULL;
-  } else {
-    return raw.release();
-  }
-}
-
-RawDexFile::~RawDexFile() {}
-
-bool RawDexFile::Init() {
-  InitMembers();
-  if (!IsMagicValid()) {
-    return false;
-  }
-  InitIndex();
-  return true;
-}
-
-void RawDexFile::InitMembers() {
-  const byte* b = base_;
-  header_ = reinterpret_cast<const Header*>(b);
-  const Header* h = header_;
-  string_ids_ = reinterpret_cast<const StringId*>(b + h->string_ids_off_);
-  type_ids_ = reinterpret_cast<const TypeId*>(b + h->type_ids_off_);
-  field_ids_ = reinterpret_cast<const FieldId*>(b + h->field_ids_off_);
-  method_ids_ = reinterpret_cast<const MethodId*>(b + h->method_ids_off_);
-  proto_ids_ = reinterpret_cast<const ProtoId*>(b + h->proto_ids_off_);
-  class_defs_ = reinterpret_cast<const ClassDef*>(b + h->class_defs_off_);
-}
-
-bool RawDexFile::IsMagicValid() {
-  return CheckMagic(header_->magic_);
-}
-
-bool RawDexFile::CheckMagic(const byte* magic) {
-  CHECK(magic != NULL);
-  if (memcmp(magic, kDexMagic, sizeof(kDexMagic)) != 0) {
-    LOG(WARNING) << "Unrecognized magic number:"
-            << " " << magic[0]
-            << " " << magic[1]
-            << " " << magic[2]
-            << " " << magic[3];
-    return false;
-  }
-  const byte* version = &magic[sizeof(kDexMagic)];
-  if (memcmp(version, kDexMagicVersion, sizeof(kDexMagicVersion)) != 0) {
-    LOG(WARNING) << "Unrecognized version number:"
-            << " " << version[0]
-            << " " << version[1]
-            << " " << version[2]
-            << " " << version[3];
-    return false;
-  }
-  return true;
-}
-
-void RawDexFile::InitIndex() {
-  CHECK_EQ(index_.size(), 0U);
-  for (size_t i = 0; i < NumClassDefs(); ++i) {
-    const ClassDef& class_def = GetClassDef(i);
-    const char* descriptor = GetClassDescriptor(class_def);
-    index_[descriptor] = &class_def;
-  }
-}
-
-const RawDexFile::ClassDef* RawDexFile::FindClassDef(const StringPiece& descriptor) const {
-  CHECK(descriptor != NULL);
-  Index::const_iterator it = index_.find(descriptor);
-  if (it == index_.end()) {
-    return NULL;
-  } else {
-    return it->second;
-  }
-}
-
-// Read a signed integer.  "zwidth" is the zero-based byte count.
-static int32_t ReadSignedInt(const byte* ptr, int zwidth)
-{
-  int32_t val = 0;
-  for (int i = zwidth; i >= 0; --i) {
-    val = ((uint32_t)val >> 8) | (((int32_t)*ptr++) << 24);
-  }
-  val >>= (3 - zwidth) * 8;
-  return val;
-}
-
-// Read an unsigned integer.  "zwidth" is the zero-based byte count,
-// "fill_on_right" indicates which side we want to zero-fill from.
-static uint32_t ReadUnsignedInt(const byte* ptr, int zwidth,
-                                bool fill_on_right) {
-  uint32_t val = 0;
-  if (!fill_on_right) {
-    for (int i = zwidth; i >= 0; --i) {
-      val = (val >> 8) | (((uint32_t)*ptr++) << 24);
-    }
-    val >>= (3 - zwidth) * 8;
-  } else {
-    for (int i = zwidth; i >= 0; --i) {
-      val = (val >> 8) | (((uint32_t)*ptr++) << 24);
-    }
-  }
-  return val;
-}
-
-// Read a signed long.  "zwidth" is the zero-based byte count.
-static int64_t ReadSignedLong(const byte* ptr, int zwidth) {
-  int64_t val = 0;
-  for (int i = zwidth; i >= 0; --i) {
-    val = ((uint64_t)val >> 8) | (((int64_t)*ptr++) << 56);
-  }
-  val >>= (7 - zwidth) * 8;
-  return val;
-}
-
-// Read an unsigned long.  "zwidth" is the zero-based byte count,
-// "fill_on_right" indicates which side we want to zero-fill from.
-static uint64_t ReadUnsignedLong(const byte* ptr, int zwidth,
-                                 bool fill_on_right) {
-  uint64_t val = 0;
-  if (!fill_on_right) {
-    for (int i = zwidth; i >= 0; --i) {
-      val = (val >> 8) | (((uint64_t)*ptr++) << 56);
-    }
-    val >>= (7 - zwidth) * 8;
-  } else {
-    for (int i = zwidth; i >= 0; --i) {
-      val = (val >> 8) | (((uint64_t)*ptr++) << 56);
-    }
-  }
-  return val;
-}
-
-RawDexFile::ValueType RawDexFile::ReadEncodedValue(const byte** stream,
-                                                   JValue* value) const {
-  const byte* ptr = *stream;
-  byte value_type = *ptr++;
-  byte value_arg = value_type >> kEncodedValueArgShift;
-  size_t width = value_arg + 1;  // assume and correct later
-  int type = value_type & kEncodedValueTypeMask;
-  switch (type) {
-    case RawDexFile::kByte: {
-      int32_t b = ReadSignedInt(ptr, value_arg);
-      CHECK(IsInt(8, b));
-      value->i = b;
-      break;
-    }
-    case RawDexFile::kShort: {
-      int32_t s = ReadSignedInt(ptr, value_arg);
-      CHECK(IsInt(16, s));
-      value->i = s;
-      break;
-    }
-    case RawDexFile::kChar: {
-      uint32_t c = ReadUnsignedInt(ptr, value_arg, false);
-      CHECK(IsUint(16, c));
-      value->i = c;
-      break;
-    }
-    case RawDexFile::kInt:
-      value->i = ReadSignedInt(ptr, value_arg);
-      break;
-    case RawDexFile::kLong:
-      value->j = ReadSignedLong(ptr, value_arg);
-      break;
-    case RawDexFile::kFloat:
-      value->i = ReadUnsignedInt(ptr, value_arg, true);
-      break;
-    case RawDexFile::kDouble:
-      value->j = ReadUnsignedLong(ptr, value_arg, true);
-      break;
-    case RawDexFile::kBoolean:
-      value->i = (value_arg != 0);
-      width = 0;
-      break;
-    case RawDexFile::kString:
-    case RawDexFile::kType:
-    case RawDexFile::kMethod:
-    case RawDexFile::kEnum:
-      value->i = ReadUnsignedInt(ptr, value_arg, false);
-      break;
-    case RawDexFile::kField:
-    case RawDexFile::kArray:
-    case RawDexFile::kAnnotation:
-      LOG(FATAL) << "Unimplemented";
-      break;
-    case RawDexFile::kNull:
-      value->i = 0;
-      width = 0;
-      break;
-    default:
-      LOG(FATAL) << "Unreached";
-  }
-  ptr += width;
-  *stream = ptr;
-  return static_cast<ValueType>(type);
-}
-
-}  // namespace art
diff --git a/src/raw_dex_file.h b/src/raw_dex_file.h
deleted file mode 100644
index da7cd86..0000000
--- a/src/raw_dex_file.h
+++ /dev/null
@@ -1,525 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-
-#ifndef ART_SRC_RAW_DEX_FILE_H_
-#define ART_SRC_RAW_DEX_FILE_H_
-
-#include "globals.h"
-#include "leb128.h"
-#include "logging.h"
-#include "scoped_ptr.h"
-#include "stringpiece.h"
-#include "strutil.h"
-
-#include <map>
-
-namespace art {
-
-union JValue;
-
-// TODO: move all of the macro functionality into the DexFile class.
-class RawDexFile {
- public:
-  static const byte kDexMagic[];
-  static const byte kDexMagicVersion[];
-  static const size_t kSha1DigestSize = 20;
-
-  static const byte kEncodedValueTypeMask = 0x1f;  // 0b11111
-  static const byte kEncodedValueArgShift = 5;
-
-  // The value of an invalid index.
-  static const uint32_t kDexNoIndex = 0xFFFFFFFF;
-
-  enum ValueType {
-    kByte = 0x00,
-    kShort = 0x02,
-    kChar = 0x03,
-    kInt = 0x04,
-    kLong = 0x06,
-    kFloat = 0x10,
-    kDouble = 0x11,
-    kString = 0x17,
-    kType = 0x18,
-    kField = 0x19,
-    kMethod = 0x1a,
-    kEnum = 0x1b,
-    kArray = 0x1c,
-    kAnnotation = 0x1d,
-    kNull = 0x1e,
-    kBoolean = 0x1f
-  };
-
-  // Raw header_item.
-  struct Header {
-    uint8_t magic_[8];
-    uint32_t checksum_;
-    uint8_t signature_[kSha1DigestSize];
-    uint32_t file_size_;  // length of entire file
-    uint32_t header_size_;  // offset to start of next section
-    uint32_t endian_tag_;
-    uint32_t link_size_;
-    uint32_t link_off_;
-    uint32_t map_off_;
-    uint32_t string_ids_size_;
-    uint32_t string_ids_off_;
-    uint32_t type_ids_size_;
-    uint32_t type_ids_off_;
-    uint32_t proto_ids_size_;
-    uint32_t proto_ids_off_;
-    uint32_t field_ids_size_;
-    uint32_t field_ids_off_;
-    uint32_t method_ids_size_;
-    uint32_t method_ids_off_;
-    uint32_t class_defs_size_;
-    uint32_t class_defs_off_;
-    uint32_t data_size_;
-    uint32_t data_off_;
-  };
-
-  // Raw string_id_item.
-  struct StringId {
-    uint32_t string_data_off_;  // offset in bytes from the base address
-  };
-
-  // Raw type_id_item.
-  struct TypeId {
-    uint32_t descriptor_idx_;  // index into string_ids
-  };
-
-  // Raw field_id_item.
-  struct FieldId {
-    uint16_t class_idx_;  // index into typeIds list for defining class
-    uint16_t type_idx_;  // index into typeIds for field type
-    uint32_t name_idx_;  // index into stringIds for field name
-  };
-
-  // Raw method_id_item.
-  struct MethodId {
-    uint16_t class_idx_;  // index into typeIds list for defining class
-    uint16_t proto_idx_;  // index into protoIds for method prototype
-    uint32_t name_idx_;  // index into stringIds for method name
-  };
-
-  // Raw proto_id_item.
-  struct ProtoId {
-    uint32_t shorty_idx_;  // index into string_ids for shorty descriptor
-    uint32_t return_type_idx_;  // index into type_ids list for return type
-    uint32_t parameters_off_;  // file offset to type_list for parameter types
-  };
-
-  // Raw class_def_item.
-  struct ClassDef {
-    uint32_t class_idx_;  // index into typeIds for this class
-    uint32_t access_flags_;
-    uint32_t superclass_idx_;  // index into typeIds for superclass
-    uint32_t interfaces_off_;  // file offset to TypeList
-    uint32_t source_file_idx_;  // index into stringIds for source file name
-    uint32_t annotations_off_;  // file offset to annotations_directory_item
-    uint32_t class_data_off_;  // file offset to class_data_item
-    uint32_t static_values_off_;  // file offset to EncodedArray
-  };
-
-  // Raw type_item.
-  struct TypeItem {
-    uint16_t type_idx_;  // index into type_ids section
-  };
-
-  // Raw type_list.
-  class TypeList {
-   public:
-    uint32_t Size() const {
-      return size_;
-    }
-
-    const TypeItem& GetTypeItem(uint32_t idx) const {
-      CHECK_LT(idx, this->size_);
-      return this->list_[idx];
-    }
-
-   private:
-    uint32_t size_;  // size of the list, in entries
-    TypeItem list_[1];  // elements of the list
-  };
-
-  class ParameterIterator {  // TODO: stream
-   public:
-    ParameterIterator(const RawDexFile& raw, const ProtoId& proto_id)
-        : raw_(raw), size_(0), pos_(0) {
-      type_list_ = raw_.GetProtoParameters(proto_id);
-      if (type_list_ != NULL) {
-        size_ = type_list_->Size();
-      }
-    }
-    bool HasNext() const { return pos_ != size_; }
-    void Next() { ++pos_; }
-    const char* GetDescriptor() {
-      uint32_t type_idx = type_list_->GetTypeItem(pos_).type_idx_;
-      return raw_.dexStringByTypeIdx(type_idx);
-    }
-   private:
-    const RawDexFile& raw_;
-    const TypeList* type_list_;
-    uint32_t size_;
-    uint32_t pos_;
-    DISALLOW_IMPLICIT_CONSTRUCTORS(ParameterIterator);
-  };
-
-  ParameterIterator* GetParameterIterator(const ProtoId& proto_id) const {
-    return new ParameterIterator(*this, proto_id);
-  }
-
-  const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const {
-    return dexStringByTypeIdx(proto_id.return_type_idx_);
-  }
-
-  // Raw code_item.
-  struct CodeItem {
-    uint16_t registers_size_;
-    uint16_t ins_size_;
-    uint16_t outs_size_;
-    uint16_t tries_size_;
-    uint32_t debug_info_off_;  // file offset to debug info stream
-    uint32_t insns_size_;  // size of the insns array, in 2 byte code units
-    uint16_t insns_[1];
-  };
-
-  // Partially decoded form of class_data_item.
-  struct ClassDataHeader {
-    uint32_t static_fields_size_;  // the number of static fields
-    uint32_t instance_fields_size_;  // the number of instance fields
-    uint32_t direct_methods_size_;  // the number of direct methods
-    uint32_t virtual_methods_size_;  // the number of virtual methods
-  };
-
-  // Decoded form of encoded_field.
-  struct Field {
-    uint32_t field_idx_;  // index into the field_ids list for the identity of this field
-    uint32_t access_flags_;  // access flags for the field
-  };
-
-  // Decoded form of encoded_method.
-  struct Method {
-    uint32_t method_idx_;
-    uint32_t access_flags_;
-    uint32_t code_off_;
-  };
-
-  // Opens a .dex file from the file system.
-  static RawDexFile* OpenFile(const char* filename);
-
-  // Opens a .dex file from a new allocated pointer
-  static RawDexFile* OpenPtr(byte* ptr, size_t length);
-
-  // Closes a .dex file.
-  virtual ~RawDexFile();
-
-  const Header& GetHeader() {
-    CHECK(header_ != NULL);
-    return *header_;
-  }
-
-  // Looks up a class definition by its class descriptor.
-  const ClassDef* FindClassDef(const StringPiece& descriptor) const;
-
-  // Returns the number of string identifiers in the .dex file.
-  size_t NumStringIds() const {
-    CHECK(header_ != NULL);
-    return header_->string_ids_size_;
-  }
-
-  // Returns the number of type identifiers in the .dex file.
-  size_t NumTypeIds() const {
-    CHECK(header_ != NULL);
-    return header_->type_ids_size_;
-  }
-
-  // Returns the number of prototype identifiers in the .dex file.
-  size_t NumProtoIds() const {
-    CHECK(header_ != NULL);
-    return header_->proto_ids_size_;
-  }
-
-  // Returns the number of field identifiers in the .dex file.
-  size_t NumFieldIds() const {
-    CHECK(header_ != NULL);
-    return header_->field_ids_size_;
-  }
-
-  // Returns the number of method identifiers in the .dex file.
-  size_t NumMethodIds() const {
-    CHECK(header_ != NULL);
-    return header_->method_ids_size_;
-  }
-
-  // Returns the number of class definitions in the .dex file.
-  size_t NumClassDefs() const {
-    CHECK(header_ != NULL);
-    return header_->class_defs_size_;
-  }
-
-  // Returns a pointer to the memory mapped class data.
-  // TODO: return a stream
-  const byte* GetClassData(const ClassDef& class_def) const {
-    if (class_def.class_data_off_ == 0) {
-      return NULL;
-    } else {
-      return base_ + class_def.class_data_off_;
-    }
-  }
-
-  // Decodes the header section from the raw class data bytes.
-  ClassDataHeader ReadClassDataHeader(const byte** class_data) const {
-    CHECK(class_data != NULL);
-    ClassDataHeader header;
-    memset(&header, 0, sizeof(ClassDataHeader));
-    if (*class_data != NULL) {
-      header.static_fields_size_ = DecodeUnsignedLeb128(class_data);
-      header.instance_fields_size_ = DecodeUnsignedLeb128(class_data);
-      header.direct_methods_size_ = DecodeUnsignedLeb128(class_data);
-      header.virtual_methods_size_ = DecodeUnsignedLeb128(class_data);
-    }
-    return header;
-  }
-
-  // Returns the class descriptor string of a class definition.
-  const char* GetClassDescriptor(const ClassDef& class_def) const {
-    return dexStringByTypeIdx(class_def.class_idx_);
-  }
-
-  // Returns the StringId at the specified index.
-  const StringId& GetStringId(uint32_t idx) const {
-    CHECK_LT(idx, NumStringIds());
-    return string_ids_[idx];
-  }
-
-  // Returns the TypeId at the specified index.
-  const TypeId& GetTypeId(uint32_t idx) const {
-    CHECK_LT(idx, NumTypeIds());
-    return type_ids_[idx];
-  }
-
-  // Returns the FieldId at the specified index.
-  const FieldId& GetFieldId(uint32_t idx) const {
-    CHECK_LT(idx, NumFieldIds());
-    return field_ids_[idx];
-  }
-
-  // Returns the MethodId at the specified index.
-  const MethodId& GetMethodId(uint32_t idx) const {
-    CHECK_LT(idx, NumMethodIds());
-    return method_ids_[idx];
-  }
-
-  // Returns the ProtoId at the specified index.
-  const ProtoId& GetProtoId(uint32_t idx) const {
-    CHECK_LT(idx, NumProtoIds());
-    return proto_ids_[idx];
-  }
-
-  // Returns the ClassDef at the specified index.
-  const ClassDef& GetClassDef(uint32_t idx) const {
-    CHECK_LT(idx, NumClassDefs());
-    return class_defs_[idx];
-  }
-
-  const TypeList* GetInterfacesList(const ClassDef& class_def) const {
-    if (class_def.interfaces_off_ == 0) {
-        return NULL;
-    } else {
-      const byte* addr = base_ + class_def.interfaces_off_;
-      return reinterpret_cast<const TypeList*>(addr);
-    }
-  }
-
-  const CodeItem* GetCodeItem(const Method& method) const {
-    if (method.code_off_ == 0) {
-      return NULL;  // native or abstract method
-    } else {
-      const byte* addr = base_ + method.code_off_;
-      return reinterpret_cast<const CodeItem*>(addr);
-    }
-  }
-
-  // Returns the short form method descriptor for the given prototype.
-  const char* GetShorty(uint32_t proto_idx) const {
-    const ProtoId& proto_id = GetProtoId(proto_idx);
-    return dexStringById(proto_id.shorty_idx_);
-  }
-
-  const TypeList* GetProtoParameters(const ProtoId& proto_id) const {
-    if (proto_id.parameters_off_ == 0) {
-      return NULL;
-    } else {
-      const byte* addr = base_ + proto_id.parameters_off_;
-      return reinterpret_cast<const TypeList*>(addr);
-    }
-  }
-
-  const byte* GetEncodedArray(const ClassDef& class_def) const {
-    if (class_def.static_values_off_ == 0) {
-      return 0;
-    } else {
-      return base_ + class_def.static_values_off_;
-    }
-  }
-
-  int32_t GetStringLength(const StringId& string_id) const {
-    const byte* ptr = base_ + string_id.string_data_off_;
-    return DecodeUnsignedLeb128(&ptr);
-  }
-
-  ValueType ReadEncodedValue(const byte** encoded_value, JValue* value) const;
-
-  // From libdex...
-
-  // Returns a pointer to the UTF-8 string data referred to by the
-  // given string_id.
-  const char* GetStringData(const StringId& string_id) const {
-    const byte* ptr = base_ + string_id.string_data_off_;
-    // Skip the uleb128 length.
-    while (*(ptr++) > 0x7f) /* empty */ ;
-    return (const char*) ptr;
-  }
-
-  // return the UTF-8 encoded string with the specified string_id index
-  const char* dexStringById(uint32_t idx) const {
-    const StringId& string_id = GetStringId(idx);
-    return GetStringData(string_id);
-  }
-
-  // Get the descriptor string associated with a given type index.
-  const char* dexStringByTypeIdx(uint32_t idx) const {
-    const TypeId& type_id = GetTypeId(idx);
-    return dexStringById(type_id.descriptor_idx_);
-  }
-
-  // TODO: encoded_field is actually a stream of bytes
-  void dexReadClassDataField(const byte** encoded_field,
-                             RawDexFile::Field* field,
-                             uint32_t* last_idx) const {
-    uint32_t idx = *last_idx + DecodeUnsignedLeb128(encoded_field);
-    field->access_flags_ = DecodeUnsignedLeb128(encoded_field);
-    field->field_idx_ = idx;
-    *last_idx = idx;
-  }
-
-  // TODO: encoded_method is actually a stream of bytes
-  void dexReadClassDataMethod(const byte** encoded_method,
-                              RawDexFile::Method* method,
-                              uint32_t* last_idx) const {
-    uint32_t idx = *last_idx + DecodeUnsignedLeb128(encoded_method);
-    method->access_flags_ = DecodeUnsignedLeb128(encoded_method);
-    method->code_off_ = DecodeUnsignedLeb128(encoded_method);
-    method->method_idx_ = idx;
-    *last_idx = idx;
-  }
-
-
-  // TODO: const reference
-  uint32_t dexGetIndexForClassDef(const ClassDef* class_def) const {
-    CHECK_GE(class_def, class_defs_);
-    CHECK_LT(class_def, class_defs_ + header_->class_defs_size_);
-    return class_def - class_defs_;
-  }
-
-  const char* dexGetSourceFile(const ClassDef& class_def) const {
-    if (class_def.source_file_idx_ == 0xffffffff) {
-      return NULL;
-    } else {
-      return dexStringById(class_def.source_file_idx_);
-    }
-  }
-
- private:
-  // Helper class to deallocate underlying storage.
-  class Closer {
-   public:
-    virtual ~Closer();
-  };
-
-  // Helper class to deallocate mmap-backed .dex files.
-  class MmapCloser : public Closer {
-   public:
-    MmapCloser(void* addr, size_t length);
-    virtual ~MmapCloser();
-   private:
-    void* addr_;
-    size_t length_;
-  };
-
-  // Helper class for deallocating new/delete-backed .dex files.
-  class PtrCloser : public Closer {
-   public:
-    PtrCloser(byte* addr);
-    virtual ~PtrCloser();
-   private:
-    byte* addr_;
-  };
-
-  // Opens a .dex file at a the given address.
-  static RawDexFile* Open(const byte* dex_file, size_t length, Closer* closer);
-
-  RawDexFile(const byte* addr, size_t length, Closer* closer)
-      : base_(addr),
-        length_(length),
-        closer_(closer),
-        header_(0),
-        string_ids_(0),
-        type_ids_(0),
-        field_ids_(0),
-        method_ids_(0),
-        proto_ids_(0),
-        class_defs_(0) {}
-
-  // Top-level initializer that calls other Init methods.
-  bool Init();
-
-  // Caches pointers into to the various file sections.
-  void InitMembers();
-
-  // Builds the index of descriptors to class definitions.
-  void InitIndex();
-
-  // Returns true if the byte string equals the magic value.
-  bool CheckMagic(const byte* magic);
-
-  // Returns true if the header magic is of the expected value.
-  bool IsMagicValid();
-
-  // The index of descriptors to class definitions.
-  typedef std::map<const StringPiece, const RawDexFile::ClassDef*> Index;
-  Index index_;
-
-  // The base address of the memory mapping.
-  const byte* base_;
-
-  // The size of the underlying memory allocation in bytes.
-  size_t length_;
-
-  // Helper object to free the underlying allocation.
-  scoped_ptr<Closer> closer_;
-
-  // Points to the header section.
-  const Header* header_;
-
-  // Points to the base of the string identifier list.
-  const StringId* string_ids_;
-
-  // Points to the base of the type identifier list.
-  const TypeId* type_ids_;
-
-  // Points to the base of the field identifier list.
-  const FieldId* field_ids_;
-
-  // Points to the base of the method identifier list.
-  const MethodId* method_ids_;
-
-  // Points to the base of the prototype identifier list.
-  const ProtoId* proto_ids_;
-
-  // Points to the base of the class definition list.
-  const ClassDef* class_defs_;
-};
-
-}  // namespace art
-
-#endif  // ART_SRC_RAW_DEX_FILE_H_
diff --git a/src/raw_dex_file_test.cc b/src/raw_dex_file_test.cc
deleted file mode 100644
index 4be9991..0000000
--- a/src/raw_dex_file_test.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-
-#include "common_test.h"
-#include "dex_file.h"
-#include "raw_dex_file.h"
-#include "scoped_ptr.h"
-
-#include <stdio.h>
-#include "gtest/gtest.h"
-
-namespace art {
-
-TEST(RawDexFileTest, Open) {
-  scoped_ptr<RawDexFile> raw(OpenRawDexFileBase64(kNestedDex));
-  ASSERT_TRUE(raw != NULL);
-}
-
-TEST(RawDexFileTest, Header) {
-  scoped_ptr<RawDexFile> raw(OpenRawDexFileBase64(kNestedDex));
-  ASSERT_TRUE(raw != NULL);
-
-  const RawDexFile::Header& header = raw->GetHeader();
-  // TODO: header.magic_
-  EXPECT_EQ(0x00d87910U, header.checksum_);
-  // TODO: header.signature_
-  EXPECT_EQ(904U, header.file_size_);
-  EXPECT_EQ(112U, header.header_size_);
-  EXPECT_EQ(0U, header.link_size_);
-  EXPECT_EQ(0U, header.link_off_);
-  EXPECT_EQ(15U, header.string_ids_size_);
-  EXPECT_EQ(112U, header.string_ids_off_);
-  EXPECT_EQ(7U, header.type_ids_size_);
-  EXPECT_EQ(172U, header.type_ids_off_);
-  EXPECT_EQ(2U, header.proto_ids_size_);
-  EXPECT_EQ(200U, header.proto_ids_off_);
-  EXPECT_EQ(1U, header.field_ids_size_);
-  EXPECT_EQ(224U, header.field_ids_off_);
-  EXPECT_EQ(3U, header.method_ids_size_);
-  EXPECT_EQ(232U, header.method_ids_off_);
-  EXPECT_EQ(2U, header.class_defs_size_);
-  EXPECT_EQ(256U, header.class_defs_off_);
-  EXPECT_EQ(584U, header.data_size_);
-  EXPECT_EQ(320U, header.data_off_);
-}
-
-TEST(RawDexFileTest, ClassDefs) {
-  scoped_ptr<RawDexFile> raw(OpenRawDexFileBase64(kNestedDex));
-  ASSERT_TRUE(raw != NULL);
-  EXPECT_EQ(2U, raw->NumClassDefs());
-
-  const RawDexFile::ClassDef& c0 = raw->GetClassDef(0);
-  EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c0));
-
-  const RawDexFile::ClassDef& c1 = raw->GetClassDef(1);
-  EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
-}
-
-}  // namespace art
diff --git a/src/runtime.h b/src/runtime.h
index 69f6228..f697b4a 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -7,7 +7,7 @@
 
 #include "globals.h"
 #include "macros.h"
-#include "raw_dex_file.h"
+#include "dex_file.h"
 #include "stringpiece.h"
 
 namespace art {