diff --git a/dexlayout/Android.mk b/dexlayout/Android.mk
index 3095866..de02580 100755
--- a/dexlayout/Android.mk
+++ b/dexlayout/Android.mk
@@ -16,7 +16,7 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-dexlayout_src_files := dexlayout_main.cc dexlayout.cc dex_ir.cc
+dexlayout_src_files := dexlayout_main.cc dexlayout.cc dex_ir_builder.cc
 dexlayout_c_includes := art/runtime
 dexlayout_libraries := libart
 
diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc
deleted file mode 100644
index 0ed040e..0000000
--- a/dexlayout/dex_ir.cc
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- *
- * Implementation file of the dex file intermediate representation.
- *
- * Utilities for reading dex files into an internal representation,
- * manipulating them, and writing them out.
- */
-
-#include "dex_ir.h"
-
-#include <map>
-#include <vector>
-
-#include "dex_file.h"
-#include "dex_file-inl.h"
-#include "utils.h"
-
-namespace art {
-namespace dex_ir {
-
-namespace {
-static uint64_t ReadVarWidth(const uint8_t** data, uint8_t length, bool sign_extend) {
-  uint64_t value = 0;
-  for (uint32_t i = 0; i <= length; i++) {
-    value |= static_cast<uint64_t>(*(*data)++) << (i * 8);
-  }
-  if (sign_extend) {
-    int shift = (7 - length) * 8;
-    return (static_cast<int64_t>(value) << shift) >> shift;
-  }
-  return value;
-}
-
-static bool GetPositionsCb(void* context, const DexFile::PositionInfo& entry) {
-  DebugInfoItem* debug_info = reinterpret_cast<DebugInfoItem*>(context);
-  std::vector<std::unique_ptr<PositionInfo>>& positions = debug_info->GetPositionInfo();
-  positions.push_back(std::unique_ptr<PositionInfo>(new PositionInfo(entry.address_, entry.line_)));
-  return false;
-}
-
-static void GetLocalsCb(void* context, const DexFile::LocalInfo& entry) {
-  DebugInfoItem* debug_info = reinterpret_cast<DebugInfoItem*>(context);
-  std::vector<std::unique_ptr<LocalInfo>>& locals = debug_info->GetLocalInfo();
-  const char* name = entry.name_ != nullptr ? entry.name_ : "(null)";
-  const char* signature = entry.signature_ != nullptr ? entry.signature_ : "";
-  locals.push_back(std::unique_ptr<LocalInfo>(
-      new LocalInfo(name, entry.descriptor_, signature, entry.start_address_,
-                    entry.end_address_, entry.reg_)));
-}
-}  // namespace
-
-Header::Header(const DexFile& dex_file) : dex_file_(dex_file) {
-  const DexFile::Header& disk_header = dex_file.GetHeader();
-  memcpy(magic_, disk_header.magic_, sizeof(magic_));
-  checksum_ = disk_header.checksum_;
-  // TODO(sehr): clearly the signature will need to be recomputed before dumping.
-  memcpy(signature_, disk_header.signature_, sizeof(signature_));
-  endian_tag_ = disk_header.endian_tag_;
-  file_size_ = disk_header.file_size_;
-  header_size_ = disk_header.header_size_;
-  link_size_ = disk_header.link_size_;
-  link_offset_ = disk_header.link_off_;
-  data_size_ = disk_header.data_size_;
-  data_offset_ = disk_header.data_off_;
-  // Walk the rest of the header fields.
-  string_ids_.SetOffset(disk_header.string_ids_off_);
-  for (uint32_t i = 0; i < dex_file_.NumStringIds(); ++i) {
-    string_ids_.AddWithPosition(i, new StringId(dex_file_.GetStringId(i), *this));
-  }
-  type_ids_.SetOffset(disk_header.type_ids_off_);
-  for (uint32_t i = 0; i < dex_file_.NumTypeIds(); ++i) {
-    type_ids_.AddWithPosition(i, new TypeId(dex_file_.GetTypeId(i), *this));
-  }
-  proto_ids_.SetOffset(disk_header.proto_ids_off_);
-  for (uint32_t i = 0; i < dex_file_.NumProtoIds(); ++i) {
-    proto_ids_.AddWithPosition(i, new ProtoId(dex_file_.GetProtoId(i), *this));
-  }
-  field_ids_.SetOffset(disk_header.field_ids_off_);
-  for (uint32_t i = 0; i < dex_file_.NumFieldIds(); ++i) {
-    field_ids_.AddWithPosition(i, new FieldId(dex_file_.GetFieldId(i), *this));
-  }
-  method_ids_.SetOffset(disk_header.method_ids_off_);
-  for (uint32_t i = 0; i < dex_file_.NumMethodIds(); ++i) {
-    method_ids_.AddWithPosition(i, new MethodId(dex_file_.GetMethodId(i), *this));
-  }
-  class_defs_.SetOffset(disk_header.class_defs_off_);
-  for (uint32_t i = 0; i < dex_file_.NumClassDefs(); ++i) {
-    class_defs_.AddWithPosition(i, new ClassDef(dex_file_.GetClassDef(i), *this));
-  }
-}
-
-ArrayItem::ArrayItem(Header& header, const uint8_t** data, uint8_t type, uint8_t length) {
-  Read(header, data, type, length);
-}
-
-ArrayItem::ArrayItem(Header& header, const uint8_t** data) {
-  const uint8_t encoded_value = *(*data)++;
-  Read(header, data, encoded_value & 0x1f, encoded_value >> 5);
-}
-
-void ArrayItem::Read(Header& header, const uint8_t** data, uint8_t type, uint8_t length) {
-  type_ = type;
-  switch (type_) {
-    case DexFile::kDexAnnotationByte:
-      item_.byte_val_ = static_cast<int8_t>(ReadVarWidth(data, length, false));
-      break;
-    case DexFile::kDexAnnotationShort:
-      item_.short_val_ = static_cast<int16_t>(ReadVarWidth(data, length, true));
-      break;
-    case DexFile::kDexAnnotationChar:
-      item_.char_val_ = static_cast<uint16_t>(ReadVarWidth(data, length, false));
-      break;
-    case DexFile::kDexAnnotationInt:
-      item_.int_val_ = static_cast<int32_t>(ReadVarWidth(data, length, true));
-      break;
-    case DexFile::kDexAnnotationLong:
-      item_.long_val_ = static_cast<int64_t>(ReadVarWidth(data, length, true));
-      break;
-    case DexFile::kDexAnnotationFloat: {
-      // Fill on right.
-      union {
-        float f;
-        uint32_t data;
-      } conv;
-      conv.data = static_cast<uint32_t>(ReadVarWidth(data, length, false)) << (3 - length) * 8;
-      item_.float_val_ = conv.f;
-      break;
-    }
-    case DexFile::kDexAnnotationDouble: {
-      // Fill on right.
-      union {
-        double d;
-        uint64_t data;
-      } conv;
-      conv.data = ReadVarWidth(data, length, false) << (7 - length) * 8;
-      item_.double_val_ = conv.d;
-      break;
-    }
-    case DexFile::kDexAnnotationString: {
-      const uint32_t string_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
-      item_.string_val_ = header.StringIds()[string_index].get();
-      break;
-    }
-    case DexFile::kDexAnnotationType: {
-      const uint32_t string_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
-      item_.string_val_ = header.TypeIds()[string_index]->GetStringId();
-      break;
-    }
-    case DexFile::kDexAnnotationField:
-    case DexFile::kDexAnnotationEnum: {
-      const uint32_t field_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
-      item_.field_val_ = header.FieldIds()[field_index].get();
-      break;
-    }
-    case DexFile::kDexAnnotationMethod: {
-      const uint32_t method_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
-      item_.method_val_ = header.MethodIds()[method_index].get();
-      break;
-    }
-    case DexFile::kDexAnnotationArray: {
-      item_.annotation_array_val_ = new std::vector<std::unique_ptr<ArrayItem>>();
-      // Decode all elements.
-      const uint32_t size = DecodeUnsignedLeb128(data);
-      for (uint32_t i = 0; i < size; i++) {
-        item_.annotation_array_val_->push_back(
-            std::unique_ptr<ArrayItem>(new ArrayItem(header, data)));
-      }
-      break;
-    }
-    case DexFile::kDexAnnotationAnnotation: {
-      const uint32_t type_idx = DecodeUnsignedLeb128(data);
-      item_.annotation_annotation_val_.string_ = header.TypeIds()[type_idx]->GetStringId();
-      item_.annotation_annotation_val_.array_ = new std::vector<std::unique_ptr<NameValuePair>>();
-      // Decode all name=value pairs.
-      const uint32_t size = DecodeUnsignedLeb128(data);
-      for (uint32_t i = 0; i < size; i++) {
-        const uint32_t name_index = DecodeUnsignedLeb128(data);
-        item_.annotation_annotation_val_.array_->push_back(std::unique_ptr<NameValuePair>(
-            new NameValuePair(header.StringIds()[name_index].get(), new ArrayItem(header, data))));
-      }
-      break;
-    }
-    case DexFile::kDexAnnotationNull:
-      break;
-    case DexFile::kDexAnnotationBoolean:
-      item_.bool_val_ = (length != 0);
-      break;
-    default:
-      break;
-  }
-}
-
-ClassDef::ClassDef(const DexFile::ClassDef& disk_class_def, Header& header) {
-  class_type_ = header.TypeIds()[disk_class_def.class_idx_].get();
-  access_flags_ = disk_class_def.access_flags_;
-  superclass_ = header.GetTypeIdOrNullPtr(disk_class_def.superclass_idx_);
-
-  const DexFile::TypeList* type_list = header.GetDexFile().GetInterfacesList(disk_class_def);
-  interfaces_offset_ = disk_class_def.interfaces_off_;
-  if (type_list != nullptr) {
-    for (uint32_t index = 0; index < type_list->Size(); ++index) {
-      interfaces_.push_back(header.TypeIds()[type_list->GetTypeItem(index).type_idx_].get());
-    }
-  }
-  source_file_ = header.GetStringIdOrNullPtr(disk_class_def.source_file_idx_);
-  // Annotations.
-  const DexFile::AnnotationsDirectoryItem* disk_annotations_directory_item =
-      header.GetDexFile().GetAnnotationsDirectory(disk_class_def);
-  if (disk_annotations_directory_item == nullptr) {
-    annotations_.reset(nullptr);
-  } else {
-    annotations_.reset(new AnnotationsDirectoryItem(disk_annotations_directory_item, header));
-    annotations_->SetOffset(disk_class_def.annotations_off_);
-  }
-  // Static field initializers.
-  static_values_ = nullptr;
-  const uint8_t* static_data = header.GetDexFile().GetEncodedStaticFieldValuesArray(disk_class_def);
-  if (static_data != nullptr) {
-    uint32_t static_value_count = static_data == nullptr ? 0 : DecodeUnsignedLeb128(&static_data);
-    if (static_value_count > 0) {
-      static_values_ = new std::vector<std::unique_ptr<ArrayItem>>();
-      for (uint32_t i = 0; i < static_value_count; ++i) {
-        static_values_->push_back(std::unique_ptr<ArrayItem>(new ArrayItem(header, &static_data)));
-      }
-    }
-  }
-  // Read the fields and methods defined by the class, resolving the circular reference from those
-  // to classes by setting class at the same time.
-  const uint8_t* encoded_data = header.GetDexFile().GetClassData(disk_class_def);
-  class_data_.SetOffset(disk_class_def.class_data_off_);
-  if (encoded_data != nullptr) {
-    ClassDataItemIterator cdii(header.GetDexFile(), encoded_data);
-    // Static fields.
-    for (uint32_t i = 0; cdii.HasNextStaticField(); i++, cdii.Next()) {
-      FieldId* field_item = header.FieldIds()[cdii.GetMemberIndex()].get();
-      uint32_t access_flags = cdii.GetRawMemberAccessFlags();
-      class_data_.StaticFields().push_back(
-          std::unique_ptr<FieldItem>(new FieldItem(access_flags, field_item)));
-    }
-    // Instance fields.
-    for (uint32_t i = 0; cdii.HasNextInstanceField(); i++, cdii.Next()) {
-      FieldId* field_item = header.FieldIds()[cdii.GetMemberIndex()].get();
-      uint32_t access_flags = cdii.GetRawMemberAccessFlags();
-      class_data_.InstanceFields().push_back(
-          std::unique_ptr<FieldItem>(new FieldItem(access_flags, field_item)));
-    }
-    // Direct methods.
-    for (uint32_t i = 0; cdii.HasNextDirectMethod(); i++, cdii.Next()) {
-      class_data_.DirectMethods().push_back(
-          std::unique_ptr<MethodItem>(GenerateMethodItem(header, cdii)));
-    }
-    // Virtual methods.
-    for (uint32_t i = 0; cdii.HasNextVirtualMethod(); i++, cdii.Next()) {
-      class_data_.VirtualMethods().push_back(
-          std::unique_ptr<MethodItem>(GenerateMethodItem(header, cdii)));
-    }
-  }
-}
-
-MethodItem* ClassDef::GenerateMethodItem(Header& header, ClassDataItemIterator& cdii) {
-  MethodId* method_item = header.MethodIds()[cdii.GetMemberIndex()].get();
-  uint32_t access_flags = cdii.GetRawMemberAccessFlags();
-  const DexFile::CodeItem* disk_code_item = cdii.GetMethodCodeItem();
-  CodeItem* code_item = nullptr;
-  DebugInfoItem* debug_info = nullptr;
-  if (disk_code_item != nullptr) {
-    code_item = new CodeItem(*disk_code_item, header);
-    code_item->SetOffset(cdii.GetMethodCodeItemOffset());
-    debug_info = code_item->DebugInfo();
-  }
-  if (debug_info != nullptr) {
-    bool is_static = (access_flags & kAccStatic) != 0;
-    header.GetDexFile().DecodeDebugLocalInfo(
-        disk_code_item, is_static, cdii.GetMemberIndex(), GetLocalsCb, debug_info);
-    header.GetDexFile().DecodeDebugPositionInfo(disk_code_item, GetPositionsCb, debug_info);
-  }
-  return new MethodItem(access_flags, method_item, code_item);
-}
-
-CodeItem::CodeItem(const DexFile::CodeItem& disk_code_item, Header& header) {
-  registers_size_ = disk_code_item.registers_size_;
-  ins_size_ = disk_code_item.ins_size_;
-  outs_size_ = disk_code_item.outs_size_;
-  tries_size_ = disk_code_item.tries_size_;
-
-  const uint8_t* debug_info_stream = header.GetDexFile().GetDebugInfoStream(&disk_code_item);
-  if (debug_info_stream != nullptr) {
-    debug_info_.reset(new DebugInfoItem());
-  } else {
-    debug_info_.reset(nullptr);
-  }
-
-  insns_size_ = disk_code_item.insns_size_in_code_units_;
-  insns_.reset(new uint16_t[insns_size_]);
-  memcpy(insns_.get(), disk_code_item.insns_, insns_size_ * sizeof(uint16_t));
-
-  if (tries_size_ > 0) {
-    tries_ = new std::vector<std::unique_ptr<const TryItem>>();
-    for (uint32_t i = 0; i < tries_size_; ++i) {
-      const DexFile::TryItem* disk_try_item = header.GetDexFile().GetTryItems(disk_code_item, i);
-      tries_->push_back(std::unique_ptr<const TryItem>(
-          new TryItem(*disk_try_item, disk_code_item, header)));
-    }
-  } else {
-    tries_ = nullptr;
-  }
-}
-
-AnnotationSetItem::AnnotationSetItem(const DexFile::AnnotationSetItem& disk_annotations_item,
-                                     Header& header) {
-  if (disk_annotations_item.size_ == 0) {
-    return;
-  }
-  for (uint32_t i = 0; i < disk_annotations_item.size_; ++i) {
-    const DexFile::AnnotationItem* annotation =
-        header.GetDexFile().GetAnnotationItem(&disk_annotations_item, i);
-    if (annotation == nullptr) {
-      continue;
-    }
-    uint8_t visibility = annotation->visibility_;
-    const uint8_t* annotation_data = annotation->annotation_;
-    ArrayItem* array_item =
-        new ArrayItem(header, &annotation_data, DexFile::kDexAnnotationAnnotation, 0);
-    items_.push_back(std::unique_ptr<AnnotationItem>(new AnnotationItem(visibility, array_item)));
-  }
-}
-
-AnnotationsDirectoryItem::AnnotationsDirectoryItem(
-    const DexFile::AnnotationsDirectoryItem* disk_annotations_item, Header& header) {
-  const DexFile::AnnotationSetItem* class_set_item =
-      header.GetDexFile().GetClassAnnotationSet(disk_annotations_item);
-  if (class_set_item == nullptr) {
-    class_annotation_.reset(nullptr);
-  } else {
-    class_annotation_.reset(new AnnotationSetItem(*class_set_item, header));
-  }
-  const DexFile::FieldAnnotationsItem* fields =
-      header.GetDexFile().GetFieldAnnotations(disk_annotations_item);
-  if (fields != nullptr) {
-    for (uint32_t i = 0; i < disk_annotations_item->fields_size_; ++i) {
-      FieldId* field_id = header.FieldIds()[fields[i].field_idx_].get();
-      const DexFile::AnnotationSetItem* field_set_item =
-          header.GetDexFile().GetFieldAnnotationSetItem(fields[i]);
-      dex_ir::AnnotationSetItem* annotation_set_item =
-          new AnnotationSetItem(*field_set_item, header);
-      field_annotations_.push_back(std::unique_ptr<FieldAnnotation>(
-          new FieldAnnotation(field_id, annotation_set_item)));
-    }
-  }
-  const DexFile::MethodAnnotationsItem* methods =
-      header.GetDexFile().GetMethodAnnotations(disk_annotations_item);
-  if (methods != nullptr) {
-    for (uint32_t i = 0; i < disk_annotations_item->methods_size_; ++i) {
-      MethodId* method_id = header.MethodIds()[methods[i].method_idx_].get();
-      const DexFile::AnnotationSetItem* method_set_item =
-          header.GetDexFile().GetMethodAnnotationSetItem(methods[i]);
-      dex_ir::AnnotationSetItem* annotation_set_item =
-          new AnnotationSetItem(*method_set_item, header);
-      method_annotations_.push_back(std::unique_ptr<MethodAnnotation>(
-          new MethodAnnotation(method_id, annotation_set_item)));
-    }
-  }
-  const DexFile::ParameterAnnotationsItem* parameters =
-      header.GetDexFile().GetParameterAnnotations(disk_annotations_item);
-  if (parameters != nullptr) {
-    for (uint32_t i = 0; i < disk_annotations_item->parameters_size_; ++i) {
-      MethodId* method_id = header.MethodIds()[parameters[i].method_idx_].get();
-      const DexFile::AnnotationSetRefList* list =
-          header.GetDexFile().GetParameterAnnotationSetRefList(&parameters[i]);
-      parameter_annotations_.push_back(std::unique_ptr<ParameterAnnotation>(
-          new ParameterAnnotation(method_id, list, header)));
-    }
-  }
-}
-
-}  // namespace dex_ir
-}  // namespace art
diff --git a/dexlayout/dex_ir.h b/dexlayout/dex_ir.h
index fcd3ab0..514d6fd 100644
--- a/dexlayout/dex_ir.h
+++ b/dexlayout/dex_ir.h
@@ -19,12 +19,10 @@
 #ifndef ART_DEXLAYOUT_DEX_IR_H_
 #define ART_DEXLAYOUT_DEX_IR_H_
 
-#include <iostream>
-#include <map>
 #include <vector>
 #include <stdint.h>
 
-#include "dex_file.h"
+#include "dex_file-inl.h"
 
 namespace art {
 namespace dex_ir {
@@ -106,19 +104,39 @@
 class Item {
  public:
   virtual ~Item() { }
+
   uint32_t GetOffset() const { return offset_; }
   void SetOffset(uint32_t offset) { offset_ = offset; }
+
  protected:
   uint32_t offset_ = 0;
 };
 
 class Header : public Item {
  public:
-  explicit Header(const DexFile& dex_file);
+  Header(const uint8_t* magic,
+         uint32_t checksum,
+         const uint8_t* signature,
+         uint32_t endian_tag,
+         uint32_t file_size,
+         uint32_t header_size,
+         uint32_t link_size,
+         uint32_t link_offset,
+         uint32_t data_size,
+         uint32_t data_offset)
+      : checksum_(checksum),
+        endian_tag_(endian_tag),
+        file_size_(file_size),
+        header_size_(header_size),
+        link_size_(link_size),
+        link_offset_(link_offset),
+        data_size_(data_size),
+        data_offset_(data_offset) {
+    memcpy(magic_, magic, sizeof(magic_));
+    memcpy(signature_, signature, sizeof(signature_));
+  }
   ~Header() OVERRIDE { }
 
-  const DexFile& GetDexFile() const { return dex_file_; }
-
   const uint8_t* Magic() const { return magic_; }
   uint32_t Checksum() const { return checksum_; }
   const uint8_t* Signature() const { return signature_; }
@@ -178,7 +196,6 @@
   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
 
  private:
-  const DexFile& dex_file_;
   uint8_t magic_[8];
   uint32_t checksum_;
   uint8_t signature_[DexFile::kSha1DigestSize];
@@ -201,9 +218,7 @@
 
 class StringId : public Item {
  public:
-  StringId(const DexFile::StringId& disk_string_id, Header& header) :
-    data_(strdup(header.GetDexFile().GetStringData(disk_string_id))) {
-  }
+  explicit StringId(const char* data) : data_(strdup(data)) { }
   ~StringId() OVERRIDE { }
 
   const char* Data() const { return data_.get(); }
@@ -217,9 +232,7 @@
 
 class TypeId : public Item {
  public:
-  TypeId(const DexFile::TypeId& disk_type_id, Header& header) :
-    string_id_(header.StringIds()[disk_type_id.descriptor_idx_].get()) {
-  }
+  explicit TypeId(StringId* string_id) : string_id_(string_id) { }
   ~TypeId() OVERRIDE { }
 
   StringId* GetStringId() const { return string_id_; }
@@ -231,39 +244,31 @@
   DISALLOW_COPY_AND_ASSIGN(TypeId);
 };
 
+using TypeIdVector = std::vector<const TypeId*>;
+
 class ProtoId : public Item {
  public:
-  ProtoId(const DexFile::ProtoId& disk_proto_id, Header& header) {
-    shorty_ = header.StringIds()[disk_proto_id.shorty_idx_].get();
-    return_type_ = header.TypeIds()[disk_proto_id.return_type_idx_].get();
-    DexFileParameterIterator dfpi(header.GetDexFile(), disk_proto_id);
-    while (dfpi.HasNext()) {
-      parameters_.push_back(header.TypeIds()[dfpi.GetTypeIdx()].get());
-      dfpi.Next();
-    }
-  }
+  ProtoId(const StringId* shorty, const TypeId* return_type, TypeIdVector* parameters)
+      : shorty_(shorty), return_type_(return_type), parameters_(parameters) { }
   ~ProtoId() OVERRIDE { }
 
   const StringId* Shorty() const { return shorty_; }
   const TypeId* ReturnType() const { return return_type_; }
-  const std::vector<const TypeId*>& Parameters() const { return parameters_; }
+  const std::vector<const TypeId*>& Parameters() const { return *parameters_; }
 
   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
 
  private:
   const StringId* shorty_;
   const TypeId* return_type_;
-  std::vector<const TypeId*> parameters_;
+  std::unique_ptr<TypeIdVector> parameters_;
   DISALLOW_COPY_AND_ASSIGN(ProtoId);
 };
 
 class FieldId : public Item {
  public:
-  FieldId(const DexFile::FieldId& disk_field_id, Header& header) {
-    class_ = header.TypeIds()[disk_field_id.class_idx_].get();
-    type_ = header.TypeIds()[disk_field_id.type_idx_].get();
-    name_ = header.StringIds()[disk_field_id.name_idx_].get();
-  }
+  FieldId(const TypeId* klass, const TypeId* type, const StringId* name)
+      : class_(klass), type_(type), name_(name) { }
   ~FieldId() OVERRIDE { }
 
   const TypeId* Class() const { return class_; }
@@ -281,11 +286,8 @@
 
 class MethodId : public Item {
  public:
-  MethodId(const DexFile::MethodId& disk_method_id, Header& header) {
-    class_ = header.TypeIds()[disk_method_id.class_idx_].get();
-    proto_ = header.ProtoIds()[disk_method_id.proto_idx_].get();
-    name_ = header.StringIds()[disk_method_id.name_idx_].get();
-  }
+  MethodId(const TypeId* klass, const ProtoId* proto, const StringId* name)
+      : class_(klass), proto_(proto), name_(name) { }
   ~MethodId() OVERRIDE { }
 
   const TypeId* Class() const { return class_; }
@@ -303,8 +305,8 @@
 
 class FieldItem : public Item {
  public:
-  FieldItem(uint32_t access_flags, const FieldId* field_id) :
-    access_flags_(access_flags), field_id_(field_id) { }
+  FieldItem(uint32_t access_flags, const FieldId* field_id)
+      : access_flags_(access_flags), field_id_(field_id) { }
   ~FieldItem() OVERRIDE { }
 
   uint32_t GetAccessFlags() const { return access_flags_; }
@@ -318,10 +320,12 @@
   DISALLOW_COPY_AND_ASSIGN(FieldItem);
 };
 
+using FieldItemVector = std::vector<std::unique_ptr<FieldItem>>;
+
 class MethodItem : public Item {
  public:
-  MethodItem(uint32_t access_flags, const MethodId* method_id, const CodeItem* code) :
-    access_flags_(access_flags), method_id_(method_id), code_(code) { }
+  MethodItem(uint32_t access_flags, const MethodId* method_id, const CodeItem* code)
+      : access_flags_(access_flags), method_id_(method_id), code_(code) { }
   ~MethodItem() OVERRIDE { }
 
   uint32_t GetAccessFlags() const { return access_flags_; }
@@ -337,12 +341,14 @@
   DISALLOW_COPY_AND_ASSIGN(MethodItem);
 };
 
+using MethodItemVector = std::vector<std::unique_ptr<MethodItem>>;
+
 class ArrayItem : public Item {
  public:
   class NameValuePair {
    public:
-    NameValuePair(StringId* name, ArrayItem* value) :
-      name_(name), value_(value) { }
+    NameValuePair(StringId* name, ArrayItem* value)
+        : name_(name), value_(value) { }
 
     StringId* Name() const { return name_; }
     ArrayItem* Value() const { return value_.get(); }
@@ -353,8 +359,26 @@
     DISALLOW_COPY_AND_ASSIGN(NameValuePair);
   };
 
-  ArrayItem(Header& header, const uint8_t** data, uint8_t type, uint8_t length);
-  ArrayItem(Header& header, const uint8_t** data);
+  union PayloadUnion {
+    bool bool_val_;
+    int8_t byte_val_;
+    int16_t short_val_;
+    uint16_t char_val_;
+    int32_t int_val_;
+    int64_t long_val_;
+    float float_val_;
+    double double_val_;
+    StringId* string_val_;
+    FieldId* field_val_;
+    MethodId* method_val_;
+    std::vector<std::unique_ptr<ArrayItem>>* annotation_array_val_;
+    struct {
+      StringId* string_;
+      std::vector<std::unique_ptr<NameValuePair>>* array_;
+    } annotation_annotation_val_;
+  };
+
+  explicit ArrayItem(uint8_t type) : type_(type) { }
   ~ArrayItem() OVERRIDE { }
 
   int8_t Type() const { return type_; }
@@ -378,67 +402,79 @@
   std::vector<std::unique_ptr<NameValuePair>>* GetAnnotationAnnotationNameValuePairArray() const {
     return item_.annotation_annotation_val_.array_;
   }
+  // Used to construct the item union.  Ugly, but necessary.
+  PayloadUnion* GetPayloadUnion() { return &item_; }
 
   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
 
  private:
-  void Read(Header& header, const uint8_t** data, uint8_t type, uint8_t length);
   uint8_t type_;
-  union {
-    bool bool_val_;
-    int8_t byte_val_;
-    int16_t short_val_;
-    uint16_t char_val_;
-    int32_t int_val_;
-    int64_t long_val_;
-    float float_val_;
-    double double_val_;
-    StringId* string_val_;
-    FieldId* field_val_;
-    MethodId* method_val_;
-    std::vector<std::unique_ptr<ArrayItem>>* annotation_array_val_;
-    struct {
-      StringId* string_;
-      std::vector<std::unique_ptr<NameValuePair>>* array_;
-    } annotation_annotation_val_;
-  } item_;
+  PayloadUnion item_;
   DISALLOW_COPY_AND_ASSIGN(ArrayItem);
 };
 
+using ArrayItemVector = std::vector<std::unique_ptr<ArrayItem>>;
+
 class ClassData : public Item {
  public:
-  ClassData() = default;
+  ClassData(FieldItemVector* static_fields,
+            FieldItemVector* instance_fields,
+            MethodItemVector* direct_methods,
+            MethodItemVector* virtual_methods)
+      : static_fields_(static_fields),
+        instance_fields_(instance_fields),
+        direct_methods_(direct_methods),
+        virtual_methods_(virtual_methods) { }
+
   ~ClassData() OVERRIDE = default;
-  std::vector<std::unique_ptr<FieldItem>>& StaticFields() { return static_fields_; }
-  std::vector<std::unique_ptr<FieldItem>>& InstanceFields() { return instance_fields_; }
-  std::vector<std::unique_ptr<MethodItem>>& DirectMethods() { return direct_methods_; }
-  std::vector<std::unique_ptr<MethodItem>>& VirtualMethods() { return virtual_methods_; }
+  FieldItemVector* StaticFields() { return static_fields_.get(); }
+  FieldItemVector* InstanceFields() { return instance_fields_.get(); }
+  MethodItemVector* DirectMethods() { return direct_methods_.get(); }
+  MethodItemVector* VirtualMethods() { return virtual_methods_.get(); }
 
   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
 
  private:
-  std::vector<std::unique_ptr<FieldItem>> static_fields_;
-  std::vector<std::unique_ptr<FieldItem>> instance_fields_;
-  std::vector<std::unique_ptr<MethodItem>> direct_methods_;
-  std::vector<std::unique_ptr<MethodItem>> virtual_methods_;
+  std::unique_ptr<FieldItemVector> static_fields_;
+  std::unique_ptr<FieldItemVector> instance_fields_;
+  std::unique_ptr<MethodItemVector> direct_methods_;
+  std::unique_ptr<MethodItemVector> virtual_methods_;
   DISALLOW_COPY_AND_ASSIGN(ClassData);
 };
 
 class ClassDef : public Item {
  public:
-  ClassDef(const DexFile::ClassDef& disk_class_def, Header& header);
+  ClassDef(const TypeId* class_type,
+           uint32_t access_flags,
+           const TypeId* superclass,
+           TypeIdVector* interfaces,
+           uint32_t interfaces_offset,
+           const StringId* source_file,
+           AnnotationsDirectoryItem* annotations,
+           ArrayItemVector* static_values,
+           ClassData* class_data)
+      : class_type_(class_type),
+        access_flags_(access_flags),
+        superclass_(superclass),
+        interfaces_(interfaces),
+        interfaces_offset_(interfaces_offset),
+        source_file_(source_file),
+        annotations_(annotations),
+        static_values_(static_values),
+        class_data_(class_data) { }
+
   ~ClassDef() OVERRIDE { }
 
   const TypeId* ClassType() const { return class_type_; }
   uint32_t GetAccessFlags() const { return access_flags_; }
   const TypeId* Superclass() const { return superclass_; }
-  std::vector<TypeId*>* Interfaces() { return &interfaces_; }
+  TypeIdVector* Interfaces() { return interfaces_.get(); }
   uint32_t InterfacesOffset() const { return interfaces_offset_; }
   void SetInterfacesOffset(uint32_t new_offset) { interfaces_offset_ = new_offset; }
   const StringId* SourceFile() const { return source_file_; }
   AnnotationsDirectoryItem* Annotations() const { return annotations_.get(); }
-  std::vector<std::unique_ptr<ArrayItem>>* StaticValues() { return static_values_; }
-  ClassData* GetClassData() { return &class_data_; }
+  ArrayItemVector* StaticValues() { return static_values_.get(); }
+  ClassData* GetClassData() { return class_data_.get(); }
 
   MethodItem* GenerateMethodItem(Header& header, ClassDataItemIterator& cdii);
 
@@ -448,28 +484,78 @@
   const TypeId* class_type_;
   uint32_t access_flags_;
   const TypeId* superclass_;
-  std::vector<TypeId*> interfaces_;
+  std::unique_ptr<TypeIdVector> interfaces_;
   uint32_t interfaces_offset_;
   const StringId* source_file_;
   std::unique_ptr<AnnotationsDirectoryItem> annotations_;
-  std::vector<std::unique_ptr<ArrayItem>>* static_values_;
-  ClassData class_data_;
+  std::unique_ptr<ArrayItemVector> static_values_;
+  std::unique_ptr<ClassData> class_data_;
   DISALLOW_COPY_AND_ASSIGN(ClassDef);
 };
 
+class CatchHandler {
+ public:
+  CatchHandler(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
+
+  const TypeId* GetTypeId() const { return type_id_; }
+  uint32_t GetAddress() const { return address_; }
+
+ private:
+  const TypeId* type_id_;
+  uint32_t address_;
+  DISALLOW_COPY_AND_ASSIGN(CatchHandler);
+};
+
+using CatchHandlerVector = std::vector<std::unique_ptr<const CatchHandler>>;
+
+class TryItem : public Item {
+ public:
+  TryItem(uint32_t start_addr, uint16_t insn_count, CatchHandlerVector* handlers)
+      : start_addr_(start_addr), insn_count_(insn_count), handlers_(handlers) { }
+  ~TryItem() OVERRIDE { }
+
+  uint32_t StartAddr() const { return start_addr_; }
+  uint16_t InsnCount() const { return insn_count_; }
+  const CatchHandlerVector& GetHandlers() const { return *handlers_.get(); }
+
+  void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
+
+ private:
+  uint32_t start_addr_;
+  uint16_t insn_count_;
+  std::unique_ptr<CatchHandlerVector> handlers_;
+  DISALLOW_COPY_AND_ASSIGN(TryItem);
+};
+
+using TryItemVector = std::vector<std::unique_ptr<const TryItem>>;
+
 class CodeItem : public Item {
  public:
-  CodeItem(const DexFile::CodeItem& disk_code_item, Header& header);
+  CodeItem(uint16_t registers_size,
+           uint16_t ins_size,
+           uint16_t outs_size,
+           DebugInfoItem* debug_info,
+           uint32_t insns_size,
+           uint16_t* insns,
+           TryItemVector* tries)
+      : registers_size_(registers_size),
+        ins_size_(ins_size),
+        outs_size_(outs_size),
+        debug_info_(debug_info),
+        insns_size_(insns_size),
+        insns_(insns),
+        tries_(tries) { }
+
   ~CodeItem() OVERRIDE { }
 
   uint16_t RegistersSize() const { return registers_size_; }
   uint16_t InsSize() const { return ins_size_; }
   uint16_t OutsSize() const { return outs_size_; }
-  uint16_t TriesSize() const { return tries_size_; }
+  uint16_t TriesSize() const { return tries_ == nullptr ? 0 : tries_->size(); }
   DebugInfoItem* DebugInfo() const { return debug_info_.get(); }
   uint32_t InsnsSize() const { return insns_size_; }
   uint16_t* Insns() const { return insns_.get(); }
-  std::vector<std::unique_ptr<const TryItem>>* Tries() const { return tries_; }
+  TryItemVector* Tries() const { return tries_.get(); }
 
   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
 
@@ -477,56 +563,13 @@
   uint16_t registers_size_;
   uint16_t ins_size_;
   uint16_t outs_size_;
-  uint16_t tries_size_;
   std::unique_ptr<DebugInfoItem> debug_info_;
   uint32_t insns_size_;
   std::unique_ptr<uint16_t[]> insns_;
-  std::vector<std::unique_ptr<const TryItem>>* tries_;
+  std::unique_ptr<TryItemVector> tries_;
   DISALLOW_COPY_AND_ASSIGN(CodeItem);
 };
 
-class TryItem : public Item {
- public:
-  class CatchHandler {
-   public:
-    CatchHandler(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
-
-    const TypeId* GetTypeId() const { return type_id_; }
-    uint32_t GetAddress() const { return address_; }
-
-   private:
-    const TypeId* type_id_;
-    uint32_t address_;
-    DISALLOW_COPY_AND_ASSIGN(CatchHandler);
-  };
-
-  TryItem(const DexFile::TryItem& disk_try_item,
-          const DexFile::CodeItem& disk_code_item,
-          Header& header) {
-    start_addr_ = disk_try_item.start_addr_;
-    insn_count_ = disk_try_item.insn_count_;
-    for (CatchHandlerIterator it(disk_code_item, disk_try_item); it.HasNext(); it.Next()) {
-      const uint16_t type_index = it.GetHandlerTypeIndex();
-      const TypeId* type_id = header.GetTypeIdOrNullPtr(type_index);
-      handlers_.push_back(std::unique_ptr<const CatchHandler>(
-          new CatchHandler(type_id, it.GetHandlerAddress())));
-    }
-  }
-  ~TryItem() OVERRIDE { }
-
-  uint32_t StartAddr() const { return start_addr_; }
-  uint16_t InsnCount() const { return insn_count_; }
-  const std::vector<std::unique_ptr<const CatchHandler>>& GetHandlers() const { return handlers_; }
-
-  void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
-
- private:
-  uint32_t start_addr_;
-  uint16_t insn_count_;
-  std::vector<std::unique_ptr<const CatchHandler>> handlers_;
-  DISALLOW_COPY_AND_ASSIGN(TryItem);
-};
-
 
 struct PositionInfo {
   PositionInfo(uint32_t address, uint32_t line) : address_(address), line_(line) { }
@@ -535,11 +578,21 @@
   uint32_t line_;
 };
 
+using PositionInfoVector = std::vector<std::unique_ptr<PositionInfo>>;
+
 struct LocalInfo {
-  LocalInfo(const char* name, const char* descriptor, const char* signature, uint32_t start_address,
-            uint32_t end_address, uint16_t reg) :
-    name_(name), descriptor_(descriptor), signature_(signature), start_address_(start_address),
-    end_address_(end_address), reg_(reg) { }
+  LocalInfo(const char* name,
+            const char* descriptor,
+            const char* signature,
+            uint32_t start_address,
+            uint32_t end_address,
+            uint16_t reg)
+      : name_(name),
+        descriptor_(descriptor),
+        signature_(signature),
+        start_address_(start_address),
+        end_address_(end_address),
+        reg_(reg) { }
 
   std::string name_;
   std::string descriptor_;
@@ -549,124 +602,123 @@
   uint16_t reg_;
 };
 
+using LocalInfoVector = std::vector<std::unique_ptr<LocalInfo>>;
+
 class DebugInfoItem : public Item {
  public:
   DebugInfoItem() = default;
 
-  std::vector<std::unique_ptr<PositionInfo>>& GetPositionInfo() { return positions_; }
-  std::vector<std::unique_ptr<LocalInfo>>& GetLocalInfo() { return locals_; }
+  PositionInfoVector& GetPositionInfo() { return positions_; }
+  LocalInfoVector& GetLocalInfo() { return locals_; }
 
  private:
-  std::vector<std::unique_ptr<PositionInfo>> positions_;
-  std::vector<std::unique_ptr<LocalInfo>> locals_;
+  PositionInfoVector positions_;
+  LocalInfoVector locals_;
   DISALLOW_COPY_AND_ASSIGN(DebugInfoItem);
 };
 
+class AnnotationItem {
+ public:
+  AnnotationItem(uint8_t visibility, ArrayItem* item) : visibility_(visibility), item_(item) { }
+
+  uint8_t GetVisibility() const { return visibility_; }
+  ArrayItem* GetItem() const { return item_.get(); }
+
+ private:
+  uint8_t visibility_;
+  std::unique_ptr<ArrayItem> item_;
+  DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
+};
+
+using AnnotationItemVector = std::vector<std::unique_ptr<AnnotationItem>>;
+
 class AnnotationSetItem : public Item {
  public:
-  class AnnotationItem {
-   public:
-    AnnotationItem(uint8_t visibility, ArrayItem* item) :
-      visibility_(visibility), item_(item) { }
-
-    uint8_t GetVisibility() const { return visibility_; }
-    ArrayItem* GetItem() const { return item_.get(); }
-
-   private:
-    uint8_t visibility_;
-    std::unique_ptr<ArrayItem> item_;
-    DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
-  };
-
-  AnnotationSetItem(const DexFile::AnnotationSetItem& disk_annotations_item, Header& header);
+  explicit AnnotationSetItem(AnnotationItemVector* items) : items_(items) { }
   ~AnnotationSetItem() OVERRIDE { }
 
-  std::vector<std::unique_ptr<AnnotationItem>>& GetItems() { return items_; }
+  AnnotationItemVector* GetItems() { return items_.get(); }
 
   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
 
  private:
-  std::vector<std::unique_ptr<AnnotationItem>> items_;
+  std::unique_ptr<AnnotationItemVector> items_;
   DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
 };
 
+using AnnotationSetItemVector = std::vector<std::unique_ptr<AnnotationSetItem>>;
+
+class FieldAnnotation {
+ public:
+  FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item)
+      : field_id_(field_id), annotation_set_item_(annotation_set_item) { }
+
+  FieldId* GetFieldId() const { return field_id_; }
+  AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_.get(); }
+
+ private:
+  FieldId* field_id_;
+  std::unique_ptr<AnnotationSetItem> annotation_set_item_;
+  DISALLOW_COPY_AND_ASSIGN(FieldAnnotation);
+};
+
+using FieldAnnotationVector = std::vector<std::unique_ptr<FieldAnnotation>>;
+
+class MethodAnnotation {
+ public:
+  MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item)
+      : method_id_(method_id), annotation_set_item_(annotation_set_item) { }
+
+  MethodId* GetMethodId() const { return method_id_; }
+  AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_.get(); }
+
+ private:
+  MethodId* method_id_;
+  std::unique_ptr<AnnotationSetItem> annotation_set_item_;
+  DISALLOW_COPY_AND_ASSIGN(MethodAnnotation);
+};
+
+using MethodAnnotationVector = std::vector<std::unique_ptr<MethodAnnotation>>;
+
+class ParameterAnnotation {
+ public:
+  ParameterAnnotation(MethodId* method_id, AnnotationSetItemVector* annotations)
+      : method_id_(method_id), annotations_(annotations) { }
+
+  MethodId* GetMethodId() const { return method_id_; }
+  AnnotationSetItemVector* GetAnnotations() { return annotations_.get(); }
+
+ private:
+  MethodId* method_id_;
+  std::unique_ptr<AnnotationSetItemVector> annotations_;
+  DISALLOW_COPY_AND_ASSIGN(ParameterAnnotation);
+};
+
+using ParameterAnnotationVector = std::vector<std::unique_ptr<ParameterAnnotation>>;
+
 class AnnotationsDirectoryItem : public Item {
  public:
-  class FieldAnnotation {
-   public:
-    FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item) :
-      field_id_(field_id), annotation_set_item_(annotation_set_item) { }
-
-    FieldId* GetFieldId() const { return field_id_; }
-    AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_.get(); }
-
-   private:
-    FieldId* field_id_;
-    std::unique_ptr<AnnotationSetItem> annotation_set_item_;
-    DISALLOW_COPY_AND_ASSIGN(FieldAnnotation);
-  };
-
-  class MethodAnnotation {
-   public:
-    MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item) :
-      method_id_(method_id), annotation_set_item_(annotation_set_item) { }
-
-    MethodId* GetMethodId() const { return method_id_; }
-    AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_.get(); }
-
-   private:
-    MethodId* method_id_;
-    std::unique_ptr<AnnotationSetItem> annotation_set_item_;
-    DISALLOW_COPY_AND_ASSIGN(MethodAnnotation);
-  };
-
-  class ParameterAnnotation {
-   public:
-    ParameterAnnotation(MethodId* method_id,
-                        const DexFile::AnnotationSetRefList* annotation_set_ref_list,
-                        Header& header) :
-      method_id_(method_id) {
-      for (uint32_t i = 0; i < annotation_set_ref_list->size_; ++i) {
-        const DexFile::AnnotationSetItem* annotation_set_item =
-            header.GetDexFile().GetSetRefItemItem(&annotation_set_ref_list->list_[i]);
-        annotations_.push_back(std::unique_ptr<AnnotationSetItem>(
-            new AnnotationSetItem(*annotation_set_item, header)));
-      }
-    }
-
-    MethodId* GetMethodId() const { return method_id_; }
-    std::vector<std::unique_ptr<AnnotationSetItem>>& GetAnnotations() { return annotations_; }
-
-   private:
-    MethodId* method_id_;
-    std::vector<std::unique_ptr<AnnotationSetItem>> annotations_;
-    DISALLOW_COPY_AND_ASSIGN(ParameterAnnotation);
-  };
-
-  AnnotationsDirectoryItem(const DexFile::AnnotationsDirectoryItem* disk_annotations_item,
-                           Header& header);
+  AnnotationsDirectoryItem(AnnotationSetItem* class_annotation,
+                           FieldAnnotationVector* field_annotations,
+                           MethodAnnotationVector* method_annotations,
+                           ParameterAnnotationVector* parameter_annotations)
+      : class_annotation_(class_annotation),
+        field_annotations_(field_annotations),
+        method_annotations_(method_annotations),
+        parameter_annotations_(parameter_annotations) { }
 
   AnnotationSetItem* GetClassAnnotation() const { return class_annotation_.get(); }
-
-  std::vector<std::unique_ptr<FieldAnnotation>>& GetFieldAnnotations() {
-    return field_annotations_;
-  }
-
-  std::vector<std::unique_ptr<MethodAnnotation>>& GetMethodAnnotations() {
-    return method_annotations_;
-  }
-
-  std::vector<std::unique_ptr<ParameterAnnotation>>& GetParameterAnnotations() {
-    return parameter_annotations_;
-  }
+  FieldAnnotationVector* GetFieldAnnotations() { return field_annotations_.get(); }
+  MethodAnnotationVector* GetMethodAnnotations() { return method_annotations_.get(); }
+  ParameterAnnotationVector* GetParameterAnnotations() { return parameter_annotations_.get(); }
 
   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
 
  private:
   std::unique_ptr<AnnotationSetItem> class_annotation_;
-  std::vector<std::unique_ptr<FieldAnnotation>> field_annotations_;
-  std::vector<std::unique_ptr<MethodAnnotation>> method_annotations_;
-  std::vector<std::unique_ptr<ParameterAnnotation>> parameter_annotations_;
+  std::unique_ptr<FieldAnnotationVector> field_annotations_;
+  std::unique_ptr<MethodAnnotationVector> method_annotations_;
+  std::unique_ptr<ParameterAnnotationVector> parameter_annotations_;
   DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
 };
 
diff --git a/dexlayout/dex_ir_builder.cc b/dexlayout/dex_ir_builder.cc
new file mode 100644
index 0000000..38f35e7
--- /dev/null
+++ b/dexlayout/dex_ir_builder.cc
@@ -0,0 +1,507 @@
+/*
+ * Copyright (C) 2016 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.
+ *
+ * Header file of an in-memory representation of DEX files.
+ */
+
+#include <stdint.h>
+#include <vector>
+
+#include "dex_ir_builder.h"
+
+namespace art {
+namespace dex_ir {
+
+namespace {
+
+static uint64_t ReadVarWidth(const uint8_t** data, uint8_t length, bool sign_extend) {
+  uint64_t value = 0;
+  for (uint32_t i = 0; i <= length; i++) {
+    value |= static_cast<uint64_t>(*(*data)++) << (i * 8);
+  }
+  if (sign_extend) {
+    int shift = (7 - length) * 8;
+    return (static_cast<int64_t>(value) << shift) >> shift;
+  }
+  return value;
+}
+
+// Prototype to break cyclic dependency.
+void ReadPayloadUnion(Header& header,
+                      const uint8_t** data,
+                      uint8_t type,
+                      uint8_t length,
+                      ArrayItem::PayloadUnion* item);
+
+ArrayItem* ReadArrayItem(Header& header, const uint8_t** data, uint8_t type, uint8_t length) {
+  ArrayItem* item = new ArrayItem(type);
+  ReadPayloadUnion(header, data, type, length, item->GetPayloadUnion());
+  return item;
+}
+
+ArrayItem* ReadArrayItem(Header& header, const uint8_t** data) {
+  const uint8_t encoded_value = *(*data)++;
+  const uint8_t type = encoded_value & 0x1f;
+  ArrayItem* item = new ArrayItem(type);
+  ReadPayloadUnion(header, data, type, encoded_value >> 5, item->GetPayloadUnion());
+  return item;
+}
+
+void ReadPayloadUnion(Header& header,
+                      const uint8_t** data,
+                      uint8_t type,
+                      uint8_t length,
+                      ArrayItem::PayloadUnion* item) {
+  switch (type) {
+    case DexFile::kDexAnnotationByte:
+      item->byte_val_ = static_cast<int8_t>(ReadVarWidth(data, length, false));
+      break;
+    case DexFile::kDexAnnotationShort:
+      item->short_val_ = static_cast<int16_t>(ReadVarWidth(data, length, true));
+      break;
+    case DexFile::kDexAnnotationChar:
+      item->char_val_ = static_cast<uint16_t>(ReadVarWidth(data, length, false));
+      break;
+    case DexFile::kDexAnnotationInt:
+      item->int_val_ = static_cast<int32_t>(ReadVarWidth(data, length, true));
+      break;
+    case DexFile::kDexAnnotationLong:
+      item->long_val_ = static_cast<int64_t>(ReadVarWidth(data, length, true));
+      break;
+    case DexFile::kDexAnnotationFloat: {
+      // Fill on right.
+      union {
+        float f;
+        uint32_t data;
+      } conv;
+      conv.data = static_cast<uint32_t>(ReadVarWidth(data, length, false)) << (3 - length) * 8;
+      item->float_val_ = conv.f;
+      break;
+    }
+    case DexFile::kDexAnnotationDouble: {
+      // Fill on right.
+      union {
+        double d;
+        uint64_t data;
+      } conv;
+      conv.data = ReadVarWidth(data, length, false) << (7 - length) * 8;
+      item->double_val_ = conv.d;
+      break;
+    }
+    case DexFile::kDexAnnotationString: {
+      const uint32_t string_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
+      item->string_val_ = header.StringIds()[string_index].get();
+      break;
+    }
+    case DexFile::kDexAnnotationType: {
+      const uint32_t string_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
+      item->string_val_ = header.TypeIds()[string_index]->GetStringId();
+      break;
+    }
+    case DexFile::kDexAnnotationField:
+    case DexFile::kDexAnnotationEnum: {
+      const uint32_t field_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
+      item->field_val_ = header.FieldIds()[field_index].get();
+      break;
+    }
+    case DexFile::kDexAnnotationMethod: {
+      const uint32_t method_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
+      item->method_val_ = header.MethodIds()[method_index].get();
+      break;
+    }
+    case DexFile::kDexAnnotationArray: {
+      item->annotation_array_val_ = new ArrayItemVector();
+      // Decode all elements.
+      const uint32_t size = DecodeUnsignedLeb128(data);
+      for (uint32_t i = 0; i < size; i++) {
+        item->annotation_array_val_->push_back(
+            std::unique_ptr<ArrayItem>(ReadArrayItem(header, data)));
+      }
+      break;
+    }
+    case DexFile::kDexAnnotationAnnotation: {
+      const uint32_t type_idx = DecodeUnsignedLeb128(data);
+      item->annotation_annotation_val_.string_ = header.TypeIds()[type_idx]->GetStringId();
+      item->annotation_annotation_val_.array_ =
+          new std::vector<std::unique_ptr<ArrayItem::NameValuePair>>();
+      // Decode all name=value pairs.
+      const uint32_t size = DecodeUnsignedLeb128(data);
+      for (uint32_t i = 0; i < size; i++) {
+        const uint32_t name_index = DecodeUnsignedLeb128(data);
+        item->annotation_annotation_val_.array_->push_back(
+            std::unique_ptr<ArrayItem::NameValuePair>(
+                new ArrayItem::NameValuePair(header.StringIds()[name_index].get(),
+                                             ReadArrayItem(header, data))));
+      }
+      break;
+    }
+    case DexFile::kDexAnnotationNull:
+      break;
+    case DexFile::kDexAnnotationBoolean:
+      item->bool_val_ = (length != 0);
+      break;
+    default:
+      break;
+  }
+}
+
+static bool GetPositionsCb(void* context, const DexFile::PositionInfo& entry) {
+  DebugInfoItem* debug_info = reinterpret_cast<DebugInfoItem*>(context);
+  PositionInfoVector& positions = debug_info->GetPositionInfo();
+  positions.push_back(std::unique_ptr<PositionInfo>(new PositionInfo(entry.address_, entry.line_)));
+  return false;
+}
+
+static void GetLocalsCb(void* context, const DexFile::LocalInfo& entry) {
+  DebugInfoItem* debug_info = reinterpret_cast<DebugInfoItem*>(context);
+  LocalInfoVector& locals = debug_info->GetLocalInfo();
+  const char* name = entry.name_ != nullptr ? entry.name_ : "(null)";
+  const char* signature = entry.signature_ != nullptr ? entry.signature_ : "";
+  locals.push_back(std::unique_ptr<LocalInfo>(
+      new LocalInfo(name, entry.descriptor_, signature, entry.start_address_,
+                    entry.end_address_, entry.reg_)));
+}
+
+CodeItem* ReadCodeItem(const DexFile& dex_file,
+                       const DexFile::CodeItem& disk_code_item,
+                       Header& header) {
+  uint16_t registers_size = disk_code_item.registers_size_;
+  uint16_t ins_size = disk_code_item.ins_size_;
+  uint16_t outs_size = disk_code_item.outs_size_;
+  uint32_t tries_size = disk_code_item.tries_size_;
+
+  const uint8_t* debug_info_stream = dex_file.GetDebugInfoStream(&disk_code_item);
+  DebugInfoItem* debug_info = nullptr;
+  if (debug_info_stream != nullptr) {
+    debug_info = new DebugInfoItem();
+  }
+
+  uint32_t insns_size = disk_code_item.insns_size_in_code_units_;
+  uint16_t* insns = new uint16_t[insns_size];
+  memcpy(insns, disk_code_item.insns_, insns_size * sizeof(uint16_t));
+
+  TryItemVector* tries = nullptr;
+  if (tries_size > 0) {
+    tries = new TryItemVector();
+    for (uint32_t i = 0; i < tries_size; ++i) {
+      const DexFile::TryItem* disk_try_item = dex_file.GetTryItems(disk_code_item, i);
+      uint32_t start_addr = disk_try_item->start_addr_;
+      uint16_t insn_count = disk_try_item->insn_count_;
+      CatchHandlerVector* handlers = new CatchHandlerVector();
+      for (CatchHandlerIterator it(disk_code_item, *disk_try_item); it.HasNext(); it.Next()) {
+        const uint16_t type_index = it.GetHandlerTypeIndex();
+        const TypeId* type_id = header.GetTypeIdOrNullPtr(type_index);
+        handlers->push_back(std::unique_ptr<const CatchHandler>(
+            new CatchHandler(type_id, it.GetHandlerAddress())));
+      }
+      TryItem* try_item = new TryItem(start_addr, insn_count, handlers);
+      tries->push_back(std::unique_ptr<const TryItem>(try_item));
+    }
+  }
+  return new CodeItem(registers_size, ins_size, outs_size, debug_info, insns_size, insns, tries);
+}
+
+MethodItem* GenerateMethodItem(const DexFile& dex_file,
+                               dex_ir::Header& header,
+                               ClassDataItemIterator& cdii) {
+  MethodId* method_item = header.MethodIds()[cdii.GetMemberIndex()].get();
+  uint32_t access_flags = cdii.GetRawMemberAccessFlags();
+  const DexFile::CodeItem* disk_code_item = cdii.GetMethodCodeItem();
+  CodeItem* code_item = nullptr;
+  DebugInfoItem* debug_info = nullptr;
+  if (disk_code_item != nullptr) {
+    code_item = ReadCodeItem(dex_file, *disk_code_item, header);
+    code_item->SetOffset(cdii.GetMethodCodeItemOffset());
+    debug_info = code_item->DebugInfo();
+  }
+  if (debug_info != nullptr) {
+    bool is_static = (access_flags & kAccStatic) != 0;
+    dex_file.DecodeDebugLocalInfo(
+        disk_code_item, is_static, cdii.GetMemberIndex(), GetLocalsCb, debug_info);
+    dex_file.DecodeDebugPositionInfo(disk_code_item, GetPositionsCb, debug_info);
+  }
+  return new MethodItem(access_flags, method_item, code_item);
+}
+
+AnnotationSetItem* ReadAnnotationSetItem(const DexFile& dex_file,
+                                         const DexFile::AnnotationSetItem& disk_annotations_item,
+                                         Header& header) {
+  if (disk_annotations_item.size_ == 0) {
+    return nullptr;
+  }
+  AnnotationItemVector* items = new AnnotationItemVector();
+  for (uint32_t i = 0; i < disk_annotations_item.size_; ++i) {
+    const DexFile::AnnotationItem* annotation =
+        dex_file.GetAnnotationItem(&disk_annotations_item, i);
+    if (annotation == nullptr) {
+      continue;
+    }
+    uint8_t visibility = annotation->visibility_;
+    const uint8_t* annotation_data = annotation->annotation_;
+    ArrayItem* array_item =
+        ReadArrayItem(header, &annotation_data, DexFile::kDexAnnotationAnnotation, 0);
+    items->push_back(std::unique_ptr<AnnotationItem>(new AnnotationItem(visibility, array_item)));
+  }
+  return new AnnotationSetItem(items);
+}
+
+ParameterAnnotation* ReadParameterAnnotation(
+    const DexFile& dex_file,
+    MethodId* method_id,
+    const DexFile::AnnotationSetRefList* annotation_set_ref_list,
+    Header& header) {
+  AnnotationSetItemVector* annotations = new AnnotationSetItemVector();
+  for (uint32_t i = 0; i < annotation_set_ref_list->size_; ++i) {
+    const DexFile::AnnotationSetItem* annotation_set_item =
+        dex_file.GetSetRefItemItem(&annotation_set_ref_list->list_[i]);
+    annotations->push_back(std::unique_ptr<AnnotationSetItem>(
+        ReadAnnotationSetItem(dex_file, *annotation_set_item, header)));
+  }
+  return new ParameterAnnotation(method_id, annotations);
+}
+
+AnnotationsDirectoryItem* ReadAnnotationsDirectoryItem(
+    const DexFile& dex_file,
+    const DexFile::AnnotationsDirectoryItem* disk_annotations_item,
+    Header& header) {
+  const DexFile::AnnotationSetItem* class_set_item =
+      dex_file.GetClassAnnotationSet(disk_annotations_item);
+  AnnotationSetItem* class_annotation = nullptr;
+  if (class_set_item != nullptr) {
+    class_annotation = ReadAnnotationSetItem(dex_file, *class_set_item, header);
+  }
+  const DexFile::FieldAnnotationsItem* fields =
+      dex_file.GetFieldAnnotations(disk_annotations_item);
+  FieldAnnotationVector* field_annotations = nullptr;
+  if (fields != nullptr) {
+    field_annotations = new FieldAnnotationVector();
+    for (uint32_t i = 0; i < disk_annotations_item->fields_size_; ++i) {
+      FieldId* field_id = header.FieldIds()[fields[i].field_idx_].get();
+      const DexFile::AnnotationSetItem* field_set_item =
+          dex_file.GetFieldAnnotationSetItem(fields[i]);
+      AnnotationSetItem* annotation_set_item =
+          ReadAnnotationSetItem(dex_file, *field_set_item, header);
+      field_annotations->push_back(std::unique_ptr<FieldAnnotation>(
+          new FieldAnnotation(field_id, annotation_set_item)));
+    }
+  }
+  const DexFile::MethodAnnotationsItem* methods =
+      dex_file.GetMethodAnnotations(disk_annotations_item);
+  MethodAnnotationVector* method_annotations = nullptr;
+  if (methods != nullptr) {
+    method_annotations = new MethodAnnotationVector();
+    for (uint32_t i = 0; i < disk_annotations_item->methods_size_; ++i) {
+      MethodId* method_id = header.MethodIds()[methods[i].method_idx_].get();
+      const DexFile::AnnotationSetItem* method_set_item =
+          dex_file.GetMethodAnnotationSetItem(methods[i]);
+      AnnotationSetItem* annotation_set_item =
+          ReadAnnotationSetItem(dex_file, *method_set_item, header);
+      method_annotations->push_back(std::unique_ptr<MethodAnnotation>(
+          new MethodAnnotation(method_id, annotation_set_item)));
+    }
+  }
+  const DexFile::ParameterAnnotationsItem* parameters =
+      dex_file.GetParameterAnnotations(disk_annotations_item);
+  ParameterAnnotationVector* parameter_annotations = nullptr;
+  if (parameters != nullptr) {
+    parameter_annotations = new ParameterAnnotationVector();
+    for (uint32_t i = 0; i < disk_annotations_item->parameters_size_; ++i) {
+      MethodId* method_id = header.MethodIds()[parameters[i].method_idx_].get();
+      const DexFile::AnnotationSetRefList* list =
+          dex_file.GetParameterAnnotationSetRefList(&parameters[i]);
+      parameter_annotations->push_back(std::unique_ptr<ParameterAnnotation>(
+          ReadParameterAnnotation(dex_file, method_id, list, header)));
+    }
+  }
+
+  return new AnnotationsDirectoryItem(class_annotation,
+                                      field_annotations,
+                                      method_annotations,
+                                      parameter_annotations);
+}
+
+ClassDef* ReadClassDef(const DexFile& dex_file,
+                       const DexFile::ClassDef& disk_class_def,
+                       Header& header) {
+  const TypeId* class_type = header.TypeIds()[disk_class_def.class_idx_].get();
+  uint32_t access_flags = disk_class_def.access_flags_;
+  const TypeId* superclass = header.GetTypeIdOrNullPtr(disk_class_def.superclass_idx_);
+
+  TypeIdVector* interfaces = nullptr;
+  const DexFile::TypeList* type_list = dex_file.GetInterfacesList(disk_class_def);
+  uint32_t interfaces_offset = disk_class_def.interfaces_off_;
+  if (type_list != nullptr) {
+    interfaces = new TypeIdVector();
+    for (uint32_t index = 0; index < type_list->Size(); ++index) {
+      interfaces->push_back(header.TypeIds()[type_list->GetTypeItem(index).type_idx_].get());
+    }
+  }
+  const StringId* source_file = header.GetStringIdOrNullPtr(disk_class_def.source_file_idx_);
+  // Annotations.
+  AnnotationsDirectoryItem* annotations = nullptr;
+  const DexFile::AnnotationsDirectoryItem* disk_annotations_directory_item =
+      dex_file.GetAnnotationsDirectory(disk_class_def);
+  if (disk_annotations_directory_item != nullptr) {
+    annotations = ReadAnnotationsDirectoryItem(dex_file, disk_annotations_directory_item, header);
+    annotations->SetOffset(disk_class_def.annotations_off_);
+  }
+  // Static field initializers.
+  ArrayItemVector* static_values = nullptr;
+  const uint8_t* static_data = dex_file.GetEncodedStaticFieldValuesArray(disk_class_def);
+  if (static_data != nullptr) {
+    uint32_t static_value_count = static_data == nullptr ? 0 : DecodeUnsignedLeb128(&static_data);
+    if (static_value_count > 0) {
+      static_values = new ArrayItemVector();
+      for (uint32_t i = 0; i < static_value_count; ++i) {
+        static_values->push_back(std::unique_ptr<ArrayItem>(ReadArrayItem(header, &static_data)));
+      }
+    }
+  }
+  // Read the fields and methods defined by the class, resolving the circular reference from those
+  // to classes by setting class at the same time.
+  const uint8_t* encoded_data = dex_file.GetClassData(disk_class_def);
+  ClassData* class_data = nullptr;
+  if (encoded_data != nullptr) {
+    uint32_t offset = disk_class_def.class_data_off_;
+    ClassDataItemIterator cdii(dex_file, encoded_data);
+    // Static fields.
+    FieldItemVector* static_fields = new FieldItemVector();
+    for (uint32_t i = 0; cdii.HasNextStaticField(); i++, cdii.Next()) {
+      FieldId* field_item = header.FieldIds()[cdii.GetMemberIndex()].get();
+      uint32_t access_flags = cdii.GetRawMemberAccessFlags();
+      static_fields->push_back(std::unique_ptr<FieldItem>(new FieldItem(access_flags, field_item)));
+    }
+    // Instance fields.
+    FieldItemVector* instance_fields = new FieldItemVector();
+    for (uint32_t i = 0; cdii.HasNextInstanceField(); i++, cdii.Next()) {
+      FieldId* field_item = header.FieldIds()[cdii.GetMemberIndex()].get();
+      uint32_t access_flags = cdii.GetRawMemberAccessFlags();
+      instance_fields->push_back(
+          std::unique_ptr<FieldItem>(new FieldItem(access_flags, field_item)));
+    }
+    // Direct methods.
+    MethodItemVector* direct_methods = new MethodItemVector();
+    for (uint32_t i = 0; cdii.HasNextDirectMethod(); i++, cdii.Next()) {
+      direct_methods->push_back(
+          std::unique_ptr<MethodItem>(GenerateMethodItem(dex_file, header, cdii)));
+    }
+    // Virtual methods.
+    MethodItemVector* virtual_methods = new MethodItemVector();
+    for (uint32_t i = 0; cdii.HasNextVirtualMethod(); i++, cdii.Next()) {
+      virtual_methods->push_back(
+          std::unique_ptr<MethodItem>(GenerateMethodItem(dex_file, header, cdii)));
+    }
+    class_data = new ClassData(static_fields, instance_fields, direct_methods, virtual_methods);
+    class_data->SetOffset(offset);
+  }
+  return new ClassDef(class_type,
+                      access_flags,
+                      superclass,
+                      interfaces,
+                      interfaces_offset,
+                      source_file,
+                      annotations,
+                      static_values,
+                      class_data);
+}
+
+}  // namespace
+
+Header* DexIrBuilder(const DexFile& dex_file) {
+  const DexFile::Header& disk_header = dex_file.GetHeader();
+  Header* header = new Header(disk_header.magic_,
+                              disk_header.checksum_,
+                              disk_header.signature_,
+                              disk_header.endian_tag_,
+                              disk_header.file_size_,
+                              disk_header.header_size_,
+                              disk_header.link_size_,
+                              disk_header.link_off_,
+                              disk_header.data_size_,
+                              disk_header.data_off_);
+  // Walk the rest of the header fields.
+  // StringId table.
+  std::vector<std::unique_ptr<StringId>>& string_ids = header->StringIds();
+  header->SetStringIdsOffset(disk_header.string_ids_off_);
+  for (uint32_t i = 0; i < dex_file.NumStringIds(); ++i) {
+    const DexFile::StringId& disk_string_id = dex_file.GetStringId(i);
+    StringId* string_id = new StringId(dex_file.GetStringData(disk_string_id));
+    string_id->SetOffset(i);
+    string_ids.push_back(std::unique_ptr<StringId>(string_id));
+  }
+  // TypeId table.
+  std::vector<std::unique_ptr<TypeId>>& type_ids = header->TypeIds();
+  header->SetTypeIdsOffset(disk_header.type_ids_off_);
+  for (uint32_t i = 0; i < dex_file.NumTypeIds(); ++i) {
+    const DexFile::TypeId& disk_type_id = dex_file.GetTypeId(i);
+    TypeId* type_id = new TypeId(header->StringIds()[disk_type_id.descriptor_idx_].get());
+    type_id->SetOffset(i);
+    type_ids.push_back(std::unique_ptr<TypeId>(type_id));
+  }
+  // ProtoId table.
+  std::vector<std::unique_ptr<ProtoId>>& proto_ids = header->ProtoIds();
+  header->SetProtoIdsOffset(disk_header.proto_ids_off_);
+  for (uint32_t i = 0; i < dex_file.NumProtoIds(); ++i) {
+    const DexFile::ProtoId& disk_proto_id = dex_file.GetProtoId(i);
+    // Build the parameter type vector.
+    TypeIdVector* parameters = new TypeIdVector();
+    DexFileParameterIterator dfpi(dex_file, disk_proto_id);
+    while (dfpi.HasNext()) {
+      parameters->push_back(header->TypeIds()[dfpi.GetTypeIdx()].get());
+      dfpi.Next();
+    }
+    ProtoId* proto_id = new ProtoId(header->StringIds()[disk_proto_id.shorty_idx_].get(),
+                                    header->TypeIds()[disk_proto_id.return_type_idx_].get(),
+                                    parameters);
+    proto_id->SetOffset(i);
+    proto_ids.push_back(std::unique_ptr<ProtoId>(proto_id));
+  }
+  // FieldId table.
+  std::vector<std::unique_ptr<FieldId>>& field_ids = header->FieldIds();
+  header->SetFieldIdsOffset(disk_header.field_ids_off_);
+  for (uint32_t i = 0; i < dex_file.NumFieldIds(); ++i) {
+    const DexFile::FieldId& disk_field_id = dex_file.GetFieldId(i);
+    FieldId* field_id = new FieldId(header->TypeIds()[disk_field_id.class_idx_].get(),
+                                    header->TypeIds()[disk_field_id.type_idx_].get(),
+                                    header->StringIds()[disk_field_id.name_idx_].get());
+    field_id->SetOffset(i);
+    field_ids.push_back(std::unique_ptr<FieldId>(field_id));
+  }
+  // MethodId table.
+  std::vector<std::unique_ptr<MethodId>>& method_ids = header->MethodIds();
+  header->SetMethodIdsOffset(disk_header.method_ids_off_);
+  for (uint32_t i = 0; i < dex_file.NumMethodIds(); ++i) {
+    const DexFile::MethodId& disk_method_id = dex_file.GetMethodId(i);
+    MethodId* method_id = new MethodId(header->TypeIds()[disk_method_id.class_idx_].get(),
+                                       header->ProtoIds()[disk_method_id.proto_idx_].get(),
+                                       header->StringIds()[disk_method_id.name_idx_].get());
+    method_id->SetOffset(i);
+    method_ids.push_back(std::unique_ptr<MethodId>(method_id));
+  }
+  // ClassDef table.
+  std::vector<std::unique_ptr<ClassDef>>& class_defs = header->ClassDefs();
+  header->SetClassDefsOffset(disk_header.class_defs_off_);
+  for (uint32_t i = 0; i < dex_file.NumClassDefs(); ++i) {
+    const DexFile::ClassDef& disk_class_def = dex_file.GetClassDef(i);
+    ClassDef* class_def = ReadClassDef(dex_file, disk_class_def, *header);
+    class_def->SetOffset(i);
+    class_defs.push_back(std::unique_ptr<ClassDef>(class_def));
+  }
+
+  return header;
+}
+
+}  // namespace dex_ir
+}  // namespace art
diff --git a/dexlayout/dex_ir_builder.h b/dexlayout/dex_ir_builder.h
new file mode 100644
index 0000000..c53157b
--- /dev/null
+++ b/dexlayout/dex_ir_builder.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 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.
+ *
+ * Header file of an in-memory representation of DEX files.
+ */
+
+#ifndef ART_DEXLAYOUT_DEX_IR_BUILDER_H_
+#define ART_DEXLAYOUT_DEX_IR_BUILDER_H_
+
+#include "dex_ir.h"
+
+namespace art {
+namespace dex_ir {
+
+dex_ir::Header* DexIrBuilder(const DexFile& dex_file);
+
+}  // namespace dex_ir
+}  // namespace art
+
+#endif  // ART_DEXLAYOUT_DEX_IR_BUILDER_H_
diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc
index 0b31614..0d0b37a 100644
--- a/dexlayout/dexlayout.cc
+++ b/dexlayout/dexlayout.cc
@@ -30,7 +30,7 @@
 #include <sstream>
 #include <vector>
 
-#include "dex_ir.h"
+#include "dex_ir_builder.h"
 #include "dex_file-inl.h"
 #include "dex_instruction-inl.h"
 #include "utils.h"
@@ -501,20 +501,33 @@
   }
   fprintf(out_file_, "annotations_off     : %d (0x%06x)\n",
           annotations_offset, annotations_offset);
-  fprintf(out_file_, "class_data_off      : %d (0x%06x)\n",
-          class_def->GetClassData()->GetOffset(), class_def->GetClassData()->GetOffset());
+  if (class_def->GetClassData() == nullptr) {
+    fprintf(out_file_, "class_data_off      : %d (0x%06x)\n", 0, 0);
+  } else {
+    fprintf(out_file_, "class_data_off      : %d (0x%06x)\n",
+            class_def->GetClassData()->GetOffset(), class_def->GetClassData()->GetOffset());
+  }
 
   // Fields and methods.
   dex_ir::ClassData* class_data = class_def->GetClassData();
-  if (class_data != nullptr) {
-    fprintf(out_file_, "static_fields_size  : %zu\n", class_data->StaticFields().size());
-    fprintf(out_file_, "instance_fields_size: %zu\n", class_data->InstanceFields().size());
-    fprintf(out_file_, "direct_methods_size : %zu\n", class_data->DirectMethods().size());
-    fprintf(out_file_, "virtual_methods_size: %zu\n", class_data->VirtualMethods().size());
+  if (class_data != nullptr && class_data->StaticFields() != nullptr) {
+    fprintf(out_file_, "static_fields_size  : %zu\n", class_data->StaticFields()->size());
   } else {
     fprintf(out_file_, "static_fields_size  : 0\n");
+  }
+  if (class_data != nullptr && class_data->InstanceFields() != nullptr) {
+    fprintf(out_file_, "instance_fields_size: %zu\n", class_data->InstanceFields()->size());
+  } else {
     fprintf(out_file_, "instance_fields_size: 0\n");
+  }
+  if (class_data != nullptr && class_data->DirectMethods() != nullptr) {
+    fprintf(out_file_, "direct_methods_size : %zu\n", class_data->DirectMethods()->size());
+  } else {
     fprintf(out_file_, "direct_methods_size : 0\n");
+  }
+  if (class_data != nullptr && class_data->VirtualMethods() != nullptr) {
+    fprintf(out_file_, "virtual_methods_size: %zu\n", class_data->VirtualMethods()->size());
+  } else {
     fprintf(out_file_, "virtual_methods_size: 0\n");
   }
   fprintf(out_file_, "\n");
@@ -524,12 +537,11 @@
  * Dumps an annotation set item.
  */
 static void DumpAnnotationSetItem(dex_ir::AnnotationSetItem* set_item) {
-  if (set_item == nullptr || set_item->GetItems().size() == 0) {
+  if (set_item == nullptr || set_item->GetItems()->size() == 0) {
     fputs("  empty-annotation-set\n", out_file_);
     return;
   }
-  for (std::unique_ptr<dex_ir::AnnotationSetItem::AnnotationItem>& annotation :
-       set_item->GetItems()) {
+  for (std::unique_ptr<dex_ir::AnnotationItem>& annotation : *set_item->GetItems()) {
     if (annotation == nullptr) {
       continue;
     }
@@ -561,12 +573,9 @@
   fprintf(out_file_, "Class #%d annotations:\n", idx);
 
   dex_ir::AnnotationSetItem* class_set_item = annotations_directory->GetClassAnnotation();
-  std::vector<std::unique_ptr<dex_ir::AnnotationsDirectoryItem::FieldAnnotation>>& fields =
-      annotations_directory->GetFieldAnnotations();
-  std::vector<std::unique_ptr<dex_ir::AnnotationsDirectoryItem::MethodAnnotation>>& methods =
-      annotations_directory->GetMethodAnnotations();
-  std::vector<std::unique_ptr<dex_ir::AnnotationsDirectoryItem::ParameterAnnotation>>& parameters =
-      annotations_directory->GetParameterAnnotations();
+  dex_ir::FieldAnnotationVector* fields = annotations_directory->GetFieldAnnotations();
+  dex_ir::MethodAnnotationVector* methods = annotations_directory->GetMethodAnnotations();
+  dex_ir::ParameterAnnotationVector* parameters = annotations_directory->GetParameterAnnotations();
 
   // Annotations on the class itself.
   if (class_set_item != nullptr) {
@@ -575,34 +584,40 @@
   }
 
   // Annotations on fields.
-  for (auto& field : fields) {
-    const dex_ir::FieldId* field_id = field->GetFieldId();
-    const uint32_t field_idx = field_id->GetOffset();
-    const char* field_name = field_id->Name()->Data();
-    fprintf(out_file_, "Annotations on field #%u '%s'\n", field_idx, field_name);
-    DumpAnnotationSetItem(field->GetAnnotationSetItem());
+  if (fields != nullptr) {
+    for (auto& field : *fields) {
+      const dex_ir::FieldId* field_id = field->GetFieldId();
+      const uint32_t field_idx = field_id->GetOffset();
+      const char* field_name = field_id->Name()->Data();
+      fprintf(out_file_, "Annotations on field #%u '%s'\n", field_idx, field_name);
+      DumpAnnotationSetItem(field->GetAnnotationSetItem());
+    }
   }
 
   // Annotations on methods.
-  for (auto& method : methods) {
-    const dex_ir::MethodId* method_id = method->GetMethodId();
-    const uint32_t method_idx = method_id->GetOffset();
-    const char* method_name = method_id->Name()->Data();
-    fprintf(out_file_, "Annotations on method #%u '%s'\n", method_idx, method_name);
-    DumpAnnotationSetItem(method->GetAnnotationSetItem());
+  if (methods != nullptr) {
+    for (auto& method : *methods) {
+      const dex_ir::MethodId* method_id = method->GetMethodId();
+      const uint32_t method_idx = method_id->GetOffset();
+      const char* method_name = method_id->Name()->Data();
+      fprintf(out_file_, "Annotations on method #%u '%s'\n", method_idx, method_name);
+      DumpAnnotationSetItem(method->GetAnnotationSetItem());
+    }
   }
 
   // Annotations on method parameters.
-  for (auto& parameter : parameters) {
-    const dex_ir::MethodId* method_id = parameter->GetMethodId();
-    const uint32_t method_idx = method_id->GetOffset();
-    const char* method_name = method_id->Name()->Data();
-    fprintf(out_file_, "Annotations on method #%u '%s' parameters\n", method_idx, method_name);
-    uint32_t j = 0;
-    for (auto& annotation : parameter->GetAnnotations()) {
-      fprintf(out_file_, "#%u\n", j);
-      DumpAnnotationSetItem(annotation.get());
-      ++j;
+  if (parameters != nullptr) {
+    for (auto& parameter : *parameters) {
+      const dex_ir::MethodId* method_id = parameter->GetMethodId();
+      const uint32_t method_idx = method_id->GetOffset();
+      const char* method_name = method_id->Name()->Data();
+      fprintf(out_file_, "Annotations on method #%u '%s' parameters\n", method_idx, method_name);
+      uint32_t j = 0;
+      for (auto& annotation : *parameter->GetAnnotations()) {
+        fprintf(out_file_, "#%u\n", j);
+        DumpAnnotationSetItem(annotation.get());
+        ++j;
+      }
     }
   }
 
@@ -612,7 +627,7 @@
 /*
  * Dumps an interface that a class declares to implement.
  */
-static void DumpInterface(dex_ir::TypeId* type_item, int i) {
+static void DumpInterface(const dex_ir::TypeId* type_item, int i) {
   const char* interface_name = type_item->GetStringId()->Data();
   if (options_.output_format_ == kOutputPlain) {
     fprintf(out_file_, "    #%d              : '%s'\n", i, interface_name);
@@ -1260,8 +1275,8 @@
   }
   while (it.HasNextVirtualMethod()) {
     DumpCFG(dex_file,
-                it.GetMemberIndex(),
-                it.GetMethodCodeItem());
+            it.GetMemberIndex(),
+            it.GetMethodCodeItem());
     it.Next();
   }
 }
@@ -1274,7 +1289,10 @@
  * If "*last_package" is nullptr or does not match the current class' package,
  * the value will be replaced with a newly-allocated string.
  */
-static void DumpClass(dex_ir::Header* header, int idx, char** last_package) {
+static void DumpClass(const DexFile* dex_file,
+                      dex_ir::Header* header,
+                      int idx,
+                      char** last_package) {
   dex_ir::ClassDef* class_def = header->ClassDefs()[idx].get();
   // Omitting non-public class.
   if (options_.exports_only_ && (class_def->GetAccessFlags() & kAccPublic) == 0) {
@@ -1290,7 +1308,7 @@
   }
 
   if (options_.show_cfg_) {
-    DumpCFG(&header->GetDexFile(), idx);
+    DumpCFG(dex_file, idx);
     return;
   }
 
@@ -1368,10 +1386,12 @@
   }
 
   // Interfaces.
-  std::vector<dex_ir::TypeId*>* interfaces = class_def->Interfaces();
-  for (uint32_t i = 0; i < interfaces->size(); i++) {
-    DumpInterface((*interfaces)[i], i);
-  }  // for
+  dex_ir::TypeIdVector* interfaces = class_def->Interfaces();
+  if (interfaces != nullptr) {
+    for (uint32_t i = 0; i < interfaces->size(); i++) {
+      DumpInterface((*interfaces)[i], i);
+    }  // for
+  }
 
   // Fields and methods.
   dex_ir::ClassData* class_data = class_def->GetClassData();
@@ -1383,52 +1403,68 @@
   if (options_.output_format_ == kOutputPlain) {
     fprintf(out_file_, "  Static fields     -\n");
   }
-  std::vector<std::unique_ptr<dex_ir::FieldItem>>& static_fields = class_data->StaticFields();
-  for (uint32_t i = 0; i < static_fields.size(); i++) {
-    DumpSField(header,
-               static_fields[i]->GetFieldId()->GetOffset(),
-               static_fields[i]->GetAccessFlags(),
-               i,
-               i < static_values_size ? (*static_values)[i].get() : nullptr);
-  }  // for
+  if (class_data != nullptr) {
+    dex_ir::FieldItemVector* static_fields = class_data->StaticFields();
+    if (static_fields != nullptr) {
+      for (uint32_t i = 0; i < static_fields->size(); i++) {
+        DumpSField(header,
+                   (*static_fields)[i]->GetFieldId()->GetOffset(),
+                   (*static_fields)[i]->GetAccessFlags(),
+                   i,
+                   i < static_values_size ? (*static_values)[i].get() : nullptr);
+      }  // for
+    }
+  }
 
   // Instance fields.
   if (options_.output_format_ == kOutputPlain) {
     fprintf(out_file_, "  Instance fields   -\n");
   }
-  std::vector<std::unique_ptr<dex_ir::FieldItem>>& instance_fields = class_data->InstanceFields();
-  for (uint32_t i = 0; i < instance_fields.size(); i++) {
-    DumpIField(header,
-               instance_fields[i]->GetFieldId()->GetOffset(),
-               instance_fields[i]->GetAccessFlags(),
-               i);
-  }  // for
+  if (class_data != nullptr) {
+    dex_ir::FieldItemVector* instance_fields = class_data->InstanceFields();
+    if (instance_fields != nullptr) {
+      for (uint32_t i = 0; i < instance_fields->size(); i++) {
+        DumpIField(header,
+                   (*instance_fields)[i]->GetFieldId()->GetOffset(),
+                   (*instance_fields)[i]->GetAccessFlags(),
+                   i);
+      }  // for
+    }
+  }
 
   // Direct methods.
   if (options_.output_format_ == kOutputPlain) {
     fprintf(out_file_, "  Direct methods    -\n");
   }
-  std::vector<std::unique_ptr<dex_ir::MethodItem>>& direct_methods = class_data->DirectMethods();
-  for (uint32_t i = 0; i < direct_methods.size(); i++) {
-    DumpMethod(header,
-               direct_methods[i]->GetMethodId()->GetOffset(),
-               direct_methods[i]->GetAccessFlags(),
-               direct_methods[i]->GetCodeItem(),
-               i);
-  }  // for
+  if (class_data != nullptr) {
+    dex_ir::MethodItemVector* direct_methods = class_data->DirectMethods();
+    if (direct_methods != nullptr) {
+      for (uint32_t i = 0; i < direct_methods->size(); i++) {
+        DumpMethod(header,
+                   (*direct_methods)[i]->GetMethodId()->GetOffset(),
+                   (*direct_methods)[i]->GetAccessFlags(),
+                   (*direct_methods)[i]->GetCodeItem(),
+                 i);
+      }  // for
+    }
+  }
 
   // Virtual methods.
   if (options_.output_format_ == kOutputPlain) {
     fprintf(out_file_, "  Virtual methods   -\n");
   }
-  std::vector<std::unique_ptr<dex_ir::MethodItem>>& virtual_methods = class_data->VirtualMethods();
-  for (uint32_t i = 0; i < virtual_methods.size(); i++) {
-    DumpMethod(header,
-               virtual_methods[i]->GetMethodId()->GetOffset(),
-               virtual_methods[i]->GetAccessFlags(),
-               virtual_methods[i]->GetCodeItem(),
-               i);
-  }  // for
+  if (class_data != nullptr) {
+    dex_ir::MethodItemVector* virtual_methods = class_data->VirtualMethods();
+    if (virtual_methods != nullptr) {
+      for (uint32_t i = 0; i < virtual_methods->size(); i++) {
+        DumpMethod(header,
+                   (*virtual_methods)[i]->GetMethodId()->GetOffset(),
+                   (*virtual_methods)[i]->GetAccessFlags(),
+                   (*virtual_methods)[i]->GetCodeItem(),
+                   i);
+      }  // for
+    }
+  }
 
   // End of class.
   if (options_.output_format_ == kOutputPlain) {
@@ -1454,11 +1490,11 @@
     fprintf(out_file_, "Opened '%s', DEX version '%.3s'\n",
             file_name, dex_file->GetHeader().magic_ + 4);
   }
-  dex_ir::Header header(*dex_file);
+  dex_ir::Header* header = dex_ir::DexIrBuilder(*dex_file);
 
   // Headers.
   if (options_.show_file_headers_) {
-    DumpFileHeader(&header);
+    DumpFileHeader(header);
   }
 
   // Open XML context.
@@ -1468,9 +1504,9 @@
 
   // Iterate over all classes.
   char* package = nullptr;
-  const uint32_t class_defs_size = header.ClassDefsSize();
+  const uint32_t class_defs_size = header->ClassDefsSize();
   for (uint32_t i = 0; i < class_defs_size; i++) {
-    DumpClass(&header, i, &package);
+    DumpClass(dex_file, header, i, &package);
   }  // for
 
   // Free the last package allocated.
