diff --git a/dexlayout/dex_ir.h b/dexlayout/dex_ir.h
new file mode 100644
index 0000000..bef5c0d
--- /dev/null
+++ b/dexlayout/dex_ir.h
@@ -0,0 +1,684 @@
+/*
+ * 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_H_
+#define ART_DEXLAYOUT_DEX_IR_H_
+
+#include <iostream>
+#include <map>
+#include <vector>
+#include <stdint.h>
+
+#include "dex_file.h"
+
+namespace art {
+namespace dex_ir {
+
+// Forward declarations for classes used in containers or pointed to.
+class AnnotationsDirectoryItem;
+class AnnotationSetItem;
+class ArrayItem;
+class ClassData;
+class ClassDef;
+class CodeItem;
+class DebugInfoItem;
+class FieldId;
+class FieldItem;
+class Header;
+class MapList;
+class MapItem;
+class MethodId;
+class MethodItem;
+class ProtoId;
+class StringId;
+class TryItem;
+class TypeId;
+
+// Visitor support
+class AbstractDispatcher {
+ public:
+  AbstractDispatcher() = default;
+  virtual ~AbstractDispatcher() { }
+
+  virtual void Dispatch(Header* header) = 0;
+  virtual void Dispatch(const StringId* string_id) = 0;
+  virtual void Dispatch(const TypeId* type_id) = 0;
+  virtual void Dispatch(const ProtoId* proto_id) = 0;
+  virtual void Dispatch(const FieldId* field_id) = 0;
+  virtual void Dispatch(const MethodId* method_id) = 0;
+  virtual void Dispatch(ClassData* class_data) = 0;
+  virtual void Dispatch(ClassDef* class_def) = 0;
+  virtual void Dispatch(FieldItem* field_item) = 0;
+  virtual void Dispatch(MethodItem* method_item) = 0;
+  virtual void Dispatch(ArrayItem* array_item) = 0;
+  virtual void Dispatch(CodeItem* code_item) = 0;
+  virtual void Dispatch(TryItem* try_item) = 0;
+  virtual void Dispatch(DebugInfoItem* debug_info_item) = 0;
+  virtual void Dispatch(AnnotationSetItem* annotation_set_item) = 0;
+  virtual void Dispatch(AnnotationsDirectoryItem* annotations_directory_item) = 0;
+  virtual void Dispatch(MapList* map_list) = 0;
+  virtual void Dispatch(MapItem* map_item) = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AbstractDispatcher);
+};
+
+// Collections become owners of the objects added by moving them into unique pointers.
+template<class T> class CollectionWithOffset {
+ public:
+  CollectionWithOffset() = default;
+  std::vector<std::unique_ptr<T>>& Collection() { return collection_; }
+  // Read-time support methods
+  void AddWithPosition(uint32_t position, T* object) {
+    collection_.push_back(std::unique_ptr<T>(object));
+    collection_.back()->SetOffset(position);
+  }
+  // Ordinary object insertion into collection.
+  void Insert(T object ATTRIBUTE_UNUSED) {
+    // TODO(sehr): add ordered insertion support.
+    UNIMPLEMENTED(FATAL) << "Insertion not ready";
+  }
+  uint32_t GetOffset() const { return offset_; }
+  void SetOffset(uint32_t new_offset) { offset_ = new_offset; }
+  uint32_t Size() const { return collection_.size(); }
+
+ private:
+  std::vector<std::unique_ptr<T>> collection_;
+  uint32_t offset_ = 0;
+  DISALLOW_COPY_AND_ASSIGN(CollectionWithOffset);
+};
+
+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() 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_; }
+  uint32_t EndianTag() const { return endian_tag_; }
+  uint32_t FileSize() const { return file_size_; }
+  uint32_t HeaderSize() const { return header_size_; }
+  uint32_t LinkSize() const { return link_size_; }
+  uint32_t LinkOffset() const { return link_offset_; }
+  uint32_t DataSize() const { return data_size_; }
+  uint32_t DataOffset() const { return data_offset_; }
+
+  void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; }
+  void SetSignature(const uint8_t* new_signature) {
+    memcpy(signature_, new_signature, sizeof(signature_));
+  }
+  void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; }
+  void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; }
+  void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; }
+  void SetLinkOffset(uint32_t new_link_offset) { link_offset_ = new_link_offset; }
+  void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; }
+  void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; }
+
+  // Collections.
+  std::vector<std::unique_ptr<StringId>>& StringIds() { return string_ids_.Collection(); }
+  std::vector<std::unique_ptr<TypeId>>& TypeIds() { return type_ids_.Collection(); }
+  std::vector<std::unique_ptr<ProtoId>>& ProtoIds() { return proto_ids_.Collection(); }
+  std::vector<std::unique_ptr<FieldId>>& FieldIds() { return field_ids_.Collection(); }
+  std::vector<std::unique_ptr<MethodId>>& MethodIds() { return method_ids_.Collection(); }
+  std::vector<std::unique_ptr<ClassDef>>& ClassDefs() { return class_defs_.Collection(); }
+  uint32_t StringIdsOffset() const { return string_ids_.GetOffset(); }
+  uint32_t TypeIdsOffset() const { return type_ids_.GetOffset(); }
+  uint32_t ProtoIdsOffset() const { return proto_ids_.GetOffset(); }
+  uint32_t FieldIdsOffset() const { return field_ids_.GetOffset(); }
+  uint32_t MethodIdsOffset() const { return method_ids_.GetOffset(); }
+  uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); }
+  void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); }
+  void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); }
+  void SetProtoIdsOffset(uint32_t new_offset) { proto_ids_.SetOffset(new_offset); }
+  void SetFieldIdsOffset(uint32_t new_offset) { field_ids_.SetOffset(new_offset); }
+  void SetMethodIdsOffset(uint32_t new_offset) { method_ids_.SetOffset(new_offset); }
+  void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); }
+  uint32_t StringIdsSize() const { return string_ids_.Size(); }
+  uint32_t TypeIdsSize() const { return type_ids_.Size(); }
+  uint32_t ProtoIdsSize() const { return proto_ids_.Size(); }
+  uint32_t FieldIdsSize() const { return field_ids_.Size(); }
+  uint32_t MethodIdsSize() const { return method_ids_.Size(); }
+  uint32_t ClassDefsSize() const { return class_defs_.Size(); }
+
+  void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
+
+ private:
+  const DexFile& dex_file_;
+  uint8_t magic_[8];
+  uint32_t checksum_;
+  uint8_t signature_[DexFile::kSha1DigestSize];
+  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_;
+
+  CollectionWithOffset<StringId> string_ids_;
+  CollectionWithOffset<TypeId> type_ids_;
+  CollectionWithOffset<ProtoId> proto_ids_;
+  CollectionWithOffset<FieldId> field_ids_;
+  CollectionWithOffset<MethodId> method_ids_;
+  CollectionWithOffset<ClassDef> class_defs_;
+  DISALLOW_COPY_AND_ASSIGN(Header);
+};
+
+class StringId : public Item {
+ public:
+  StringId(const DexFile::StringId& disk_string_id, Header& header) :
+    data_(strdup(header.GetDexFile().GetStringData(disk_string_id))) {
+  }
+  ~StringId() OVERRIDE { }
+
+  const char* Data() const { return data_.get(); }
+
+  void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
+
+ private:
+  std::unique_ptr<const char> data_;
+  DISALLOW_COPY_AND_ASSIGN(StringId);
+};
+
+class TypeId : public Item {
+ public:
+  TypeId(const DexFile::TypeId& disk_type_id, Header& header) :
+    string_id_(header.StringIds()[disk_type_id.descriptor_idx_].get()) {
+  }
+  ~TypeId() OVERRIDE { }
+
+  StringId* GetStringId() const { return string_id_; }
+
+  void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
+
+ private:
+  StringId* string_id_;
+  DISALLOW_COPY_AND_ASSIGN(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() OVERRIDE { }
+
+  const StringId* Shorty() const { return shorty_; }
+  const TypeId* ReturnType() const { return return_type_; }
+  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_;
+  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() OVERRIDE { }
+
+  const TypeId* Class() const { return class_; }
+  const TypeId* Type() const { return type_; }
+  const StringId* Name() const { return name_; }
+
+  void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
+
+ private:
+  const TypeId* class_;
+  const TypeId* type_;
+  const StringId* name_;
+  DISALLOW_COPY_AND_ASSIGN(FieldId);
+};
+
+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() OVERRIDE { }
+
+  const TypeId* Class() const { return class_; }
+  const ProtoId* Proto() const { return proto_; }
+  const StringId* Name() const { return name_; }
+
+  void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
+
+ private:
+  const TypeId* class_;
+  const ProtoId* proto_;
+  const StringId* name_;
+  DISALLOW_COPY_AND_ASSIGN(MethodId);
+};
+
+class FieldItem : public Item {
+ public:
+  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_; }
+  const FieldId* GetFieldId() const { return field_id_; }
+
+  void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
+
+ private:
+  uint32_t access_flags_;
+  const FieldId* field_id_;
+  DISALLOW_COPY_AND_ASSIGN(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() OVERRIDE { }
+
+  uint32_t GetAccessFlags() const { return access_flags_; }
+  const MethodId* GetMethodId() const { return method_id_; }
+  const CodeItem* GetCodeItem() const { return code_.get(); }
+
+  void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
+
+ private:
+  uint32_t access_flags_;
+  const MethodId* method_id_;
+  std::unique_ptr<const CodeItem> code_;
+  DISALLOW_COPY_AND_ASSIGN(MethodItem);
+};
+
+class ArrayItem : public Item {
+ public:
+  class NameValuePair {
+   public:
+    NameValuePair(StringId* name, ArrayItem* value) :
+      name_(name), value_(value) { }
+
+    StringId* Name() const { return name_; }
+    ArrayItem* Value() const { return value_.get(); }
+
+   private:
+    StringId* name_;
+    std::unique_ptr<ArrayItem> value_;
+    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);
+  ~ArrayItem() OVERRIDE { }
+
+  int8_t Type() const { return type_; }
+  bool GetBoolean() const { return item_.bool_val_; }
+  int8_t GetByte() const { return item_.byte_val_; }
+  int16_t GetShort() const { return item_.short_val_; }
+  uint16_t GetChar() const { return item_.char_val_; }
+  int32_t GetInt() const { return item_.int_val_; }
+  int64_t GetLong() const { return item_.long_val_; }
+  float GetFloat() const { return item_.float_val_; }
+  double GetDouble() const { return item_.double_val_; }
+  StringId* GetStringId() const { return item_.string_val_; }
+  FieldId* GetFieldId() const { return item_.field_val_; }
+  MethodId* GetMethodId() const { return item_.method_val_; }
+  std::vector<std::unique_ptr<ArrayItem>>* GetAnnotationArray() const {
+    return item_.annotation_array_val_;
+  }
+  StringId* GetAnnotationAnnotationString() const {
+    return item_.annotation_annotation_val_.string_;
+  }
+  std::vector<std::unique_ptr<NameValuePair>>* GetAnnotationAnnotationNameValuePairArray() const {
+    return item_.annotation_annotation_val_.array_;
+  }
+
+  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_;
+  DISALLOW_COPY_AND_ASSIGN(ArrayItem);
+};
+
+class ClassData : public Item {
+ public:
+  ClassData() = default;
+  ~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_; }
+
+  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_;
+  DISALLOW_COPY_AND_ASSIGN(ClassData);
+};
+
+class ClassDef : public Item {
+ public:
+  ClassDef(const DexFile::ClassDef& disk_class_def, Header& header);
+  ~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_; }
+  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_; }
+
+  void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
+
+ private:
+  const TypeId* class_type_;
+  uint32_t access_flags_;
+  const TypeId* superclass_;
+  std::vector<TypeId*> 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_;
+  DISALLOW_COPY_AND_ASSIGN(ClassDef);
+};
+
+class CodeItem : public Item {
+ public:
+  CodeItem(const DexFile::CodeItem& disk_code_item, Header& header);
+  ~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_; }
+  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_; }
+
+  void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
+
+ private:
+  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_;
+  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 = type_index != DexFile::kDexNoIndex16 ?
+          header.TypeIds()[type_index].get() : nullptr;
+      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) { }
+
+  uint32_t address_;
+  uint32_t line_;
+};
+
+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) { }
+
+  std::string name_;
+  std::string descriptor_;
+  std::string signature_;
+  uint32_t start_address_;
+  uint32_t end_address_;
+  uint16_t reg_;
+};
+
+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_; }
+
+ private:
+  std::vector<std::unique_ptr<PositionInfo>> positions_;
+  std::vector<std::unique_ptr<LocalInfo>> locals_;
+  DISALLOW_COPY_AND_ASSIGN(DebugInfoItem);
+};
+
+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);
+  ~AnnotationSetItem() OVERRIDE { }
+
+  std::vector<std::unique_ptr<AnnotationItem>>& GetItems() { return items_; }
+
+  void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
+
+ private:
+  std::vector<std::unique_ptr<AnnotationItem>> items_;
+  DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
+};
+
+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);
+
+  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_;
+  }
+
+  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_;
+  DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
+};
+
+// TODO(sehr): implement MapList.
+class MapList : public Item {
+ public:
+  void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MapList);
+};
+
+class MapItem : public Item {
+ public:
+  void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MapItem);
+};
+
+}  // namespace dex_ir
+}  // namespace art
+
+#endif  // ART_DEXLAYOUT_DEX_IR_H_
