diff --git a/tools/ijar/classfile.cc b/tools/ijar/classfile.cc
new file mode 100644
index 0000000..5d12cc2
--- /dev/null
+++ b/tools/ijar/classfile.cc
@@ -0,0 +1,1788 @@
+// Copyright 2001,2007 Alan Donovan. All rights reserved.
+//
+// Author: Alan Donovan <adonovan@google.com>
+//
+// 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.
+//
+// classfile.cc -- classfile parsing and stripping.
+//
+
+// TODO(adonovan) don't pass pointers by reference; this is not
+// compatible with Google C++ style.
+
+// See README.txt for details.
+//
+// For definition of JVM class file format, see:
+// Java SE 8 Edition:
+// http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4
+
+#define __STDC_FORMAT_MACROS 1
+#define __STDC_LIMIT_MACROS 1
+#include <inttypes.h> // for PRIx32
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "common.h"
+
+namespace devtools_ijar {
+
+// See Table 4.3 in JVM Spec.
+enum CONSTANT {
+  CONSTANT_Class              = 7,
+  CONSTANT_FieldRef           = 9,
+  CONSTANT_Methodref          = 10,
+  CONSTANT_Interfacemethodref = 11,
+  CONSTANT_String             = 8,
+  CONSTANT_Integer            = 3,
+  CONSTANT_Float              = 4,
+  CONSTANT_Long               = 5,
+  CONSTANT_Double             = 6,
+  CONSTANT_NameAndType        = 12,
+  CONSTANT_Utf8               = 1,
+  CONSTANT_MethodHandle       = 15,
+  CONSTANT_MethodType         = 16,
+  CONSTANT_InvokeDynamic      = 18
+};
+
+// See Tables 4.1, 4.4, 4.5 in JVM Spec.
+enum ACCESS  {
+  ACC_PUBLIC          = 0x0001,
+  ACC_PRIVATE         = 0x0002,
+  ACC_PROTECTED       = 0x0004,
+  ACC_STATIC          = 0x0008,
+  ACC_FINAL           = 0x0010,
+  ACC_SYNCHRONIZED    = 0x0020,
+  ACC_VOLATILE        = 0x0040,
+  ACC_TRANSIENT       = 0x0080,
+  ACC_INTERFACE       = 0x0200,
+  ACC_ABSTRACT        = 0x0400
+};
+
+// See Table 4.7.20-A in Java 8 JVM Spec.
+enum TARGET_TYPE {
+  // Targets for type parameter declarations (ElementType.TYPE_PARAMETER):
+  CLASS_TYPE_PARAMETER        = 0x00,
+  METHOD_TYPE_PARAMETER       = 0x01,
+
+  // Targets for type uses that may be externally visible in classes and members
+  // (ElementType.TYPE_USE):
+  CLASS_EXTENDS               = 0x10,
+  CLASS_TYPE_PARAMETER_BOUND  = 0x11,
+  METHOD_TYPE_PARAMETER_BOUND = 0x12,
+  FIELD                       = 0x13,
+  METHOD_RETURN               = 0x14,
+  METHOD_RECEIVER             = 0x15,
+  METHOD_FORMAL_PARAMETER     = 0x16,
+  THROWS                      = 0x17,
+
+  // TARGET_TYPE >= 0x40 is reserved for type uses that occur only within code
+  // blocks. Ijar doesn't need to know about these.
+};
+
+struct Constant;
+
+// TODO(adonovan) these globals are unfortunate
+static std::vector<Constant*>        const_pool_in; // input constant pool
+static std::vector<Constant*>        const_pool_out; // output constant_pool
+static std::set<std::string>         used_class_names;
+static Constant *                    class_name;
+
+// Returns the Constant object, given an index into the input constant pool.
+// Note: constant(0) == NULL; this invariant is exploited by the
+// InnerClassesAttribute, inter alia.
+inline Constant *constant(int idx) {
+  if (idx < 0 || (unsigned)idx >= const_pool_in.size()) {
+    fprintf(stderr, "Illegal constant pool index: %d\n", idx);
+    abort();
+  }
+  return const_pool_in[idx];
+}
+
+/**********************************************************************
+ *                                                                    *
+ *                             Constants                              *
+ *                                                                    *
+ **********************************************************************/
+
+// See sec.4.4 of JVM spec.
+struct Constant {
+
+  Constant(u1 tag) :
+      slot_(0),
+      tag_(tag) {}
+
+  virtual ~Constant() {}
+
+  // For UTF-8 string constants, returns the encoded string.
+  // Otherwise, returns an undefined string value suitable for debugging.
+  virtual std::string Display() = 0;
+
+  virtual void Write(u1 *&p) = 0;
+
+  // Called by slot() when a constant has been identified as required
+  // in the output classfile's constant pool.  This is a hook allowing
+  // constants to register their dependency on other constants, by
+  // calling slot() on them in turn.
+  virtual void Keep() {}
+
+  bool Kept() {
+    return slot_ != 0;
+  }
+
+  // Returns the index of this constant in the output class's constant
+  // pool, assigning a slot if not already done.
+  u2 slot() {
+    if (slot_ == 0) {
+      Keep();
+      slot_ = const_pool_out.size(); // BugBot's "narrowing" warning
+                                     // is bogus.  The number of
+                                     // output constants can't exceed
+                                     // the number of input constants.
+      if (slot_ == 0) {
+        fprintf(stderr, "Constant::slot() called before output phase.\n");
+        abort();
+      }
+      const_pool_out.push_back(this);
+      if (tag_ == CONSTANT_Long || tag_ == CONSTANT_Double) {
+        const_pool_out.push_back(NULL);
+      }
+    }
+    return slot_;
+  }
+
+  u2 slot_; // zero => "this constant is unreachable garbage"
+  u1 tag_;
+};
+
+// Extracts class names from a signature and puts them into the global
+// variable used_class_names.
+//
+// desc: the descriptor class names should be extracted from.
+// p: the position where the extraction should tart.
+void ExtractClassNames(const std::string& desc, size_t* p);
+
+// See sec.4.4.1 of JVM spec.
+struct Constant_Class : Constant
+{
+  Constant_Class(u2 name_index) :
+      Constant(CONSTANT_Class),
+      name_index_(name_index) {}
+
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    put_u2be(p, constant(name_index_)->slot());
+  }
+
+  std::string Display() {
+    return constant(name_index_)->Display();
+  }
+
+  void Keep() { constant(name_index_)->slot(); }
+
+  u2 name_index_;
+};
+
+// See sec.4.4.2 of JVM spec.
+struct Constant_FMIref : Constant
+{
+  Constant_FMIref(u1 tag,
+                  u2 class_index,
+                  u2 name_type_index) :
+      Constant(tag),
+      class_index_(class_index),
+      name_type_index_(name_type_index) {}
+
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    put_u2be(p, constant(class_index_)->slot());
+    put_u2be(p, constant(name_type_index_)->slot());
+  }
+
+  std::string Display() {
+    return constant(class_index_)->Display() + "::" +
+        constant(name_type_index_)->Display();
+  }
+
+  void Keep() {
+    constant(class_index_)->slot();
+    constant(name_type_index_)->slot();
+  }
+
+  u2 class_index_;
+  u2 name_type_index_;
+};
+
+// See sec.4.4.3 of JVM spec.
+struct Constant_String : Constant
+{
+  Constant_String(u2 string_index) :
+      Constant(CONSTANT_String),
+      string_index_(string_index) {}
+
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    put_u2be(p, constant(string_index_)->slot());
+  }
+
+  std::string Display() {
+    return "\"" + constant(string_index_)->Display() + "\"";
+  }
+
+  void Keep() { constant(string_index_)->slot(); }
+
+  u2 string_index_;
+};
+
+// See sec.4.4.4 of JVM spec.
+struct Constant_IntegerOrFloat : Constant
+{
+  Constant_IntegerOrFloat(u1 tag, u4 bytes) :
+      Constant(tag),
+      bytes_(bytes) {}
+
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    put_u4be(p, bytes_);
+  }
+
+  std::string Display() { return "int/float"; }
+
+  u4 bytes_;
+};
+
+// See sec.4.4.5 of JVM spec.
+struct Constant_LongOrDouble : Constant_IntegerOrFloat
+{
+  Constant_LongOrDouble(u1 tag, u4 high_bytes, u4 low_bytes) :
+      Constant_IntegerOrFloat(tag, high_bytes),
+      low_bytes_(low_bytes) {}
+
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    put_u4be(p, bytes_);
+    put_u4be(p, low_bytes_);
+  }
+
+  std::string Display() { return "long/double"; }
+
+  u4 low_bytes_;
+};
+
+// See sec.4.4.6 of JVM spec.
+struct Constant_NameAndType : Constant
+{
+  Constant_NameAndType(u2 name_index, u2 descr_index) :
+      Constant(CONSTANT_NameAndType),
+      name_index_(name_index),
+      descr_index_(descr_index) {}
+
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    put_u2be(p, constant(name_index_)->slot());
+    put_u2be(p, constant(descr_index_)->slot());
+  }
+
+  std::string Display() {
+    return constant(name_index_)->Display() + "::" +
+        constant(descr_index_)->Display();
+  }
+
+  void Keep() {
+    constant(name_index_)->slot();
+    constant(descr_index_)->slot();
+  }
+
+  u2 name_index_;
+  u2 descr_index_;
+};
+
+// See sec.4.4.7 of JVM spec.
+struct Constant_Utf8 : Constant
+{
+  Constant_Utf8(u4 length, const u1 *utf8) :
+      Constant(CONSTANT_Utf8),
+      length_(length),
+      utf8_(utf8) {}
+
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    put_u2be(p, length_);
+    put_n(p, utf8_, length_);
+  }
+
+  std::string Display() {
+    return std::string((const char*) utf8_, length_);
+  }
+
+  u4 length_;
+  const u1 *utf8_;
+};
+
+// See sec.4.4.8 of JVM spec.
+struct Constant_MethodHandle : Constant
+{
+  Constant_MethodHandle(u1 reference_kind, u2 reference_index) :
+      Constant(CONSTANT_MethodHandle),
+      reference_kind_(reference_kind),
+      reference_index_(reference_index) {}
+
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    put_u1(p, reference_kind_);
+    put_u2be(p, reference_index_);
+  }
+
+  std::string Display() {
+    return "Constant_MethodHandle::" + std::to_string(reference_kind_) + "::"
+        + constant(reference_index_)->Display();
+  }
+
+  u1 reference_kind_;
+  u2 reference_index_;
+};
+
+// See sec.4.4.9 of JVM spec.
+struct Constant_MethodType : Constant
+{
+  Constant_MethodType(u2 descriptor_index) :
+      Constant(CONSTANT_MethodType),
+      descriptor_index_(descriptor_index) {}
+
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    put_u2be(p, descriptor_index_);
+  }
+
+  std::string Display() {
+    return  "Constant_MethodType::" + constant(descriptor_index_)->Display();
+  }
+
+  u2 descriptor_index_;
+};
+
+// See sec.4.4.10 of JVM spec.
+struct Constant_InvokeDynamic : Constant
+{
+  Constant_InvokeDynamic(u2 bootstrap_method_attr_index, u2 name_and_type_index) :
+      Constant(CONSTANT_InvokeDynamic),
+      bootstrap_method_attr_index_(bootstrap_method_attr_index),
+      name_and_type_index_(name_and_type_index) {}
+
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    put_u2be(p, bootstrap_method_attr_index_);
+    put_u2be(p, name_and_type_index_);
+  }
+
+  std::string Display() {
+    return  "Constant_InvokeDynamic::"
+        + std::to_string(bootstrap_method_attr_index_) + "::"
+        + constant(name_and_type_index_)->Display();
+  }
+
+  u2 bootstrap_method_attr_index_;
+  u2 name_and_type_index_;
+};
+
+/**********************************************************************
+ *                                                                    *
+ *                             Attributes                             *
+ *                                                                    *
+ **********************************************************************/
+
+// See sec.4.7 of JVM spec.
+struct Attribute {
+
+  virtual ~Attribute() {}
+  virtual void Write(u1 *&p) = 0;
+  virtual void ExtractClassNames() {}
+
+  void WriteProlog(u1 *&p, u2 length) {
+    put_u2be(p, attribute_name_->slot());
+    put_u4be(p, length);
+  }
+
+  Constant *attribute_name_;
+};
+
+// See sec.4.7.5 of JVM spec.
+struct ExceptionsAttribute : Attribute {
+
+  static ExceptionsAttribute* Read(const u1 *&p, Constant *attribute_name) {
+    ExceptionsAttribute *attr = new ExceptionsAttribute;
+    attr->attribute_name_ = attribute_name;
+    u2 number_of_exceptions = get_u2be(p);
+    for (int ii = 0; ii < number_of_exceptions; ++ii) {
+      attr->exceptions_.push_back(constant(get_u2be(p)));
+    }
+    return attr;
+  }
+
+  void Write(u1 *&p) {
+    WriteProlog(p, exceptions_.size() * 2 + 2);
+    put_u2be(p, exceptions_.size());
+    for (size_t ii = 0; ii < exceptions_.size(); ++ii) {
+      put_u2be(p, exceptions_[ii]->slot());
+    }
+  }
+
+  std::vector<Constant*> exceptions_;
+};
+
+// See sec.4.7.6 of JVM spec.
+struct InnerClassesAttribute : Attribute {
+
+  struct Entry {
+    Constant *inner_class_info;
+    Constant *outer_class_info;
+    Constant *inner_name;
+    u2 inner_class_access_flags;
+  };
+
+  virtual ~InnerClassesAttribute() {
+    for (size_t i = 0; i < entries_.size(); i++) {
+      delete entries_[i];
+    }
+  }
+
+  static InnerClassesAttribute* Read(const u1 *&p, Constant *attribute_name) {
+    InnerClassesAttribute *attr = new InnerClassesAttribute;
+    attr->attribute_name_ = attribute_name;
+
+    u2 number_of_classes = get_u2be(p);
+    for (int ii = 0; ii < number_of_classes; ++ii) {
+      Entry *entry = new Entry;
+      entry->inner_class_info = constant(get_u2be(p));
+      entry->outer_class_info = constant(get_u2be(p));
+      entry->inner_name = constant(get_u2be(p));
+      entry->inner_class_access_flags = get_u2be(p);
+
+      attr->entries_.push_back(entry);
+    }
+    return attr;
+  }
+
+  void Write(u1 *&p) {
+    std::set<int> kept_entries;
+    // We keep an entry if the constant referring to the inner class is already
+    // kept. Then we mark its outer class and its class name as kept, too, then
+    // iterate until a fixed point is reached.
+    int entry_count;
+    int iteration = 0;
+
+    do {
+      entry_count = kept_entries.size();
+      for (int i_entry = 0; i_entry < entries_.size(); ++i_entry) {
+        Entry* entry = entries_[i_entry];
+        if (entry->inner_class_info->Kept() ||
+            used_class_names.find(entry->inner_class_info->Display())
+                != used_class_names.end() ||
+            entry->outer_class_info == class_name ||
+            entry->outer_class_info == NULL ||
+            entry->inner_name == NULL) {
+          kept_entries.insert(i_entry);
+
+          // These are zero for anonymous inner classes
+          if (entry->outer_class_info != NULL) {
+            entry->outer_class_info->slot();
+          }
+
+          if (entry->inner_name != NULL) {
+            entry->inner_name->slot();
+          }
+        }
+      }
+      iteration += 1;
+    } while (entry_count != kept_entries.size());
+
+    if (kept_entries.size() == 0) {
+      return;
+    }
+
+    WriteProlog(p, 2 + kept_entries.size() * 8);
+    put_u2be(p, kept_entries.size());
+
+    for (std::set<int>::iterator it = kept_entries.begin();
+         it != kept_entries.end();
+         ++it) {
+      Entry *entry = entries_[*it];
+      put_u2be(p, entry->inner_class_info == NULL
+               ? 0
+               : entry->inner_class_info->slot());
+      put_u2be(p, entry->outer_class_info == NULL
+               ? 0
+               : entry->outer_class_info->slot());
+      put_u2be(p, entry->inner_name == NULL
+               ? 0
+               : entry->inner_name->slot());
+      put_u2be(p, entry->inner_class_access_flags);
+    }
+  }
+
+  std::vector<Entry*> entries_;
+};
+
+// See sec.4.7.7 of JVM spec.
+// We preserve EnclosingMethod attributes to be able to identify local and
+// anonymous classes. These classes will be stripped of most content, as they
+// represent implementation details that shoudn't leak into the ijars. Omitting
+// EnclosingMethod attributes can lead to type-checking failures in the presence
+// of generics (see b/9070939).
+struct EnclosingMethodAttribute : Attribute {
+
+  static EnclosingMethodAttribute* Read(const u1 *&p,
+                                        Constant *attribute_name) {
+    EnclosingMethodAttribute *attr = new EnclosingMethodAttribute;
+    attr->attribute_name_ = attribute_name;
+    attr->class_ = constant(get_u2be(p));
+    attr->method_ = constant(get_u2be(p));
+    return attr;
+  }
+
+  void Write(u1 *&p) {
+    WriteProlog(p, 4);
+    put_u2be(p, class_->slot());
+    put_u2be(p, method_ == NULL ? 0 : method_->slot());
+  }
+
+  Constant *class_;
+  Constant *method_;
+};
+
+// See sec.4.7.16.1 of JVM spec.
+// Used by AnnotationDefault and other attributes.
+struct ElementValue {
+  virtual ~ElementValue() {}
+  virtual void Write(u1 *&p) = 0;
+  virtual void ExtractClassNames() {}
+  static ElementValue* Read(const u1 *&p);
+  u1 tag_;
+  u4 length_;
+};
+
+struct BaseTypeElementValue : ElementValue {
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    put_u2be(p, const_value_->slot());
+  }
+  static BaseTypeElementValue *Read(const u1 *&p) {
+    BaseTypeElementValue *value = new BaseTypeElementValue;
+    value->const_value_ = constant(get_u2be(p));
+    return value;
+  }
+  Constant *const_value_;
+};
+
+struct EnumTypeElementValue : ElementValue {
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    put_u2be(p, type_name_->slot());
+    put_u2be(p, const_name_->slot());
+  }
+  static EnumTypeElementValue *Read(const u1 *&p) {
+    EnumTypeElementValue *value = new EnumTypeElementValue;
+    value->type_name_ = constant(get_u2be(p));
+    value->const_name_ = constant(get_u2be(p));
+    return value;
+  }
+  Constant *type_name_;
+  Constant *const_name_;
+};
+
+struct ClassTypeElementValue : ElementValue {
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    put_u2be(p, class_info_->slot());
+  }
+
+  virtual void ExtractClassNames() {
+    size_t idx = 0;
+    devtools_ijar::ExtractClassNames(class_info_->Display(), &idx);
+  }
+
+  static ClassTypeElementValue *Read(const u1 *&p) {
+    ClassTypeElementValue *value = new ClassTypeElementValue;
+    value->class_info_ = constant(get_u2be(p));
+    return value;
+  }
+  Constant *class_info_;
+};
+
+struct ArrayTypeElementValue : ElementValue {
+  virtual ~ArrayTypeElementValue() {
+    for (size_t i = 0; i < values_.size(); i++) {
+      delete values_[i];
+    }
+  }
+
+  virtual void ExtractClassNames() {
+    for (int i = 0; i < values_.size(); i++) {
+      values_[i]->ExtractClassNames();
+    }
+  }
+
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    put_u2be(p, values_.size());
+    for (size_t ii = 0; ii < values_.size(); ++ii) {
+      values_[ii]->Write(p);
+    }
+  }
+  static ArrayTypeElementValue *Read(const u1 *&p) {
+    ArrayTypeElementValue *value = new ArrayTypeElementValue;
+    u2 num_values = get_u2be(p);
+    for (int ii = 0; ii < num_values; ++ii) {
+      value->values_.push_back(ElementValue::Read(p));
+    }
+    return value;
+  }
+  std::vector<ElementValue*> values_;
+};
+
+// See sec.4.7.16 of JVM spec.
+struct Annotation {
+  virtual ~Annotation() {
+    for (size_t i = 0; i < element_value_pairs_.size(); i++) {
+      delete element_value_pairs_[i]->element_value_;
+      delete element_value_pairs_[i];
+    }
+  }
+
+  void ExtractClassNames() {
+    for (size_t i = 0; i < element_value_pairs_.size(); i++) {
+      element_value_pairs_[i]->element_value_->ExtractClassNames();
+    }
+  }
+
+  void Write(u1 *&p) {
+    put_u2be(p, type_->slot());
+    put_u2be(p, element_value_pairs_.size());
+    for (size_t ii = 0; ii < element_value_pairs_.size(); ++ii) {
+      put_u2be(p, element_value_pairs_[ii]->element_name_->slot());
+      element_value_pairs_[ii]->element_value_->Write(p);
+    }
+  }
+  static Annotation *Read(const u1 *&p) {
+    Annotation *value = new Annotation;
+    value->type_ = constant(get_u2be(p));
+    u2 num_element_value_pairs = get_u2be(p);
+    for (int ii = 0; ii < num_element_value_pairs; ++ii) {
+      ElementValuePair *pair = new ElementValuePair;
+      pair->element_name_ = constant(get_u2be(p));
+      pair->element_value_ = ElementValue::Read(p);
+      value->element_value_pairs_.push_back(pair);
+    }
+    return value;
+  }
+  Constant *type_;
+  struct ElementValuePair {
+    Constant *element_name_;
+    ElementValue *element_value_;
+  };
+  std::vector<ElementValuePair*> element_value_pairs_;
+};
+
+// See sec 4.7.20 of Java 8 JVM Spec
+//
+// Each entry in the annotations table represents a single run-time visible
+// annotation on a type used in a declaration or expression. The type_annotation
+// structure has the following format:
+//
+// type_annotation {
+//   u1 target_type;
+//   union {
+//     type_parameter_target;
+//     supertype_target;
+//     type_parameter_bound_target;
+//     empty_target;
+//     method_formal_parameter_target;
+//     throws_target;
+//     localvar_target;
+//     catch_target;
+//     offset_target;
+//     type_argument_target;
+//   } target_info;
+//   type_path target_path;
+//   u2        type_index;
+//   u2        num_element_value_pairs;
+//   {
+//     u2            element_name_index;
+//     element_value value;
+//   }
+//   element_value_pairs[num_element_value_pairs];
+// }
+//
+struct TypeAnnotation {
+  virtual ~TypeAnnotation() {
+    delete target_info_;
+    delete type_path_;
+    delete annotation_;
+  }
+
+  void ExtractClassNames() {
+    annotation_->ExtractClassNames();
+  }
+
+  void Write(u1 *&p) {
+    put_u1(p, target_type_);
+    target_info_->Write(p);
+    type_path_->Write(p);
+    annotation_->Write(p);
+  }
+
+  static TypeAnnotation *Read(const u1 *&p) {
+    TypeAnnotation *value = new TypeAnnotation;
+    value->target_type_ = get_u1(p);
+    value->target_info_ = ReadTargetInfo(p, value->target_type_);
+    value->type_path_ = TypePath::Read(p);
+    value->annotation_ = Annotation::Read(p);
+    return value;
+  }
+
+  struct TargetInfo {
+    virtual ~TargetInfo() {}
+    virtual void Write(u1 *&p) = 0;
+  };
+
+  struct TypeParameterTargetInfo : TargetInfo {
+    void Write(u1 *&p) {
+      put_u1(p, type_parameter_index_);
+    }
+    static TypeParameterTargetInfo *Read(const u1 *&p) {
+      TypeParameterTargetInfo *value = new TypeParameterTargetInfo;
+      value->type_parameter_index_ = get_u1(p);
+      return value;
+    }
+    u1 type_parameter_index_;
+  };
+
+  struct ClassExtendsInfo : TargetInfo {
+    void Write(u1 *&p) {
+      put_u2be(p, supertype_index_);
+    }
+    static ClassExtendsInfo *Read(const u1 *&p) {
+      ClassExtendsInfo *value = new ClassExtendsInfo;
+      value->supertype_index_ = get_u2be(p);
+      return value;
+    }
+    u2 supertype_index_;
+  };
+
+  struct TypeParameterBoundInfo : TargetInfo {
+    void Write(u1 *&p) {
+      put_u1(p, type_parameter_index_);
+      put_u1(p, bound_index_);
+    }
+    static TypeParameterBoundInfo *Read(const u1 *&p) {
+      TypeParameterBoundInfo *value = new TypeParameterBoundInfo;
+      value->type_parameter_index_ = get_u1(p);
+      value->bound_index_ = get_u1(p);
+      return value;
+    }
+    u1 type_parameter_index_;
+    u1 bound_index_;
+  };
+
+  struct EmptyInfo : TargetInfo {
+    void Write(u1 *&p) {}
+    static EmptyInfo *Read(const u1 *&p) {
+      return new EmptyInfo;
+    }
+  };
+
+  struct MethodFormalParameterInfo : TargetInfo {
+    void Write(u1 *&p) {
+      put_u1(p, method_formal_parameter_index_);
+    }
+    static MethodFormalParameterInfo *Read(const u1 *&p) {
+      MethodFormalParameterInfo *value = new MethodFormalParameterInfo;
+      value->method_formal_parameter_index_ = get_u1(p);
+      return value;
+    }
+    u1 method_formal_parameter_index_;
+  };
+
+  struct ThrowsTypeInfo : TargetInfo {
+    void Write(u1 *&p) {
+      put_u2be(p, throws_type_index_);
+    }
+    static ThrowsTypeInfo *Read(const u1 *&p) {
+      ThrowsTypeInfo *value = new ThrowsTypeInfo;
+      value->throws_type_index_ = get_u2be(p);
+      return value;
+    }
+    u2 throws_type_index_;
+  };
+
+  static TargetInfo *ReadTargetInfo(const u1 *&p, u1 target_type) {
+    switch (target_type) {
+      case CLASS_TYPE_PARAMETER:
+      case METHOD_TYPE_PARAMETER:
+        return TypeParameterTargetInfo::Read(p);
+      case CLASS_EXTENDS:
+        return ClassExtendsInfo::Read(p);
+      case CLASS_TYPE_PARAMETER_BOUND:
+      case METHOD_TYPE_PARAMETER_BOUND:
+        return TypeParameterBoundInfo::Read(p);
+      case FIELD:
+      case METHOD_RETURN:
+      case METHOD_RECEIVER:
+        return new EmptyInfo;
+      case METHOD_FORMAL_PARAMETER:
+        return MethodFormalParameterInfo::Read(p);
+      case THROWS:
+        return ThrowsTypeInfo::Read(p);
+      default:
+        fprintf(stderr, "Illegal type annotation target type: %d\n",
+                target_type);
+        abort();
+    }
+  }
+
+  struct TypePath {
+    void Write(u1 *&p) {
+      put_u1(p, path_.size());
+      for (TypePathEntry entry : path_) {
+        put_u1(p, entry.type_path_kind_);
+        put_u1(p, entry.type_argument_index_);
+      }
+    }
+    static TypePath *Read(const u1 *&p) {
+      TypePath *value = new TypePath;
+      u1 path_length = get_u1(p);
+      for (int ii = 0; ii < path_length; ++ii) {
+        TypePathEntry entry;
+        entry.type_path_kind_ = get_u1(p);
+        entry.type_argument_index_ = get_u1(p);
+        value->path_.push_back(entry);
+      }
+      return value;
+    }
+
+    struct TypePathEntry {
+      u1 type_path_kind_;
+      u1 type_argument_index_;
+    };
+    std::vector<TypePathEntry> path_;
+  };
+
+  u1 target_type_;
+  TargetInfo *target_info_;
+  TypePath *type_path_;
+  Annotation *annotation_;
+};
+
+struct AnnotationTypeElementValue : ElementValue {
+  virtual ~AnnotationTypeElementValue() {
+    delete annotation_;
+  }
+
+  void Write(u1 *&p) {
+    put_u1(p, tag_);
+    annotation_->Write(p);
+  }
+  static AnnotationTypeElementValue *Read(const u1 *&p) {
+    AnnotationTypeElementValue *value = new AnnotationTypeElementValue;
+    value->annotation_ = Annotation::Read(p);
+    return value;
+  }
+
+  Annotation *annotation_;
+};
+
+ElementValue* ElementValue::Read(const u1 *&p) {
+  const u1* start = p;
+  ElementValue *result;
+  u1 tag = get_u1(p);
+  if (tag != 0 && strchr("BCDFIJSZs", (char) tag) != NULL) {
+    result = BaseTypeElementValue::Read(p);
+  } else if ((char) tag == 'e') {
+    result = EnumTypeElementValue::Read(p);
+  } else if ((char) tag == 'c') {
+    result = ClassTypeElementValue::Read(p);
+  } else if ((char) tag == '[') {
+    result = ArrayTypeElementValue::Read(p);
+  } else if ((char) tag == '@') {
+    result = AnnotationTypeElementValue::Read(p);
+  } else {
+    fprintf(stderr, "Illegal element_value::tag: %d\n", tag);
+    abort();
+  }
+  result->tag_ = tag;
+  result->length_ = p - start;
+  return result;
+}
+
+// See sec.4.7.20 of JVM spec.
+// We preserve AnnotationDefault attributes because they are required
+// in order to make use of an annotation in new code.
+struct AnnotationDefaultAttribute : Attribute {
+  virtual ~AnnotationDefaultAttribute() {
+    delete default_value_;
+  }
+
+  static AnnotationDefaultAttribute* Read(const u1 *&p,
+                                          Constant *attribute_name) {
+    AnnotationDefaultAttribute *attr = new AnnotationDefaultAttribute;
+    attr->attribute_name_ = attribute_name;
+    attr->default_value_ = ElementValue::Read(p);
+    return attr;
+  }
+
+  void Write(u1 *&p) {
+    WriteProlog(p, default_value_->length_);
+    default_value_->Write(p);
+  }
+
+  virtual void ExtractClassNames() {
+    default_value_->ExtractClassNames();
+  }
+
+  ElementValue *default_value_;
+};
+
+// See sec.4.7.2 of JVM spec.
+// We preserve ConstantValue attributes because they are required for
+// compile-time constant propagation.
+struct ConstantValueAttribute : Attribute {
+
+  static ConstantValueAttribute* Read(const u1 *&p, Constant *attribute_name) {
+    ConstantValueAttribute *attr = new ConstantValueAttribute;
+    attr->attribute_name_ = attribute_name;
+    attr->constantvalue_ = constant(get_u2be(p));
+    return attr;
+  }
+
+  void Write(u1 *&p) {
+    WriteProlog(p, 2);
+    put_u2be(p, constantvalue_->slot());
+  }
+
+  Constant *constantvalue_;
+};
+
+// See sec.4.7.9 of JVM spec.
+// We preserve Signature attributes because they are required by the
+// compiler for type-checking of generics.
+struct SignatureAttribute : Attribute {
+
+  static SignatureAttribute* Read(const u1 *&p, Constant *attribute_name) {
+    SignatureAttribute *attr = new SignatureAttribute;
+    attr->attribute_name_ = attribute_name;
+    attr->signature_  = constant(get_u2be(p));
+    return attr;
+  }
+
+  void Write(u1 *&p) {
+    WriteProlog(p, 2);
+    put_u2be(p, signature_->slot());
+  }
+
+  virtual void ExtractClassNames() {
+    size_t signature_idx = 0;
+    devtools_ijar::ExtractClassNames(signature_->Display(), &signature_idx);
+  }
+
+  Constant *signature_;
+};
+
+// See sec.4.7.15 of JVM spec.
+// We preserve Deprecated attributes because they are required by the
+// compiler to generate warning messages.
+struct DeprecatedAttribute : Attribute {
+
+  static DeprecatedAttribute* Read(const u1 *&p, Constant *attribute_name) {
+    DeprecatedAttribute *attr = new DeprecatedAttribute;
+    attr->attribute_name_ = attribute_name;
+    return attr;
+  }
+
+  void Write(u1 *&p) {
+    WriteProlog(p, 0);
+  }
+};
+
+// See sec.4.7.16-17 of JVM spec v3.  Includes RuntimeVisible and
+// RuntimeInvisible.
+//
+// We preserve all annotations.
+struct AnnotationsAttribute : Attribute {
+  virtual ~AnnotationsAttribute() {
+    for (size_t i = 0; i < annotations_.size(); i++) {
+      delete annotations_[i];
+    }
+  }
+
+  static AnnotationsAttribute* Read(const u1 *&p, Constant *attribute_name) {
+    AnnotationsAttribute *attr = new AnnotationsAttribute;
+    attr->attribute_name_ = attribute_name;
+    u2 num_annotations = get_u2be(p);
+    for (int ii = 0; ii < num_annotations; ++ii) {
+      Annotation *annotation = Annotation::Read(p);
+      attr->annotations_.push_back(annotation);
+    }
+    return attr;
+  }
+
+  virtual void ExtractClassNames() {
+    for (int i = 0; i < annotations_.size(); i++) {
+      annotations_[i]->ExtractClassNames();
+    }
+  }
+
+  void Write(u1 *&p) {
+    WriteProlog(p, -1);
+    u1 *payload_start = p - 4;
+    put_u2be(p, annotations_.size());
+    for (size_t ii = 0; ii < annotations_.size(); ++ii) {
+      annotations_[ii]->Write(p);
+    }
+    put_u4be(payload_start, p - 4 - payload_start);  // backpatch length
+  }
+
+  std::vector<Annotation*> annotations_;
+};
+
+// See sec.4.7.18-19 of JVM spec.  Includes RuntimeVisible and
+// RuntimeInvisible.
+//
+// We preserve all annotations.
+struct ParameterAnnotationsAttribute : Attribute {
+
+  static ParameterAnnotationsAttribute* Read(const u1 *&p,
+                                             Constant *attribute_name) {
+    ParameterAnnotationsAttribute *attr = new ParameterAnnotationsAttribute;
+    attr->attribute_name_ = attribute_name;
+    u1 num_parameters = get_u1(p);
+    for (int ii = 0; ii < num_parameters; ++ii) {
+      std::vector<Annotation*> annotations;
+      u2 num_annotations = get_u2be(p);
+      for (int ii = 0; ii < num_annotations; ++ii) {
+        Annotation *annotation = Annotation::Read(p);
+        annotations.push_back(annotation);
+      }
+      attr->parameter_annotations_.push_back(annotations);
+    }
+    return attr;
+  }
+
+  virtual void ExtractClassNames() {
+    for (size_t i = 0; i < parameter_annotations_.size(); i++) {
+      const std::vector<Annotation*>& annotations = parameter_annotations_[i];
+      for (size_t j = 0; j < annotations.size(); j++) {
+        annotations[j]->ExtractClassNames();
+      }
+    }
+  }
+
+  void Write(u1 *&p) {
+    WriteProlog(p, -1);
+    u1 *payload_start = p - 4;
+    put_u1(p, parameter_annotations_.size());
+    for (size_t ii = 0; ii < parameter_annotations_.size(); ++ii) {
+      std::vector<Annotation *> &annotations = parameter_annotations_[ii];
+      put_u2be(p, annotations.size());
+      for (size_t jj = 0; jj < annotations.size(); ++jj) {
+        annotations[jj]->Write(p);
+      }
+    }
+    put_u4be(payload_start, p - 4 - payload_start);  // backpatch length
+  }
+
+  std::vector<std::vector<Annotation*> > parameter_annotations_;
+};
+
+// See sec.4.7.20 of Java 8 JVM spec. Includes RuntimeVisibleTypeAnnotations
+// and RuntimeInvisibleTypeAnnotations.
+struct TypeAnnotationsAttribute : Attribute {
+  static TypeAnnotationsAttribute* Read(const u1 *&p, Constant *attribute_name,
+                                        u4 attribute_length) {
+    auto attr = new TypeAnnotationsAttribute;
+    attr->attribute_name_ = attribute_name;
+    u2 num_annotations = get_u2be(p);
+    for (int ii = 0; ii < num_annotations; ++ii) {
+      TypeAnnotation *annotation = TypeAnnotation::Read(p);
+      attr->type_annotations_.push_back(annotation);
+    }
+    return attr;
+  }
+
+  virtual void ExtractClassNames() {
+    for (int i = 0; i < type_annotations_.size(); i++) {
+      type_annotations_[i]->ExtractClassNames();
+    }
+  }
+
+  void Write(u1 *&p) {
+    WriteProlog(p, -1);
+    u1 *payload_start = p - 4;
+    put_u2be(p, type_annotations_.size());
+    for (TypeAnnotation *annotation : type_annotations_) {
+      annotation->Write(p);
+    }
+    put_u4be(payload_start, p - 4 - payload_start);  // backpatch length
+  }
+
+  std::vector<TypeAnnotation*> type_annotations_;
+};
+
+struct GeneralAttribute : Attribute {
+  static GeneralAttribute* Read(const u1 *&p, Constant *attribute_name,
+                                u4 attribute_length) {
+    auto attr = new GeneralAttribute;
+    attr->attribute_name_ = attribute_name;
+    attr->attribute_length_ = attribute_length;
+    attr->attribute_content_ = p;
+    p += attribute_length;
+    return attr;
+  }
+
+  void Write(u1 *&p) {
+    WriteProlog(p, attribute_length_);
+    put_n(p, attribute_content_, attribute_length_);
+  }
+
+  u4 attribute_length_;
+  const u1 *attribute_content_;
+};
+
+/**********************************************************************
+ *                                                                    *
+ *                             ClassFile                              *
+ *                                                                    *
+ **********************************************************************/
+
+struct HasAttrs {
+  std::vector<Attribute*> attributes;
+
+  void WriteAttrs(u1 *&p);
+  void ReadAttrs(const u1 *&p);
+
+  virtual ~HasAttrs() {
+    for (size_t i = 0; i < attributes.size(); i++) {
+      delete attributes[i];
+    }
+  }
+
+  void ExtractClassNames() {
+    for (int i = 0; i < attributes.size(); i++) {
+      attributes[i]->ExtractClassNames();
+    }
+  }
+};
+
+// A field or method.
+// See sec.4.5 and 4.6 of JVM spec.
+struct Member : HasAttrs {
+  u2 access_flags;
+  Constant *name;
+  Constant *descriptor;
+
+  static Member* Read(const u1 *&p) {
+    Member *m = new Member;
+    m->access_flags = get_u2be(p);
+    m->name = constant(get_u2be(p));
+    m->descriptor = constant(get_u2be(p));
+    m->ReadAttrs(p);
+    return m;
+  }
+
+  void Write(u1 *&p) {
+    put_u2be(p, access_flags);
+    put_u2be(p, name->slot());
+    put_u2be(p, descriptor->slot());
+    WriteAttrs(p);
+  }
+};
+
+// See sec.4.1 of JVM spec.
+struct ClassFile : HasAttrs {
+
+  size_t length;
+
+  // Header:
+  u4 magic;
+  u2 major;
+  u2 minor;
+
+  // Body:
+  u2 access_flags;
+  Constant *this_class;
+  Constant *super_class;
+  std::vector<Constant*> interfaces;
+  std::vector<Member*> fields;
+  std::vector<Member*> methods;
+
+  virtual ~ClassFile() {
+    for (size_t i = 0; i < fields.size(); i++) {
+      delete fields[i];
+    }
+
+    for (size_t i = 0; i < methods.size(); i++) {
+      delete methods[i];
+    }
+
+    // Constants do not need to be deleted; they are owned by the constant pool.
+  }
+
+  void WriteClass(u1 *&p);
+
+  bool ReadConstantPool(const u1 *&p);
+
+  void StripIfAnonymous();
+
+  void WriteHeader(u1 *&p) {
+    put_u4be(p, magic);
+    put_u2be(p, major);
+    put_u2be(p, minor);
+
+    put_u2be(p, const_pool_out.size());
+    for (u2 ii = 1; ii < const_pool_out.size(); ++ii) {
+      if (const_pool_out[ii] != NULL) { // NB: NULLs appear after long/double.
+        const_pool_out[ii]->Write(p);
+      }
+    }
+  }
+
+  void WriteBody(u1 *&p) {
+    put_u2be(p, access_flags);
+    put_u2be(p, this_class->slot());
+    put_u2be(p, super_class == NULL ? 0 : super_class->slot());
+    put_u2be(p, interfaces.size());
+    for (size_t ii = 0; ii < interfaces.size(); ++ii) {
+      put_u2be(p, interfaces[ii]->slot());
+    }
+    put_u2be(p, fields.size());
+    for (size_t ii = 0; ii < fields.size(); ++ii) {
+      fields[ii]->Write(p);
+    }
+    put_u2be(p, methods.size());
+    for (size_t ii = 0; ii < methods.size(); ++ii) {
+      methods[ii]->Write(p);
+    }
+
+    Attribute* inner_classes = NULL;
+
+    // Make the inner classes attribute the last, so that it can know which
+    // constants were needed
+    for (size_t ii = 0; ii < attributes.size(); ii++) {
+      if (attributes[ii]->attribute_name_->Display() == "InnerClasses") {
+        inner_classes = attributes[ii];
+        attributes.erase(attributes.begin() + ii);
+        break;
+      }
+    }
+
+    if (inner_classes != NULL) {
+      attributes.push_back(inner_classes);
+    }
+
+    WriteAttrs(p);
+  }
+
+};
+
+void HasAttrs::ReadAttrs(const u1 *&p) {
+  u2 attributes_count = get_u2be(p);
+  for (int ii = 0; ii < attributes_count; ii++) {
+    Constant *attribute_name = constant(get_u2be(p));
+    u4 attribute_length = get_u4be(p);
+
+    std::string attr_name = attribute_name->Display();
+    if (attr_name == "SourceFile" ||
+        attr_name == "LineNumberTable" ||
+        attr_name == "LocalVariableTable" ||
+        attr_name == "LocalVariableTypeTable" ||
+        attr_name == "Code" ||
+        attr_name == "Synthetic" ||
+        attr_name == "BootstrapMethods") {
+      p += attribute_length; // drop these attributes
+    } else if (attr_name == "Exceptions") {
+      attributes.push_back(ExceptionsAttribute::Read(p, attribute_name));
+    } else if (attr_name == "Signature") {
+      attributes.push_back(SignatureAttribute::Read(p, attribute_name));
+    } else if (attr_name == "Deprecated") {
+      attributes.push_back(DeprecatedAttribute::Read(p, attribute_name));
+    } else if (attr_name == "EnclosingMethod") {
+      attributes.push_back(EnclosingMethodAttribute::Read(p, attribute_name));
+    } else if (attr_name == "InnerClasses") {
+      // TODO(bazel-team): omit private inner classes
+      attributes.push_back(InnerClassesAttribute::Read(p, attribute_name));
+    } else if (attr_name == "AnnotationDefault") {
+      attributes.push_back(AnnotationDefaultAttribute::Read(p, attribute_name));
+    } else if (attr_name == "ConstantValue") {
+      attributes.push_back(ConstantValueAttribute::Read(p, attribute_name));
+    } else if (attr_name == "RuntimeVisibleAnnotations" ||
+               attr_name == "RuntimeInvisibleAnnotations") {
+      attributes.push_back(AnnotationsAttribute::Read(p, attribute_name));
+    } else if (attr_name == "RuntimeVisibleParameterAnnotations" ||
+               attr_name == "RuntimeInvisibleParameterAnnotations") {
+      attributes.push_back(
+          ParameterAnnotationsAttribute::Read(p, attribute_name));
+    } else if (attr_name == "Scala" ||
+               attr_name == "ScalaSig" ||
+               attr_name == "ScalaInlineInfo") {
+      // These are opaque blobs, so can be handled with a general
+      // attribute handler
+      attributes.push_back(GeneralAttribute::Read(p, attribute_name,
+                                                  attribute_length));
+    } else if (attr_name == "RuntimeVisibleTypeAnnotations" ||
+               attr_name == "RuntimeInvisibleTypeAnnotations") {
+      // JSR 308: annotations on types. JDK 7 has no use for these yet, but the
+      // Checkers Framework relies on them.
+      attributes.push_back(TypeAnnotationsAttribute::Read(p, attribute_name,
+                                                          attribute_length));
+    } else {
+      // Skip over unknown attributes with a warning.  The JVM spec
+      // says this is ok, so long as we handle the mandatory attributes.
+      fprintf(stderr, "ijar: skipping unknown attribute: \"%s\".\n",
+              attr_name.c_str());
+      p += attribute_length;
+    }
+  }
+}
+
+void HasAttrs::WriteAttrs(u1 *&p) {
+  u1* p_size = p;
+
+  put_u2be(p, 0);
+  int n_written_attrs = 0;
+  for (size_t ii = 0; ii < attributes.size(); ii++) {
+    u1* before = p;
+    attributes[ii]->Write(p);
+    if (p != before) {
+      n_written_attrs++;
+    }
+  }
+
+  put_u2be(p_size, n_written_attrs);
+}
+
+// See sec.4.4 of JVM spec.
+bool ClassFile::ReadConstantPool(const u1 *&p) {
+
+  const_pool_in.clear();
+  const_pool_in.push_back(NULL); // dummy first item
+
+  u2 cp_count = get_u2be(p);
+  for (int ii = 1; ii < cp_count; ++ii) {
+    u1 tag = get_u1(p);
+
+    if (devtools_ijar::verbose) {
+      fprintf(stderr, "cp[%d/%d] = tag %d\n", ii, cp_count, tag);
+    }
+
+    switch(tag) {
+      case CONSTANT_Class: {
+        u2 name_index = get_u2be(p);
+        const_pool_in.push_back(new Constant_Class(name_index));
+        break;
+      }
+      case CONSTANT_FieldRef:
+      case CONSTANT_Methodref:
+      case CONSTANT_Interfacemethodref: {
+        u2 class_index = get_u2be(p);
+        u2 nti = get_u2be(p);
+        const_pool_in.push_back(new Constant_FMIref(tag, class_index, nti));
+        break;
+      }
+      case CONSTANT_String: {
+        u2 string_index = get_u2be(p);
+        const_pool_in.push_back(new Constant_String(string_index));
+        break;
+      }
+      case CONSTANT_NameAndType: {
+        u2 name_index = get_u2be(p);
+        u2 descriptor_index = get_u2be(p);
+        const_pool_in.push_back(
+            new Constant_NameAndType(name_index, descriptor_index));
+        break;
+      }
+      case CONSTANT_Utf8: {
+        u2 length = get_u2be(p);
+        if (devtools_ijar::verbose) {
+          fprintf(stderr, "Utf8: \"%s\" (%d)\n",
+                  std::string((const char*) p, length).c_str(), length);
+        }
+
+        const_pool_in.push_back(new Constant_Utf8(length, p));
+        p += length;
+        break;
+      }
+      case CONSTANT_Integer:
+      case CONSTANT_Float: {
+        u4 bytes = get_u4be(p);
+        const_pool_in.push_back(new Constant_IntegerOrFloat(tag, bytes));
+        break;
+      }
+      case CONSTANT_Long:
+      case CONSTANT_Double: {
+        u4 high_bytes = get_u4be(p);
+        u4 low_bytes = get_u4be(p);
+        const_pool_in.push_back(
+            new Constant_LongOrDouble(tag, high_bytes, low_bytes));
+        // Longs and doubles occupy two constant pool slots.
+        // ("In retrospect, making 8-byte constants take two "constant
+        // pool entries was a poor choice." --JVM Spec.)
+        const_pool_in.push_back(NULL);
+        ii++;
+        break;
+      }
+      case CONSTANT_MethodHandle: {
+        u1 reference_kind = get_u1(p);
+        u2 reference_index = get_u2be(p);
+        const_pool_in.push_back(
+            new Constant_MethodHandle(reference_kind, reference_index));
+        break;
+      }
+      case CONSTANT_MethodType: {
+        u2 descriptor_index = get_u2be(p);
+        const_pool_in.push_back(new Constant_MethodType(descriptor_index));
+        break;
+      }
+      case CONSTANT_InvokeDynamic: {
+        u2 bootstrap_method_attr = get_u2be(p);
+        u2 name_name_type_index = get_u2be(p);
+        const_pool_in.push_back(new Constant_InvokeDynamic(
+            bootstrap_method_attr, name_name_type_index));
+        break;
+      }
+      default: {
+        fprintf(stderr, "Unknown constant: %02x. Passing class through.\n",
+                tag);
+        return false;
+      }
+    }
+  }
+
+  return true;
+}
+
+// Anonymous inner classes are stripped to opaque classes that only extend
+// Object. None of their methods or fields are accessible anyway.
+void ClassFile::StripIfAnonymous() {
+  int enclosing_index = -1;
+  int inner_classes_index = -1;
+
+  for (size_t ii = 0; ii < attributes.size(); ++ii) {
+    if (attributes[ii]->attribute_name_->Display() == "EnclosingMethod") {
+      enclosing_index = ii;
+    } else if (attributes[ii]->attribute_name_->Display() == "InnerClasses") {
+      inner_classes_index = ii;
+    }
+  }
+
+  // Presence of an EnclosingMethod attribute indicates a local or anonymous
+  // class, which can be stripped.
+  if (enclosing_index > -1) {
+    // Clear the signature to only extend java.lang.Object.
+    super_class = NULL;
+    interfaces.clear();
+
+    // Clear away all fields (implementation details).
+    for (size_t ii = 0; ii < fields.size(); ++ii) {
+      delete fields[ii];
+    }
+    fields.clear();
+
+    // Clear away all methods (implementation details).
+    for (size_t ii = 0; ii < methods.size(); ++ii) {
+      delete methods[ii];
+    }
+    methods.clear();
+
+    // Only preserve the InnerClasses attribute to comply with the spec.
+    Attribute *attr = NULL;
+    for (size_t ii = 0; ii < attributes.size(); ++ii) {
+      if (static_cast<int>(ii) != inner_classes_index) {
+        delete attributes[ii];
+      } else {
+        attr = attributes[ii];
+      }
+    }
+    attributes.clear();
+    if (attr != NULL) {
+      attributes.push_back(attr);
+    }
+  }
+}
+
+static ClassFile *ReadClass(const void *classdata, size_t length) {
+  const u1 *p = (u1*) classdata;
+
+  ClassFile *clazz = new ClassFile;
+
+  clazz->length = length;
+
+  clazz->magic = get_u4be(p);
+  if (clazz->magic != 0xCAFEBABE) {
+    fprintf(stderr, "Bad magic %" PRIx32 "\n", clazz->magic);
+    abort();
+  }
+  clazz->major = get_u2be(p);
+  clazz->minor = get_u2be(p);
+
+  if (!clazz->ReadConstantPool(p)) {
+    delete clazz;
+    return NULL;
+  }
+
+  clazz->access_flags = get_u2be(p);
+  clazz->this_class = constant(get_u2be(p));
+  class_name = clazz->this_class;
+
+  u2 super_class_id = get_u2be(p);
+  clazz->super_class = super_class_id == 0 ? NULL : constant(super_class_id);
+
+  u2 interfaces_count = get_u2be(p);
+  for (int ii = 0; ii < interfaces_count; ++ii) {
+    clazz->interfaces.push_back(constant(get_u2be(p)));
+  }
+
+  u2 fields_count = get_u2be(p);
+  for (int ii = 0; ii < fields_count; ++ii) {
+    Member *field = Member::Read(p);
+
+    if (!(field->access_flags & ACC_PRIVATE)) { // drop private fields
+      clazz->fields.push_back(field);
+    }
+  }
+
+  u2 methods_count = get_u2be(p);
+  for (int ii = 0; ii < methods_count; ++ii) {
+    Member *method = Member::Read(p);
+
+    // drop class initializers
+    if (method->name->Display() == "<clinit>") continue;
+
+    if (!(method->access_flags & ACC_PRIVATE)) { // drop private methods
+      clazz->methods.push_back(method);
+    }
+  }
+
+  clazz->ReadAttrs(p);
+  clazz->StripIfAnonymous();
+
+  return clazz;
+}
+
+// In theory, '/' is also reserved, but it's okay if we just parse package
+// identifiers as part of the class name. Note that signatures are UTF-8, but
+// this works just as well as in plain ASCII.
+static const char *SIGNATURE_NON_IDENTIFIER_CHARS = ".;[<>:";
+
+void Expect(const std::string& desc, size_t* p, char expected) {
+  if (desc[*p] != expected) {
+    fprintf(stderr, "Expected '%c' in '%s' at %zd in signature\n",
+            expected, desc.substr(*p).c_str(), *p);
+    exit(1);
+  }
+
+  *p += 1;
+}
+
+// These functions form a crude recursive descent parser for descriptors and
+// signatures in class files (see JVM spec 4.3).
+//
+// This parser is a bit more liberal than the spec, but this should be fine,
+// because it accepts all valid class files and croaks only on invalid ones.
+void ParseFromClassTypeSignature(const std::string& desc, size_t* p);
+void ParseSimpleClassTypeSignature(const std::string& desc, size_t* p);
+void ParseClassTypeSignatureSuffix(const std::string& desc, size_t* p);
+void ParseIdentifier(const std::string& desc, size_t* p);
+void ParseTypeArgumentsOpt(const std::string& desc, size_t* p);
+void ParseMethodDescriptor(const std::string& desc, size_t* p);
+
+void ParseClassTypeSignature(const std::string& desc, size_t* p) {
+  Expect(desc, p, 'L');
+  ParseSimpleClassTypeSignature(desc, p);
+  ParseClassTypeSignatureSuffix(desc, p);
+  Expect(desc, p, ';');
+}
+
+void ParseSimpleClassTypeSignature(const std::string& desc, size_t* p) {
+  ParseIdentifier(desc, p);
+  ParseTypeArgumentsOpt(desc, p);
+}
+
+void ParseClassTypeSignatureSuffix(const std::string& desc, size_t* p) {
+  while (desc[*p] == '.') {
+    *p += 1;
+    ParseSimpleClassTypeSignature(desc, p);
+  }
+}
+
+void ParseIdentifier(const std::string& desc, size_t* p) {
+  size_t next = desc.find_first_of(SIGNATURE_NON_IDENTIFIER_CHARS, *p);
+  std::string id = desc.substr(*p, next - *p);
+  used_class_names.insert(id);
+  *p = next;
+}
+
+void ParseTypeArgumentsOpt(const std::string& desc, size_t* p) {
+  if (desc[*p] != '<') {
+    return;
+  }
+
+  *p += 1;
+  while (desc[*p] != '>') {
+    switch (desc[*p]) {
+      case '*':
+        *p += 1;
+        break;
+
+      case '+':
+      case '-':
+        *p += 1;
+        ExtractClassNames(desc, p);
+        break;
+
+      default:
+        ExtractClassNames(desc, p);
+        break;
+    }
+  }
+
+  *p += 1;
+}
+
+void ParseMethodDescriptor(const std::string& desc, size_t* p) {
+  Expect(desc, p, '(');
+  while (desc[*p] != ')') {
+    ExtractClassNames(desc, p);
+  }
+
+  Expect(desc, p, ')');
+  ExtractClassNames(desc, p);
+}
+
+void ParseFormalTypeParameters(const std::string& desc, size_t* p) {
+  Expect(desc, p, '<');
+  while (desc[*p] != '>') {
+    ParseIdentifier(desc, p);
+    Expect(desc, p, ':');
+    if (desc[*p] != ':' && desc[*p] != '>') {
+      ExtractClassNames(desc, p);
+    }
+
+    while (desc[*p] == ':') {
+      Expect(desc, p, ':');
+      ExtractClassNames(desc, p);
+    }
+  }
+
+  Expect(desc, p, '>');
+}
+
+void ExtractClassNames(const std::string& desc, size_t* p) {
+  switch (desc[*p]) {
+    case '<':
+      ParseFormalTypeParameters(desc, p);
+      ExtractClassNames(desc, p);
+      break;
+
+    case 'L':
+      ParseClassTypeSignature(desc, p);
+      break;
+
+    case '[':
+      *p += 1;
+      ExtractClassNames(desc, p);
+      break;
+
+    case 'T':
+      *p += 1;
+      ParseIdentifier(desc, p);
+      Expect(desc, p, ';');
+      break;
+
+    case '(':
+      ParseMethodDescriptor(desc, p);
+      break;
+
+    case 'B':
+    case 'C':
+    case 'D':
+    case 'F':
+    case 'I':
+    case 'J':
+    case 'S':
+    case 'Z':
+    case 'V':
+      *p += 1;
+      break;
+
+    default:
+      fprintf(stderr, "Invalid signature %s\n", desc.substr(*p).c_str());
+  }
+}
+
+void ClassFile::WriteClass(u1 *&p) {
+  used_class_names.clear();
+  std::vector<Member *> members;
+  members.insert(members.end(), fields.begin(), fields.end());
+  members.insert(members.end(), methods.begin(), methods.end());
+  ExtractClassNames();
+  for (int i = 0; i < members.size(); i++) {
+    Member *member = members[i];
+    size_t idx = 0;
+    devtools_ijar::ExtractClassNames(member->descriptor->Display(), &idx);
+    member->ExtractClassNames();
+  }
+
+  // We have to write the body out before the header in order to reference
+  // the essential constants and populate the output constant pool:
+  u1 *body = new u1[length];
+  u1 *q = body;
+  WriteBody(q); // advances q
+  u4 body_length = q - body;
+
+  WriteHeader(p); // advances p
+  put_n(p, body, body_length);
+  delete[] body;
+}
+
+
+void StripClass(u1 *&classdata_out, const u1 *classdata_in, size_t in_length) {
+  ClassFile *clazz = ReadClass(classdata_in, in_length);
+  if (clazz == NULL) {
+    // Class is invalid. Simply copy it to the output and call it a day.
+    put_n(classdata_out, classdata_in, in_length);
+  } else {
+
+    // Constant pool item zero is a dummy entry.  Setting it marks the
+    // beginning of the output phase; calls to Constant::slot() will
+    // fail if called prior to this.
+    const_pool_out.push_back(NULL);
+    clazz->WriteClass(classdata_out);
+
+    delete clazz;
+  }
+
+  // Now clean up all the mess we left behind.
+
+  for (size_t i = 0; i < const_pool_in.size(); i++) {
+    delete const_pool_in[i];
+  }
+
+  const_pool_in.clear();
+  const_pool_out.clear();
+}
+
+}  // namespace devtools_ijar
